4 * PCB, interactive printed circuit board design
5 * Copyright (C) 1994,1995,1996 Thomas Nau
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 * Contact addresses for paper mail and Email:
22 * Thomas Nau, Schlehenweg 15, 88471 Baustetten, Germany
23 * Thomas.Nau@rz.uni-ulm.de
28 /* functions used to remove vias, pins ...
55 #ifdef HAVE_LIBDMALLOC
59 /* ---------------------------------------------------------------------------
60 * some local prototypes
62 static void *DestroyVia (PinType
*);
63 static void *DestroyRat (RatType
*);
64 static void *DestroyLine (LayerType
*, LineType
*);
65 static void *DestroyArc (LayerType
*, ArcType
*);
66 static void *DestroyText (LayerType
*, TextType
*);
67 static void *DestroyPolygon (LayerType
*, PolygonType
*);
68 static void *DestroyElement (ElementType
*);
69 static void *RemoveVia (PinType
*);
70 static void *RemoveRat (RatType
*);
71 static void *DestroyPolygonPoint (LayerType
*, PolygonType
*, PointType
*);
72 static void *RemovePolygonContour (LayerType
*, PolygonType
*, Cardinal
);
73 static void *RemovePolygonPoint (LayerType
*, PolygonType
*, PointType
*);
74 static void *RemoveLinePoint (LayerType
*, LineType
*, PointType
*);
76 /* ---------------------------------------------------------------------------
79 static ObjectFunctionType RemoveFunctions
= {
93 static ObjectFunctionType DestroyFunctions
= {
107 static DataType
*DestroyTarget
;
108 static bool Bulk
= false;
110 /* ---------------------------------------------------------------------------
114 RemovePCB (PCBType
*Ptr
)
116 ClearUndoList (true);
121 /* ---------------------------------------------------------------------------
125 DestroyVia (PinType
*Via
)
127 r_delete_entry (DestroyTarget
->via_tree
, (BoxType
*) Via
);
130 DestroyTarget
->Via
= g_list_remove (DestroyTarget
->Via
, Via
);
131 DestroyTarget
->ViaN
--;
133 g_slice_free (PinType
, Via
);
138 /* ---------------------------------------------------------------------------
139 * destroys a line from a layer
142 DestroyLine (LayerType
*Layer
, LineType
*Line
)
144 r_delete_entry (Layer
->line_tree
, (BoxType
*) Line
);
147 Layer
->Line
= g_list_remove (Layer
->Line
, Line
);
150 g_slice_free (LineType
, Line
);
155 /* ---------------------------------------------------------------------------
156 * destroys an arc from a layer
159 DestroyArc (LayerType
*Layer
, ArcType
*Arc
)
161 r_delete_entry (Layer
->arc_tree
, (BoxType
*) Arc
);
163 Layer
->Arc
= g_list_remove (Layer
->Arc
, Arc
);
166 g_slice_free (ArcType
, Arc
);
171 /* ---------------------------------------------------------------------------
172 * destroys a polygon from a layer
175 DestroyPolygon (LayerType
*Layer
, PolygonType
*Polygon
)
177 r_delete_entry (Layer
->polygon_tree
, (BoxType
*) Polygon
);
178 FreePolygonMemory (Polygon
);
180 Layer
->Polygon
= g_list_remove (Layer
->Polygon
, Polygon
);
183 g_slice_free (PolygonType
, Polygon
);
188 /* ---------------------------------------------------------------------------
189 * removes a polygon-point from a polygon and destroys the data
192 DestroyPolygonPoint (LayerType
*Layer
,
193 PolygonType
*Polygon
, PointType
*Point
)
198 Cardinal contour_start
, contour_end
, contour_points
;
200 point_idx
= polygon_point_idx (Polygon
, Point
);
201 contour
= polygon_point_contour (Polygon
, point_idx
);
202 contour_start
= (contour
== 0) ? 0 : Polygon
->HoleIndex
[contour
- 1];
203 contour_end
= (contour
== Polygon
->HoleIndexN
) ? Polygon
->PointN
:
204 Polygon
->HoleIndex
[contour
];
205 contour_points
= contour_end
- contour_start
;
207 if (contour_points
<= 3)
208 return RemovePolygonContour (Layer
, Polygon
, contour
);
210 r_delete_entry (Layer
->polygon_tree
, (BoxType
*) Polygon
);
212 /* remove point from list, keep point order */
213 for (i
= point_idx
; i
< Polygon
->PointN
- 1; i
++)
214 Polygon
->Points
[i
] = Polygon
->Points
[i
+ 1];
217 /* Shift down indices of any holes */
218 for (i
= 0; i
< Polygon
->HoleIndexN
; i
++)
219 if (Polygon
->HoleIndex
[i
] > point_idx
)
220 Polygon
->HoleIndex
[i
]--;
222 SetPolygonBoundingBox (Polygon
);
223 r_insert_entry (Layer
->polygon_tree
, (BoxType
*) Polygon
, 0);
224 InitClip (PCB
->Data
, Layer
, Polygon
);
228 /* ---------------------------------------------------------------------------
229 * destroys a text from a layer
232 DestroyText (LayerType
*Layer
, TextType
*Text
)
234 free (Text
->TextString
);
235 r_delete_entry (Layer
->text_tree
, (BoxType
*) Text
);
237 Layer
->Text
= g_list_remove (Layer
->Text
, Text
);
240 g_slice_free (TextType
, Text
);
245 /* ---------------------------------------------------------------------------
249 DestroyElement (ElementType
*Element
)
251 if (DestroyTarget
->element_tree
)
252 r_delete_entry (DestroyTarget
->element_tree
, (BoxType
*) Element
);
253 if (DestroyTarget
->pin_tree
)
257 r_delete_entry (DestroyTarget
->pin_tree
, (BoxType
*) pin
);
261 if (DestroyTarget
->pad_tree
)
265 r_delete_entry (DestroyTarget
->pad_tree
, (BoxType
*) pad
);
269 ELEMENTTEXT_LOOP (Element
);
271 if (DestroyTarget
->name_tree
[n
])
272 r_delete_entry (DestroyTarget
->name_tree
[n
], (BoxType
*) text
);
275 FreeElementMemory (Element
);
277 DestroyTarget
->Element
= g_list_remove (DestroyTarget
->Element
, Element
);
278 DestroyTarget
->ElementN
--;
280 g_slice_free (ElementType
, Element
);
285 /* ---------------------------------------------------------------------------
289 DestroyRat (RatType
*Rat
)
291 if (DestroyTarget
->rat_tree
)
292 r_delete_entry (DestroyTarget
->rat_tree
, &Rat
->BoundingBox
);
294 DestroyTarget
->Rat
= g_list_remove (DestroyTarget
->Rat
, Rat
);
295 DestroyTarget
->RatN
--;
297 g_slice_free (RatType
, Rat
);
303 /* ---------------------------------------------------------------------------
307 RemoveVia (PinType
*Via
)
309 /* erase from screen and memory */
316 MoveObjectToRemoveUndoList (VIA_TYPE
, Via
, Via
, Via
);
320 /* ---------------------------------------------------------------------------
324 RemoveRat (RatType
*Rat
)
326 /* erase from screen and memory */
333 MoveObjectToRemoveUndoList (RATLINE_TYPE
, Rat
, Rat
, Rat
);
344 remove_point (const BoxType
* b
, void *cl
)
346 LineType
*line
= (LineType
*) b
;
347 struct rlp_info
*info
= (struct rlp_info
*) cl
;
348 if (line
== info
->line
)
350 if ((line
->Point1
.X
== info
->point
->X
)
351 && (line
->Point1
.Y
== info
->point
->Y
))
354 info
->point
= &line
->Point1
;
355 longjmp (info
->env
, 1);
358 if ((line
->Point2
.X
== info
->point
->X
)
359 && (line
->Point2
.Y
== info
->point
->Y
))
362 info
->point
= &line
->Point2
;
363 longjmp (info
->env
, 1);
368 /* ---------------------------------------------------------------------------
369 * removes a line point, or a line if the selected point is the end
372 RemoveLinePoint (LayerType
*Layer
, LineType
*Line
, PointType
*Point
)
375 struct rlp_info info
;
376 if (&Line
->Point1
== Point
)
377 other
= Line
->Point2
;
379 other
= Line
->Point1
;
382 if (setjmp (info
.env
) == 0)
384 r_search (Layer
->line_tree
, (const BoxType
*) Point
, NULL
, remove_point
,
386 return RemoveLine (Layer
, Line
);
388 MoveObject (LINEPOINT_TYPE
, Layer
, info
.line
, info
.point
,
389 other
.X
- Point
->X
, other
.Y
- Point
->Y
);
390 return (RemoveLine (Layer
, Line
));
393 /* ---------------------------------------------------------------------------
394 * removes a line from a layer
397 RemoveLine (LayerType
*Layer
, LineType
*Line
)
399 /* erase from screen */
406 MoveObjectToRemoveUndoList (LINE_TYPE
, Layer
, Line
, Line
);
410 /* ---------------------------------------------------------------------------
411 * removes an arc from a layer
414 RemoveArc (LayerType
*Layer
, ArcType
*Arc
)
416 /* erase from screen */
423 MoveObjectToRemoveUndoList (ARC_TYPE
, Layer
, Arc
, Arc
);
427 /* ---------------------------------------------------------------------------
428 * removes a text from a layer
431 RemoveText (LayerType
*Layer
, TextType
*Text
)
433 /* erase from screen */
436 EraseText (Layer
, Text
);
440 MoveObjectToRemoveUndoList (TEXT_TYPE
, Layer
, Text
, Text
);
444 /* ---------------------------------------------------------------------------
445 * removes a polygon from a layer
448 RemovePolygon (LayerType
*Layer
, PolygonType
*Polygon
)
450 /* erase from screen */
453 ErasePolygon (Polygon
);
457 MoveObjectToRemoveUndoList (POLYGON_TYPE
, Layer
, Polygon
, Polygon
);
461 /* ---------------------------------------------------------------------------
462 * removes a contour from a polygon.
463 * If removing the outer contour, it removes the whole polygon.
466 RemovePolygonContour (LayerType
*Layer
,
467 PolygonType
*Polygon
,
470 Cardinal contour_start
, contour_end
, contour_points
;
474 return RemovePolygon (Layer
, Polygon
);
478 ErasePolygon (Polygon
);
483 /* Copy the polygon to the undo list */
484 AddObjectToRemoveContourUndoList (POLYGON_TYPE
, Layer
, Polygon
);
486 contour_start
= (contour
== 0) ? 0 : Polygon
->HoleIndex
[contour
- 1];
487 contour_end
= (contour
== Polygon
->HoleIndexN
) ? Polygon
->PointN
:
488 Polygon
->HoleIndex
[contour
];
489 contour_points
= contour_end
- contour_start
;
491 /* remove points from list, keep point order */
492 for (i
= contour_start
; i
< Polygon
->PointN
- contour_points
; i
++)
493 Polygon
->Points
[i
] = Polygon
->Points
[i
+ contour_points
];
494 Polygon
->PointN
-= contour_points
;
496 /* remove hole from list and shift down remaining indices */
497 for (i
= contour
; i
< Polygon
->HoleIndexN
; i
++)
498 Polygon
->HoleIndex
[i
- 1] = Polygon
->HoleIndex
[i
] - contour_points
;
499 Polygon
->HoleIndexN
--;
501 InitClip (PCB
->Data
, Layer
, Polygon
);
502 /* redraw polygon if necessary */
505 DrawPolygon (Layer
, Polygon
);
512 /* ---------------------------------------------------------------------------
513 * removes a polygon-point from a polygon
516 RemovePolygonPoint (LayerType
*Layer
,
517 PolygonType
*Polygon
, PointType
*Point
)
522 Cardinal contour_start
, contour_end
, contour_points
;
524 point_idx
= polygon_point_idx (Polygon
, Point
);
525 contour
= polygon_point_contour (Polygon
, point_idx
);
526 contour_start
= (contour
== 0) ? 0 : Polygon
->HoleIndex
[contour
- 1];
527 contour_end
= (contour
== Polygon
->HoleIndexN
) ? Polygon
->PointN
:
528 Polygon
->HoleIndex
[contour
];
529 contour_points
= contour_end
- contour_start
;
531 if (contour_points
<= 3)
532 return RemovePolygonContour (Layer
, Polygon
, contour
);
535 ErasePolygon (Polygon
);
537 /* insert the polygon-point into the undo list */
538 AddObjectToRemovePointUndoList (POLYGONPOINT_TYPE
, Layer
, Polygon
, point_idx
);
539 r_delete_entry (Layer
->polygon_tree
, (BoxType
*) Polygon
);
541 /* remove point from list, keep point order */
542 for (i
= point_idx
; i
< Polygon
->PointN
- 1; i
++)
543 Polygon
->Points
[i
] = Polygon
->Points
[i
+ 1];
546 /* Shift down indices of any holes */
547 for (i
= 0; i
< Polygon
->HoleIndexN
; i
++)
548 if (Polygon
->HoleIndex
[i
] > point_idx
)
549 Polygon
->HoleIndex
[i
]--;
551 SetPolygonBoundingBox (Polygon
);
552 r_insert_entry (Layer
->polygon_tree
, (BoxType
*) Polygon
, 0);
553 RemoveExcessPolygonPoints (Layer
, Polygon
);
554 InitClip (PCB
->Data
, Layer
, Polygon
);
556 /* redraw polygon if necessary */
559 DrawPolygon (Layer
, Polygon
);
566 /* ---------------------------------------------------------------------------
570 RemoveElement (ElementType
*Element
)
572 /* erase from screen */
573 if ((PCB
->ElementOn
|| PCB
->PinOn
) &&
574 (FRONT (Element
) || PCB
->InvisibleObjectsOn
))
576 EraseElement (Element
);
580 MoveObjectToRemoveUndoList (ELEMENT_TYPE
, Element
, Element
, Element
);
584 /* ----------------------------------------------------------------------
585 * removes all selected and visible objects
586 * returns true if any objects have been removed
589 RemoveSelected (void)
592 if (SelectedOperation (&RemoveFunctions
, false, ALL_TYPES
))
594 IncrementUndoSerialNumber ();
603 /* ---------------------------------------------------------------------------
604 * remove object as referred by pointers and type,
605 * allocated memory is passed to the 'remove undo' list
608 RemoveObject (int Type
, void *Ptr1
, void *Ptr2
, void *Ptr3
)
610 void *ptr
= ObjectOperation (&RemoveFunctions
, Type
, Ptr1
, Ptr2
, Ptr3
);
614 /* ---------------------------------------------------------------------------
615 * DeleteRats - deletes rat lines only
616 * can delete all rat lines, or only selected one
620 DeleteRats (bool selected
)
622 bool changed
= false;
624 RAT_LOOP (PCB
->Data
);
626 if ((!selected
) || TEST_FLAG (SELECTEDFLAG
, line
))
637 IncrementUndoSerialNumber ();
642 /* ---------------------------------------------------------------------------
643 * remove object as referred by pointers and type
644 * allocated memory is destroyed assumed to already be erased
647 DestroyObject (DataType
*Target
, int Type
, void *Ptr1
,
648 void *Ptr2
, void *Ptr3
)
650 DestroyTarget
= Target
;
651 return (ObjectOperation (&DestroyFunctions
, Type
, Ptr1
, Ptr2
, Ptr3
));