Pass r_NoHolesPolygonDicer a POLYAREA *, not a PLINE *
[geda-pcb/gde.git] / src / copy.c
blob5a030c9f487f72a36a48534bd914e80ce981036f
1 /* $Id$ */
3 /*
4 * COPYRIGHT
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
29 /* functions used to copy pins, elements ...
30 * it's necessary to copy data by calling create... since the base pointer
31 * may change cause of dynamic memory allocation
34 #ifdef HAVE_CONFIG_H
35 #include "config.h"
36 #endif
38 #include <stdlib.h>
40 #include "global.h"
42 #include "copy.h"
43 #include "create.h"
44 #include "data.h"
45 #include "draw.h"
46 #include "mymem.h"
47 #include "mirror.h"
48 #include "misc.h"
49 #include "move.h"
50 #include "polygon.h"
51 #include "rats.h"
52 #include "rtree.h"
53 #include "select.h"
54 #include "undo.h"
56 #ifdef HAVE_LIBDMALLOC
57 #include <dmalloc.h>
58 #endif
60 RCSID ("$Id$");
62 /* ---------------------------------------------------------------------------
63 * some local prototypes
65 static void *CopyVia (PinTypePtr);
66 static void *CopyLine (LayerTypePtr, LineTypePtr);
67 static void *CopyArc (LayerTypePtr, ArcTypePtr);
68 static void *CopyText (LayerTypePtr, TextTypePtr);
69 static void *CopyPolygon (LayerTypePtr, PolygonTypePtr);
70 static void *CopyElement (ElementTypePtr);
72 /* ---------------------------------------------------------------------------
73 * some local identifiers
75 static LocationType DeltaX, DeltaY; /* movement vector */
76 static ObjectFunctionType CopyFunctions = {
77 CopyLine,
78 CopyText,
79 CopyPolygon,
80 CopyVia,
81 CopyElement,
82 NULL,
83 NULL,
84 NULL,
85 NULL,
86 NULL,
87 CopyArc,
88 NULL
91 /* ---------------------------------------------------------------------------
92 * copies data from one polygon to another
93 * 'Dest' has to exist
95 PolygonTypePtr
96 CopyPolygonLowLevel (PolygonTypePtr Dest, PolygonTypePtr Src)
98 /* copy all data */
99 POLYGONPOINT_LOOP (Src);
101 CreateNewPointInPolygon (Dest, point->X, point->Y);
103 END_LOOP;
104 SetPolygonBoundingBox (Dest);
105 Dest->Flags = Src->Flags;
106 CLEAR_FLAG (FOUNDFLAG, Dest);
107 return (Dest);
110 /* ---------------------------------------------------------------------------
111 * copies data from one element to another and creates the destination
112 * if necessary
114 ElementTypePtr
115 CopyElementLowLevel (DataTypePtr Data, ElementTypePtr Dest,
116 ElementTypePtr Src, Boolean uniqueName, LocationType dx,
117 LocationType dy)
119 int i;
120 /* release old memory if necessary */
121 if (Dest)
122 FreeElementMemory (Dest);
124 /* both coordinates and flags are the same */
125 Dest = CreateNewElement (Data, Dest, &PCB->Font,
126 MaskFlags (Src->Flags, FOUNDFLAG),
127 DESCRIPTION_NAME (Src), NAMEONPCB_NAME (Src),
128 VALUE_NAME (Src), DESCRIPTION_TEXT (Src).X + dx,
129 DESCRIPTION_TEXT (Src).Y + dy,
130 DESCRIPTION_TEXT (Src).Direction,
131 DESCRIPTION_TEXT (Src).Scale,
132 MaskFlags (DESCRIPTION_TEXT (Src).Flags,
133 FOUNDFLAG), uniqueName);
135 /* abort on error */
136 if (!Dest)
137 return (Dest);
139 ELEMENTLINE_LOOP (Src);
141 CreateNewLineInElement (Dest, line->Point1.X + dx,
142 line->Point1.Y + dy, line->Point2.X + dx,
143 line->Point2.Y + dy, line->Thickness);
145 END_LOOP;
146 PIN_LOOP (Src);
148 CreateNewPin (Dest, pin->X + dx, pin->Y + dy, pin->Thickness,
149 pin->Clearance, pin->Mask, pin->DrillingHole,
150 pin->Name, pin->Number, MaskFlags (pin->Flags, FOUNDFLAG));
152 END_LOOP;
153 PAD_LOOP (Src);
155 CreateNewPad (Dest, pad->Point1.X + dx, pad->Point1.Y + dy,
156 pad->Point2.X + dx, pad->Point2.Y + dy, pad->Thickness,
157 pad->Clearance, pad->Mask, pad->Name, pad->Number,
158 MaskFlags (pad->Flags, FOUNDFLAG));
160 END_LOOP;
161 ARC_LOOP (Src);
163 CreateNewArcInElement (Dest, arc->X + dx, arc->Y + dy, arc->Width,
164 arc->Height, arc->StartAngle, arc->Delta,
165 arc->Thickness);
167 END_LOOP;
169 for (i=0; i<Src->Attributes.Number; i++)
170 CreateNewAttribute (& Dest->Attributes,
171 Src->Attributes.List[i].name,
172 Src->Attributes.List[i].value);
174 Dest->MarkX = Src->MarkX + dx;
175 Dest->MarkY = Src->MarkY + dy;
177 SetElementBoundingBox (Data, Dest, &PCB->Font);
178 return (Dest);
181 /* ---------------------------------------------------------------------------
182 * copies a via
184 static void *
185 CopyVia (PinTypePtr Via)
187 PinTypePtr via;
189 via = CreateNewVia (PCB->Data, Via->X + DeltaX, Via->Y + DeltaY,
190 Via->Thickness, Via->Clearance, Via->Mask,
191 Via->DrillingHole, Via->Name,
192 MaskFlags (Via->Flags, FOUNDFLAG));
193 if (!via)
194 return (via);
195 DrawVia (via, 0);
196 AddObjectToCreateUndoList (VIA_TYPE, via, via, via);
197 return (via);
200 /* ---------------------------------------------------------------------------
201 * copies a line
203 static void *
204 CopyLine (LayerTypePtr Layer, LineTypePtr Line)
206 LineTypePtr line;
208 line = CreateDrawnLineOnLayer (Layer, Line->Point1.X + DeltaX,
209 Line->Point1.Y + DeltaY,
210 Line->Point2.X + DeltaX,
211 Line->Point2.Y + DeltaY, Line->Thickness,
212 Line->Clearance,
213 MaskFlags (Line->Flags, FOUNDFLAG));
214 if (!line)
215 return (line);
216 if (Line->Number)
217 line->Number = MyStrdup (Line->Number, "CopyLine");
218 DrawLine (Layer, line, 0);
219 AddObjectToCreateUndoList (LINE_TYPE, Layer, line, line);
220 return (line);
223 /* ---------------------------------------------------------------------------
224 * copies an arc
226 static void *
227 CopyArc (LayerTypePtr Layer, ArcTypePtr Arc)
229 ArcTypePtr arc;
231 arc = CreateNewArcOnLayer (Layer, Arc->X + DeltaX,
232 Arc->Y + DeltaY, Arc->Width, Arc->Height, Arc->StartAngle,
233 Arc->Delta, Arc->Thickness, Arc->Clearance,
234 MaskFlags (Arc->Flags, FOUNDFLAG));
235 if (!arc)
236 return (arc);
237 DrawArc (Layer, arc, 0);
238 AddObjectToCreateUndoList (ARC_TYPE, Layer, arc, arc);
239 return (arc);
242 /* ---------------------------------------------------------------------------
243 * copies a text
245 static void *
246 CopyText (LayerTypePtr Layer, TextTypePtr Text)
248 TextTypePtr text;
250 text = CreateNewText (Layer, &PCB->Font, Text->X + DeltaX,
251 Text->Y + DeltaY, Text->Direction,
252 Text->Scale, Text->TextString,
253 MaskFlags (Text->Flags, FOUNDFLAG));
254 DrawText (Layer, text, 0);
255 AddObjectToCreateUndoList (TEXT_TYPE, Layer, text, text);
256 return (text);
259 /* ---------------------------------------------------------------------------
260 * copies a polygon
262 static void *
263 CopyPolygon (LayerTypePtr Layer, PolygonTypePtr Polygon)
265 PolygonTypePtr polygon;
267 polygon = CreateNewPolygon (Layer, NoFlags ());
268 CopyPolygonLowLevel (polygon, Polygon);
269 MovePolygonLowLevel (polygon, DeltaX, DeltaY);
270 if (!Layer->polygon_tree)
271 Layer->polygon_tree = r_create_tree (NULL, 0, 0);
272 r_insert_entry (Layer->polygon_tree, (BoxTypePtr) polygon, 0);
273 InitClip (PCB->Data, Layer, polygon);
274 DrawPolygon (Layer, polygon, 0);
275 AddObjectToCreateUndoList (POLYGON_TYPE, Layer, polygon, polygon);
276 return (polygon);
279 /* ---------------------------------------------------------------------------
280 * copies a element
282 static void *
283 CopyElement (ElementTypePtr Element)
285 Boolean didDraw = False;
286 ElementTypePtr element = CopyElementLowLevel (PCB->Data,
287 NULL, Element,
288 TEST_FLAG (UNIQUENAMEFLAG,
289 PCB), DeltaX,
290 DeltaY);
292 /* this call clears the polygons */
293 AddObjectToCreateUndoList (ELEMENT_TYPE, element, element, element);
294 if (PCB->ElementOn && (FRONT (element) || PCB->InvisibleObjectsOn))
296 DrawElementName (element, 0);
297 DrawElementPackage (element, 0);
298 didDraw = True;
300 if (PCB->PinOn)
302 DrawElementPinsAndPads (element, 0);
303 didDraw = True;
305 return (element);
308 /* ---------------------------------------------------------------------------
309 * pastes the contents of the buffer to the layout. Only visible objects
310 * are handled by the routine.
312 Boolean
313 CopyPastebufferToLayout (LocationType X, LocationType Y)
315 Cardinal i;
316 Boolean changed = False;
318 /* set movement vector */
319 DeltaX = X - PASTEBUFFER->X, DeltaY = Y - PASTEBUFFER->Y;
321 /* paste all layers */
322 for (i = 0; i < max_layer + 2; i++)
324 LayerTypePtr sourcelayer = &PASTEBUFFER->Data->Layer[i],
325 destlayer = LAYER_PTR (i);
327 if (destlayer->On)
329 changed = changed ||
330 (sourcelayer->LineN != 0) ||
331 (sourcelayer->ArcN != 0) ||
332 (sourcelayer->PolygonN != 0) || (sourcelayer->TextN != 0);
333 LINE_LOOP (sourcelayer);
335 CopyLine (destlayer, line);
337 END_LOOP;
338 ARC_LOOP (sourcelayer);
340 CopyArc (destlayer, arc);
342 END_LOOP;
343 TEXT_LOOP (sourcelayer);
345 CopyText (destlayer, text);
347 END_LOOP;
348 POLYGON_LOOP (sourcelayer);
350 CopyPolygon (destlayer, polygon);
352 END_LOOP;
356 /* paste elements */
357 if (PCB->PinOn && PCB->ElementOn)
359 ELEMENT_LOOP (PASTEBUFFER->Data);
361 if (FRONT (element) || PCB->InvisibleObjectsOn)
363 CopyElement (element);
364 changed = True;
367 END_LOOP;
370 /* finally the vias */
371 if (PCB->ViaOn)
373 changed |= (PASTEBUFFER->Data->ViaN != 0);
374 VIA_LOOP (PASTEBUFFER->Data);
376 CopyVia (via);
378 END_LOOP;
380 if (changed)
382 Draw ();
383 IncrementUndoSerialNumber ();
385 return (changed);
388 /* ---------------------------------------------------------------------------
389 * copies the object identified by its data pointers and the type
390 * the new objects is moved by DX,DY
391 * I assume that the appropriate layer ... is switched on
393 void *
394 CopyObject (int Type, void *Ptr1, void *Ptr2, void *Ptr3,
395 LocationType DX, LocationType DY)
397 void *ptr;
399 /* setup movement vector */
400 DeltaX = DX;
401 DeltaY = DY;
403 /* the subroutines add the objects to the undo-list */
404 ptr = ObjectOperation (&CopyFunctions, Type, Ptr1, Ptr2, Ptr3);
405 IncrementUndoSerialNumber ();
406 return (ptr);