Change all Booleans to bool.
[geda-pcb/gde.git] / src / copy.c
blobffa0ed3ecd3951a243aea27d5c9fc916a1a04752
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, bool 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 an element onto the PCB. Then does a draw.
282 static void *
283 CopyElement (ElementTypePtr Element)
286 #ifdef DEBUG
287 printf("Entered CopyElement, trying to copy element %s\n",
288 Element->Name[1].TextString);
289 #endif
291 bool didDraw = false;
292 ElementTypePtr element = CopyElementLowLevel (PCB->Data,
293 NULL, Element,
294 TEST_FLAG (UNIQUENAMEFLAG,
295 PCB), DeltaX,
296 DeltaY);
298 /* this call clears the polygons */
299 AddObjectToCreateUndoList (ELEMENT_TYPE, element, element, element);
300 if (PCB->ElementOn && (FRONT (element) || PCB->InvisibleObjectsOn))
302 DrawElementName (element, 0);
303 DrawElementPackage (element, 0);
304 didDraw = true;
306 if (PCB->PinOn)
308 DrawElementPinsAndPads (element, 0);
309 didDraw = true;
311 #ifdef DEBUG
312 printf(" ... Leaving CopyElement.\n");
313 #endif
314 return (element);
317 /* ---------------------------------------------------------------------------
318 * pastes the contents of the buffer to the layout. Only visible objects
319 * are handled by the routine.
321 bool
322 CopyPastebufferToLayout (LocationType X, LocationType Y)
324 Cardinal i;
325 bool changed = false;
327 #ifdef DEBUG
328 printf("Entering CopyPastebufferToLayout.....\n");
329 #endif
331 /* set movement vector */
332 DeltaX = X - PASTEBUFFER->X, DeltaY = Y - PASTEBUFFER->Y;
334 /* paste all layers */
335 for (i = 0; i < max_layer + 2; i++)
337 LayerTypePtr sourcelayer = &PASTEBUFFER->Data->Layer[i],
338 destlayer = LAYER_PTR (i);
340 if (destlayer->On)
342 changed = changed ||
343 (sourcelayer->LineN != 0) ||
344 (sourcelayer->ArcN != 0) ||
345 (sourcelayer->PolygonN != 0) || (sourcelayer->TextN != 0);
346 LINE_LOOP (sourcelayer);
348 CopyLine (destlayer, line);
350 END_LOOP;
351 ARC_LOOP (sourcelayer);
353 CopyArc (destlayer, arc);
355 END_LOOP;
356 TEXT_LOOP (sourcelayer);
358 CopyText (destlayer, text);
360 END_LOOP;
361 POLYGON_LOOP (sourcelayer);
363 CopyPolygon (destlayer, polygon);
365 END_LOOP;
369 /* paste elements */
370 if (PCB->PinOn && PCB->ElementOn)
372 ELEMENT_LOOP (PASTEBUFFER->Data);
374 #ifdef DEBUG
375 printf("In CopyPastebufferToLayout, pasting element %s\n",
376 element->Name[1].TextString);
377 #endif
378 if (FRONT (element) || PCB->InvisibleObjectsOn)
380 CopyElement (element);
381 changed = true;
384 END_LOOP;
387 /* finally the vias */
388 if (PCB->ViaOn)
390 changed |= (PASTEBUFFER->Data->ViaN != 0);
391 VIA_LOOP (PASTEBUFFER->Data);
393 CopyVia (via);
395 END_LOOP;
398 if (changed)
400 Draw ();
401 IncrementUndoSerialNumber ();
404 #ifdef DEBUG
405 printf(" .... Leaving CopyPastebufferToLayout.\n");
406 #endif
408 return (changed);
411 /* ---------------------------------------------------------------------------
412 * copies the object identified by its data pointers and the type
413 * the new objects is moved by DX,DY
414 * I assume that the appropriate layer ... is switched on
416 void *
417 CopyObject (int Type, void *Ptr1, void *Ptr2, void *Ptr3,
418 LocationType DX, LocationType DY)
420 void *ptr;
422 /* setup movement vector */
423 DeltaX = DX;
424 DeltaY = DY;
426 /* the subroutines add the objects to the undo-list */
427 ptr = ObjectOperation (&CopyFunctions, Type, Ptr1, Ptr2, Ptr3);
428 IncrementUndoSerialNumber ();
429 return (ptr);