src/undo.c: Converted plain comments into doxygen comments.
[geda-pcb/pcjc2.git] / src / copy.c
blob81b14a7f4ec8d59709065f4a86ae17986c9a241e
1 /*!
2 * \file src/copy.c
4 * \brief Functions used to copy pins, elements ...
6 * It's necessary to copy data by calling create... since the base pointer
7 * may change cause of dynamic memory allocation.
9 * <hr>
11 * <h1><b>Copyright.</b></h1>\n
13 * PCB, interactive printed circuit board design
15 * Copyright (C) 1994,1995,1996 Thomas Nau
17 * This program is free software; you can redistribute it and/or modify
18 * it under the terms of the GNU General Public License as published by
19 * the Free Software Foundation; either version 2 of the License, or
20 * (at your option) any later version.
22 * This program is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
27 * You should have received a copy of the GNU General Public License
28 * along with this program; if not, write to the Free Software
29 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
31 * Contact addresses for paper mail and Email:
32 * Thomas Nau, Schlehenweg 15, 88471 Baustetten, Germany
33 * Thomas.Nau@rz.uni-ulm.de
36 #ifdef HAVE_CONFIG_H
37 #include "config.h"
38 #endif
40 #include <stdlib.h>
42 #include "global.h"
44 #include "copy.h"
45 #include "create.h"
46 #include "data.h"
47 #include "draw.h"
48 #include "mymem.h"
49 #include "mirror.h"
50 #include "misc.h"
51 #include "move.h"
52 #include "polygon.h"
53 #include "rats.h"
54 #include "rtree.h"
55 #include "select.h"
56 #include "undo.h"
58 #ifdef HAVE_LIBDMALLOC
59 #include <dmalloc.h>
60 #endif
62 /* ---------------------------------------------------------------------------
63 * some local prototypes
65 static void *CopyVia (PinType *);
66 static void *CopyLine (LayerType *, LineType *);
67 static void *CopyArc (LayerType *, ArcType *);
68 static void *CopyText (LayerType *, TextType *);
69 static void *CopyPolygon (LayerType *, PolygonType *);
70 static void *CopyElement (ElementType *);
72 /* ---------------------------------------------------------------------------
73 * some local identifiers
75 static Coord 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 * \brief Copies data from one polygon to another.
94 * 'Dest' has to exist.
96 PolygonType *
97 CopyPolygonLowLevel (PolygonType *Dest, PolygonType *Src)
99 Cardinal hole = 0;
100 Cardinal n;
102 for (n = 0; n < Src->PointN; n++)
104 if (hole < Src->HoleIndexN && n == Src->HoleIndex[hole])
106 CreateNewHoleInPolygon (Dest);
107 hole++;
109 CreateNewPointInPolygon (Dest, Src->Points[n].X, Src->Points[n].Y);
111 SetPolygonBoundingBox (Dest);
112 Dest->Flags = Src->Flags;
113 CLEAR_FLAG (NOCOPY_FLAGS, Dest);
114 return (Dest);
118 * \brief Copies data from one element to another and creates the
119 * destination if necessary.
121 ElementType *
122 CopyElementLowLevel (DataType *Data, ElementType *Src,
123 bool uniqueName, Coord dx, Coord dy, int mask_flags)
125 int i;
126 ElementType *Dest;
128 /* both coordinates and flags are the same */
129 Dest = CreateNewElement (Data, &PCB->Font,
130 MaskFlags (Src->Flags, mask_flags),
131 DESCRIPTION_NAME (Src), NAMEONPCB_NAME (Src),
132 VALUE_NAME (Src), DESCRIPTION_TEXT (Src).X + dx,
133 DESCRIPTION_TEXT (Src).Y + dy,
134 DESCRIPTION_TEXT (Src).Direction,
135 DESCRIPTION_TEXT (Src).Scale,
136 MaskFlags (DESCRIPTION_TEXT (Src).Flags,
137 mask_flags), uniqueName);
139 /* abort on error */
140 if (!Dest)
141 return (Dest);
143 ELEMENTLINE_LOOP (Src);
145 CreateNewLineInElement (Dest, line->Point1.X + dx,
146 line->Point1.Y + dy, line->Point2.X + dx,
147 line->Point2.Y + dy, line->Thickness);
149 END_LOOP;
150 PIN_LOOP (Src);
152 CreateNewPin (Dest, pin->X + dx, pin->Y + dy, pin->Thickness,
153 pin->Clearance, pin->Mask, pin->DrillingHole,
154 pin->Name, pin->Number, MaskFlags (pin->Flags, mask_flags));
156 END_LOOP;
157 PAD_LOOP (Src);
159 CreateNewPad (Dest, pad->Point1.X + dx, pad->Point1.Y + dy,
160 pad->Point2.X + dx, pad->Point2.Y + dy, pad->Thickness,
161 pad->Clearance, pad->Mask, pad->Name, pad->Number,
162 MaskFlags (pad->Flags, mask_flags));
164 END_LOOP;
165 ARC_LOOP (Src);
167 CreateNewArcInElement (Dest, arc->X + dx, arc->Y + dy, arc->Width,
168 arc->Height, arc->StartAngle, arc->Delta,
169 arc->Thickness);
171 END_LOOP;
173 for (i=0; i<Src->Attributes.Number; i++)
174 CreateNewAttribute (& Dest->Attributes,
175 Src->Attributes.List[i].name,
176 Src->Attributes.List[i].value);
178 Dest->MarkX = Src->MarkX + dx;
179 Dest->MarkY = Src->MarkY + dy;
181 SetElementBoundingBox (Data, Dest, &PCB->Font);
182 return (Dest);
186 * \brief Copies a via.
188 static void *
189 CopyVia (PinType *Via)
191 PinType *via;
193 via = CreateNewVia (PCB->Data, Via->X + DeltaX, Via->Y + DeltaY,
194 Via->Thickness, Via->Clearance, Via->Mask,
195 Via->DrillingHole, Via->Name,
196 MaskFlags (Via->Flags, NOCOPY_FLAGS));
197 if (!via)
198 return (via);
199 DrawVia (via);
200 AddObjectToCreateUndoList (VIA_TYPE, via, via, via);
201 return (via);
205 * \brief Copies a line.
207 static void *
208 CopyLine (LayerType *Layer, LineType *Line)
210 LineType *line;
212 line = CreateDrawnLineOnLayer (Layer, Line->Point1.X + DeltaX,
213 Line->Point1.Y + DeltaY,
214 Line->Point2.X + DeltaX,
215 Line->Point2.Y + DeltaY, Line->Thickness,
216 Line->Clearance,
217 MaskFlags (Line->Flags, NOCOPY_FLAGS));
218 if (!line)
219 return (line);
220 if (Line->Number)
221 line->Number = strdup (Line->Number);
222 DrawLine (Layer, line);
223 AddObjectToCreateUndoList (LINE_TYPE, Layer, line, line);
224 return (line);
228 * \brief Copies an arc.
230 static void *
231 CopyArc (LayerType *Layer, ArcType *Arc)
233 ArcType *arc;
235 arc = CreateNewArcOnLayer (Layer, Arc->X + DeltaX,
236 Arc->Y + DeltaY, Arc->Width, Arc->Height, Arc->StartAngle,
237 Arc->Delta, Arc->Thickness, Arc->Clearance,
238 MaskFlags (Arc->Flags, NOCOPY_FLAGS));
239 if (!arc)
240 return (arc);
241 DrawArc (Layer, arc);
242 AddObjectToCreateUndoList (ARC_TYPE, Layer, arc, arc);
243 return (arc);
247 * \brief Copies a text.
249 static void *
250 CopyText (LayerType *Layer, TextType *Text)
252 TextType *text;
254 text = CreateNewText (Layer, &PCB->Font, Text->X + DeltaX,
255 Text->Y + DeltaY, Text->Direction,
256 Text->Scale, Text->TextString,
257 MaskFlags (Text->Flags, NOCOPY_FLAGS));
258 DrawText (Layer, text);
259 AddObjectToCreateUndoList (TEXT_TYPE, Layer, text, text);
260 return (text);
264 * \brief Copies a polygon.
266 static void *
267 CopyPolygon (LayerType *Layer, PolygonType *Polygon)
269 PolygonType *polygon;
271 polygon = CreateNewPolygon (Layer, NoFlags ());
272 CopyPolygonLowLevel (polygon, Polygon);
273 MovePolygonLowLevel (polygon, DeltaX, DeltaY);
274 if (!Layer->polygon_tree)
275 Layer->polygon_tree = r_create_tree (NULL, 0, 0);
276 r_insert_entry (Layer->polygon_tree, (BoxType *) polygon, 0);
277 InitClip (PCB->Data, Layer, polygon);
278 DrawPolygon (Layer, polygon);
279 AddObjectToCreateUndoList (POLYGON_TYPE, Layer, polygon, polygon);
280 return (polygon);
284 * \brief Copies an element onto the PCB, then does a draw.
286 static void *
287 CopyElement (ElementType *Element)
290 #ifdef DEBUG
291 printf("Entered CopyElement, trying to copy element %s\n",
292 Element->Name[1].TextString);
293 #endif
295 ElementType *element = CopyElementLowLevel (PCB->Data, Element,
296 TEST_FLAG (UNIQUENAMEFLAG, PCB),
297 DeltaX, DeltaY, NOCOPY_FLAGS);
299 /* this call clears the polygons */
300 AddObjectToCreateUndoList (ELEMENT_TYPE, element, element, element);
301 if (PCB->ElementOn && (FRONT (element) || PCB->InvisibleObjectsOn))
303 DrawElementName (element);
304 DrawElementPackage (element);
306 if (PCB->PinOn)
308 DrawElementPinsAndPads (element);
310 #ifdef DEBUG
311 printf(" ... Leaving CopyElement.\n");
312 #endif
313 return (element);
317 * \brief Pastes the contents of the buffer to the layout.
319 * \note Only visible objects are handled by the routine.
321 bool
322 CopyPastebufferToLayout (Coord X, Coord 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_copper_layer + SILK_LAYER; i++)
337 LayerType *sourcelayer = &PASTEBUFFER->Data->Layer[i];
338 LayerType *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);
412 * \brief Copies the object identified by its data pointers and the type
413 * the new objects is moved by DX,DY.
415 * \note I assume that the appropriate layer ... is switched on.
417 void *
418 CopyObject (int Type, void *Ptr1, void *Ptr2, void *Ptr3,
419 Coord DX, Coord DY)
421 void *ptr;
423 /* setup movement vector */
424 DeltaX = DX;
425 DeltaY = DY;
427 /* the subroutines add the objects to the undo-list */
428 ptr = ObjectOperation (&CopyFunctions, Type, Ptr1, Ptr2, Ptr3);
429 IncrementUndoSerialNumber ();
430 return (ptr);