6 * PCB, interactive printed circuit board design
7 * Copyright (C) 1994,1995,1996, 2005 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 create vias, pins ...
57 #ifdef HAVE_LIBDMALLOC
63 /* ---------------------------------------------------------------------------
64 * some local identifiers
66 static int ID
= 1; /* current object ID; incremented after */
67 /* each creation of an object */
69 /* ----------------------------------------------------------------------
70 * some local prototypes
72 static void AddTextToElement (TextTypePtr
, FontTypePtr
,
73 LocationType
, LocationType
, BYTE
, char *, int,
76 /* ---------------------------------------------------------------------------
77 * creates a new paste buffer
80 CreateNewBuffer (void)
83 data
= (DataTypePtr
) MyCalloc (1, sizeof (DataType
), "CreateNewBuffer()");
84 data
->pcb
= (void *) PCB
;
88 /* ---------------------------------------------------------------------------
89 * Perhaps PCB should internally just use the Settings colors? For now,
90 * use this to set PCB colors so the config can reassign PCB colors.
93 pcb_colors_from_settings (PCBTypePtr ptr
)
97 /* copy default settings */
98 ptr
->ConnectedColor
= Settings
.ConnectedColor
;
99 ptr
->ElementColor
= Settings
.ElementColor
;
100 ptr
->RatColor
= Settings
.RatColor
;
101 ptr
->InvisibleObjectsColor
= Settings
.InvisibleObjectsColor
;
102 ptr
->InvisibleMarkColor
= Settings
.InvisibleMarkColor
;
103 ptr
->ElementSelectedColor
= Settings
.ElementSelectedColor
;
104 ptr
->RatSelectedColor
= Settings
.RatSelectedColor
;
105 ptr
->PinColor
= Settings
.PinColor
;
106 ptr
->PinSelectedColor
= Settings
.PinSelectedColor
;
107 ptr
->PinNameColor
= Settings
.PinNameColor
;
108 ptr
->ViaColor
= Settings
.ViaColor
;
109 ptr
->ViaSelectedColor
= Settings
.ViaSelectedColor
;
110 ptr
->WarnColor
= Settings
.WarnColor
;
111 ptr
->MaskColor
= Settings
.MaskColor
;
112 for (i
= 0; i
< MAX_LAYER
; i
++)
114 ptr
->Data
->Layer
[i
].Color
= Settings
.LayerColor
[i
];
115 ptr
->Data
->Layer
[i
].SelectedColor
= Settings
.LayerSelectedColor
[i
];
117 ptr
->Data
->Layer
[max_layer
+ COMPONENT_LAYER
].Color
=
118 Settings
.ShowSolderSide
?
119 Settings
.InvisibleObjectsColor
: Settings
.ElementColor
;
120 ptr
->Data
->Layer
[max_layer
+ COMPONENT_LAYER
].SelectedColor
=
121 Settings
.ElementSelectedColor
;
122 ptr
->Data
->Layer
[max_layer
+ SOLDER_LAYER
].Color
=
123 Settings
.ShowSolderSide
?
124 Settings
.ElementColor
: Settings
.InvisibleObjectsColor
;
125 ptr
->Data
->Layer
[max_layer
+ SOLDER_LAYER
].SelectedColor
=
126 Settings
.ElementSelectedColor
;
129 /* ---------------------------------------------------------------------------
133 CreateNewPCB (Boolean SetDefaultNames
)
138 /* allocate memory, switch all layers on and copy resources */
139 ptr
= MyCalloc (1, sizeof (PCBType
), "CreateNewPCB()");
140 ptr
->Data
= CreateNewBuffer ();
141 ptr
->Data
->pcb
= (void *) ptr
;
144 ptr
->IsleArea
= 2.e8
;
145 ptr
->SilkActive
= False
;
146 ptr
->RatDraw
= False
;
147 SET_FLAG (NAMEONPCBFLAG
, ptr
);
148 if (Settings
.ShowNumber
)
149 SET_FLAG (SHOWNUMBERFLAG
, ptr
);
150 if (Settings
.AllDirectionLines
)
151 SET_FLAG (ALLDIRECTIONFLAG
, ptr
);
152 ptr
->Clipping
= 1; /* this is the most useful starting point for now */
153 if (Settings
.RubberBandMode
)
154 SET_FLAG (RUBBERBANDFLAG
, ptr
);
155 if (Settings
.SwapStartDirection
)
156 SET_FLAG (SWAPSTARTDIRFLAG
, ptr
);
157 if (Settings
.UniqueNames
)
158 SET_FLAG (UNIQUENAMEFLAG
, ptr
);
159 if (Settings
.SnapPin
)
160 SET_FLAG (SNAPPINFLAG
, ptr
);
161 if (Settings
.ClearLine
)
162 SET_FLAG (CLEARNEWFLAG
, ptr
);
163 if (Settings
.FullPoly
)
164 SET_FLAG (NEWFULLPOLYFLAG
, ptr
);
165 if (Settings
.OrthogonalMoves
)
166 SET_FLAG (ORTHOMOVEFLAG
, ptr
);
167 if (Settings
.liveRouting
)
168 SET_FLAG (LIVEROUTEFLAG
, ptr
);
169 if (Settings
.ShowDRC
)
170 SET_FLAG (SHOWDRCFLAG
, ptr
);
171 if (Settings
.AutoDRC
)
172 SET_FLAG (AUTODRCFLAG
, ptr
);
173 ptr
->Grid
= Settings
.Grid
;
174 ptr
->LayerGroups
= Settings
.LayerGroups
;
177 *style
= Settings
.RouteStyle
[n
];
181 hid_action ("RouteStylesChanged");
182 ptr
->Zoom
= Settings
.Zoom
;
183 ptr
->MaxWidth
= Settings
.MaxWidth
;
184 ptr
->MaxHeight
= Settings
.MaxHeight
;
186 ptr
->ThermScale
= 0.5;
188 ptr
->Bloat
= Settings
.Bloat
;
189 ptr
->Shrink
= Settings
.Shrink
;
190 ptr
->minWid
= Settings
.minWid
;
191 ptr
->minSlk
= Settings
.minSlk
;
192 ptr
->minDrill
= Settings
.minDrill
;
193 ptr
->minRing
= Settings
.minRing
;
195 for (i
= 0; i
< MAX_LAYER
; i
++)
196 ptr
->Data
->Layer
[i
].Name
= MyStrdup (Settings
.DefaultLayerName
[i
],
202 /* This post-processing step adds the top and bottom silk layers to a
206 CreateNewPCBPost (PCBTypePtr pcb
, int use_defaults
)
208 /* copy default settings */
209 pcb_colors_from_settings (pcb
);
213 if (ParseGroupString (Settings
.Groups
, &pcb
->LayerGroups
, DEF_LAYER
))
216 pcb
->Data
->Layer
[max_layer
+ COMPONENT_LAYER
].Name
=
217 MyStrdup ("silk", "CreateNewPCB()");
218 pcb
->Data
->Layer
[max_layer
+ SOLDER_LAYER
].Name
=
219 MyStrdup ("silk", "CreateNewPCB()");
224 /* ---------------------------------------------------------------------------
228 CreateNewVia (DataTypePtr Data
,
229 LocationType X
, LocationType Y
,
230 BDimension Thickness
, BDimension Clearance
, BDimension Mask
,
231 BDimension DrillingHole
, char *Name
, FlagType Flags
)
237 if (SQUARE (via
->X
- X
) + SQUARE (via
->Y
- Y
) <=
238 SQUARE (via
->Thickness
/ 2 + Thickness
/ 2))
240 Message ("Dropping via at (%d, %d) because it would overlap with the via"
241 "at (%d, %d)\n", X
/100, Y
/100, via
->X
/100, via
->Y
/100);
242 return (NULL
); /* don't allow via stacking */
247 Via
= GetViaMemory (Data
);
254 Via
->Thickness
= Thickness
;
255 Via
->Clearance
= Clearance
;
257 Via
->DrillingHole
= vendorDrillMap (DrillingHole
);
258 if (Via
->DrillingHole
!= DrillingHole
)
261 ("Mapped via drill hole to %.2f mils from %.2f mils per vendor table\n"),
262 0.01 * Via
->DrillingHole
, 0.01 * DrillingHole
);
265 Via
->Name
= MyStrdup (Name
, "CreateNewVia()");
267 CLEAR_FLAG (WARNFLAG
, Via
);
268 SET_FLAG (VIAFLAG
, Via
);
272 * don't complain about MIN_PINORVIACOPPER on a mounting hole (pure
275 if (!TEST_FLAG (HOLEFLAG
, Via
) &&
276 (Via
->Thickness
< Via
->DrillingHole
+ MIN_PINORVIACOPPER
))
278 Via
->Thickness
= Via
->DrillingHole
+ MIN_PINORVIACOPPER
;
279 Message (_("Increased via thickness to %.2f mils to allow enough copper"
280 " at (%.2f,%.2f).\n"),
281 0.01 * Via
->Thickness
, 0.01 * Via
->X
, 0.01 * Via
->Y
);
284 SetPinBoundingBox (Via
);
286 Data
->via_tree
= r_create_tree (NULL
, 0, 0);
287 r_insert_entry (Data
->via_tree
, (BoxTypePtr
) Via
, 0);
293 LocationType X1
, X2
, Y1
, Y2
;
294 BDimension Thickness
;
301 line_callback (const BoxType
* b
, void *cl
)
303 LineTypePtr line
= (LineTypePtr
) b
;
304 struct line_info
*i
= (struct line_info
*) cl
;
306 if (line
->Point1
.X
== i
->X1
&&
307 line
->Point2
.X
== i
->X2
&&
308 line
->Point1
.Y
== i
->Y1
&& line
->Point2
.Y
== i
->Y2
)
310 i
->ans
= (LineTypePtr
) (-1);
313 /* check the other point order */
314 if (line
->Point1
.X
== i
->X1
&&
315 line
->Point2
.X
== i
->X2
&&
316 line
->Point1
.Y
== i
->Y1
&& line
->Point2
.Y
== i
->Y2
)
318 i
->ans
= (LineTypePtr
) (-1);
321 if (line
->Point2
.X
== i
->X1
&&
322 line
->Point1
.X
== i
->X2
&&
323 line
->Point2
.Y
== i
->Y1
&& line
->Point1
.Y
== i
->Y2
)
325 i
->ans
= (LineTypePtr
) - 1;
328 /* remove unnecessary line points */
329 if (line
->Thickness
== i
->Thickness
330 /* don't merge lines if the clear flags differ */
331 && TEST_FLAG (CLEARLINEFLAG
, line
) == TEST_FLAG (CLEARLINEFLAG
, i
))
333 if (line
->Point1
.X
== i
->X1
&& line
->Point1
.Y
== i
->Y1
)
335 i
->test
.Point1
.X
= line
->Point2
.X
;
336 i
->test
.Point1
.Y
= line
->Point2
.Y
;
337 i
->test
.Point2
.X
= i
->X2
;
338 i
->test
.Point2
.Y
= i
->Y2
;
339 if (IsPointOnLine ((float) i
->X1
, (float) i
->Y1
, 0.0, &i
->test
))
345 else if (line
->Point2
.X
== i
->X1
&& line
->Point2
.Y
== i
->Y1
)
347 i
->test
.Point1
.X
= line
->Point1
.X
;
348 i
->test
.Point1
.Y
= line
->Point1
.Y
;
349 i
->test
.Point2
.X
= i
->X2
;
350 i
->test
.Point2
.Y
= i
->Y2
;
351 if (IsPointOnLine ((float) i
->X1
, (float) i
->Y1
, 0.0, &i
->test
))
357 else if (line
->Point1
.X
== i
->X2
&& line
->Point1
.Y
== i
->Y2
)
359 i
->test
.Point1
.X
= line
->Point2
.X
;
360 i
->test
.Point1
.Y
= line
->Point2
.Y
;
361 i
->test
.Point2
.X
= i
->X1
;
362 i
->test
.Point2
.Y
= i
->Y1
;
363 if (IsPointOnLine ((float) i
->X2
, (float) i
->Y2
, 0.0, &i
->test
))
369 else if (line
->Point2
.X
== i
->X2
&& line
->Point2
.Y
== i
->Y2
)
371 i
->test
.Point1
.X
= line
->Point1
.X
;
372 i
->test
.Point1
.Y
= line
->Point1
.Y
;
373 i
->test
.Point2
.X
= i
->X1
;
374 i
->test
.Point2
.Y
= i
->Y1
;
375 if (IsPointOnLine ((float) i
->X2
, (float) i
->Y2
, 0.0, &i
->test
))
386 /* ---------------------------------------------------------------------------
387 * creates a new line on a layer and checks for overlap and extension
390 CreateDrawnLineOnLayer (LayerTypePtr Layer
,
391 LocationType X1
, LocationType Y1
,
392 LocationType X2
, LocationType Y2
,
393 BDimension Thickness
, BDimension Clearance
,
396 struct line_info info
;
399 search
.X1
= MIN (X1
, X2
);
400 search
.X2
= MAX (X1
, X2
);
401 search
.Y1
= MIN (Y1
, Y2
);
402 search
.Y2
= MAX (Y1
, Y2
);
403 if (search
.Y2
== search
.Y1
)
405 if (search
.X2
== search
.X1
)
411 info
.Thickness
= Thickness
;
413 info
.test
.Thickness
= 0;
414 info
.test
.Flags
= NoFlags ();
416 /* prevent stacking of duplicate lines
417 * and remove needless intermediate points
418 * verify that the layer is on the board first!
420 if (setjmp (info
.env
) == 0)
422 r_search (Layer
->line_tree
, &search
, NULL
, line_callback
, &info
);
423 return CreateNewLineOnLayer (Layer
, X1
, Y1
, X2
, Y2
,
424 Thickness
, Clearance
, Flags
);
427 if ((void *) info
.ans
== (void *) (-1))
428 return NULL
; /* stacked line */
429 /* remove unnecessary points */
432 /* must do this BEFORE getting new line memory */
433 MoveObjectToRemoveUndoList (LINE_TYPE
, Layer
, info
.ans
, info
.ans
);
434 X1
= info
.test
.Point1
.X
;
435 X2
= info
.test
.Point2
.X
;
436 Y1
= info
.test
.Point1
.Y
;
437 Y2
= info
.test
.Point2
.Y
;
439 return CreateNewLineOnLayer (Layer
, X1
, Y1
, X2
, Y2
,
440 Thickness
, Clearance
, Flags
);
444 CreateNewLineOnLayer (LayerTypePtr Layer
,
445 LocationType X1
, LocationType Y1
,
446 LocationType X2
, LocationType Y2
,
447 BDimension Thickness
, BDimension Clearance
,
452 Line
= GetLineMemory (Layer
);
457 CLEAR_FLAG (RATFLAG
, Line
);
458 Line
->Thickness
= Thickness
;
459 Line
->Clearance
= Clearance
;
462 Line
->Point1
.ID
= ID
++;
465 Line
->Point2
.ID
= ID
++;
466 SetLineBoundingBox (Line
);
467 if (!Layer
->line_tree
)
468 Layer
->line_tree
= r_create_tree (NULL
, 0, 0);
469 r_insert_entry (Layer
->line_tree
, (BoxTypePtr
) Line
, 0);
473 /* ---------------------------------------------------------------------------
474 * creates a new rat-line
477 CreateNewRat (DataTypePtr Data
, LocationType X1
, LocationType Y1
,
478 LocationType X2
, LocationType Y2
, Cardinal group1
,
479 Cardinal group2
, BDimension Thickness
, FlagType Flags
)
481 RatTypePtr Line
= GetRatMemory (Data
);
488 SET_FLAG (RATFLAG
, Line
);
489 Line
->Thickness
= Thickness
;
492 Line
->Point1
.ID
= ID
++;
495 Line
->Point2
.ID
= ID
++;
496 Line
->group1
= group1
;
497 Line
->group2
= group2
;
498 SetLineBoundingBox ((LineTypePtr
) Line
);
500 Data
->rat_tree
= r_create_tree (NULL
, 0, 0);
501 r_insert_entry (Data
->rat_tree
, &Line
->BoundingBox
, 0);
505 /* ---------------------------------------------------------------------------
506 * creates a new arc on a layer
509 CreateNewArcOnLayer (LayerTypePtr Layer
,
510 LocationType X1
, LocationType Y1
,
514 int dir
, BDimension Thickness
,
515 BDimension Clearance
, FlagType Flags
)
521 if (arc
->X
== X1
&& arc
->Y
== Y1
&& arc
->Width
== width
&&
522 (arc
->StartAngle
+ 360) % 360 == (sa
+ 360) % 360 &&
524 return (NULL
); /* prevent stacked arcs */
527 Arc
= GetArcMemory (Layer
);
533 Arc
->Thickness
= Thickness
;
534 Arc
->Clearance
= Clearance
;
538 Arc
->Height
= height
;
539 Arc
->StartAngle
= sa
;
541 SetArcBoundingBox (Arc
);
542 if (!Layer
->arc_tree
)
543 Layer
->arc_tree
= r_create_tree (NULL
, 0, 0);
544 r_insert_entry (Layer
->arc_tree
, (BoxTypePtr
) Arc
, 0);
549 /* ---------------------------------------------------------------------------
550 * creates a new polygon from the old formats rectangle data
553 CreateNewPolygonFromRectangle (LayerTypePtr Layer
,
554 LocationType X1
, LocationType Y1
,
555 LocationType X2
, LocationType Y2
,
558 PolygonTypePtr polygon
= CreateNewPolygon (Layer
, Flags
);
562 CreateNewPointInPolygon (polygon
, X1
, Y1
);
563 CreateNewPointInPolygon (polygon
, X2
, Y1
);
564 CreateNewPointInPolygon (polygon
, X2
, Y2
);
565 CreateNewPointInPolygon (polygon
, X1
, Y2
);
566 SetPolygonBoundingBox (polygon
);
567 if (!Layer
->polygon_tree
)
568 Layer
->polygon_tree
= r_create_tree (NULL
, 0, 0);
569 r_insert_entry (Layer
->polygon_tree
, (BoxTypePtr
) polygon
, 0);
573 /* ---------------------------------------------------------------------------
574 * creates a new text on a layer
577 CreateNewText (LayerTypePtr Layer
, FontTypePtr PCBFont
,
578 LocationType X
, LocationType Y
,
579 BYTE Direction
, int Scale
, char *TextString
, FlagType Flags
)
581 TextTypePtr text
= GetTextMemory (Layer
);
585 /* copy values, width and height are set by drawing routine
586 * because at this point we don't know which symbols are available
590 text
->Direction
= Direction
;
593 text
->TextString
= MyStrdup (TextString
, "CreateNewText()");
595 /* calculate size of the bounding box */
596 SetTextBoundingBox (PCBFont
, text
);
598 if (!Layer
->text_tree
)
599 Layer
->text_tree
= r_create_tree (NULL
, 0, 0);
600 r_insert_entry (Layer
->text_tree
, (BoxTypePtr
) text
, 0);
604 /* ---------------------------------------------------------------------------
605 * creates a new polygon on a layer
608 CreateNewPolygon (LayerTypePtr Layer
, FlagType Flags
)
610 PolygonTypePtr polygon
= GetPolygonMemory (Layer
);
613 polygon
->Flags
= Flags
;
615 polygon
->Clipped
= NULL
;
616 polygon
->NoHoles
= NULL
;
617 polygon
->NoHolesValid
= 0;
621 /* ---------------------------------------------------------------------------
622 * creates a new point in a polygon
625 CreateNewPointInPolygon (PolygonTypePtr Polygon
, LocationType X
,
628 PointTypePtr point
= GetPointMemoryInPolygon (Polygon
);
637 /* ---------------------------------------------------------------------------
638 * creates an new element
639 * memory is allocated if needed
642 CreateNewElement (DataTypePtr Data
, ElementTypePtr Element
,
645 char *Description
, char *NameOnPCB
, char *Value
,
646 LocationType TextX
, LocationType TextY
, BYTE Direction
,
647 int TextScale
, FlagType TextFlags
, Boolean uniqueName
)
650 printf("Entered CreateNewElement.....\n");
654 Element
= GetElementMemory (Data
);
656 /* copy values and set additional information */
657 TextScale
= MAX (MIN_TEXTSCALE
, TextScale
);
658 AddTextToElement (&DESCRIPTION_TEXT (Element
), PCBFont
, TextX
, TextY
,
659 Direction
, Description
, TextScale
, TextFlags
);
661 NameOnPCB
= UniqueElementName (Data
, NameOnPCB
);
662 AddTextToElement (&NAMEONPCB_TEXT (Element
), PCBFont
, TextX
, TextY
,
663 Direction
, NameOnPCB
, TextScale
, TextFlags
);
664 AddTextToElement (&VALUE_TEXT (Element
), PCBFont
, TextX
, TextY
,
665 Direction
, Value
, TextScale
, TextFlags
);
666 DESCRIPTION_TEXT (Element
).Element
= Element
;
667 NAMEONPCB_TEXT (Element
).Element
= Element
;
668 VALUE_TEXT (Element
).Element
= Element
;
669 Element
->Flags
= Flags
;
673 printf(" .... Leaving CreateNewElement.\n");
679 /* ---------------------------------------------------------------------------
680 * creates a new arc in an element
683 CreateNewArcInElement (ElementTypePtr Element
,
684 LocationType X
, LocationType Y
,
685 BDimension Width
, BDimension Height
,
686 int Angle
, int Delta
, BDimension Thickness
)
688 ArcTypePtr arc
= Element
->Arc
;
690 /* realloc new memory if necessary and clear it */
691 if (Element
->ArcN
>= Element
->ArcMax
)
693 Element
->ArcMax
+= STEP_ELEMENTARC
;
694 arc
= MyRealloc (arc
, Element
->ArcMax
* sizeof (ArcType
),
695 "CreateNewArcInElement()");
697 memset (arc
+ Element
->ArcN
, 0, STEP_ELEMENTARC
* sizeof (ArcType
));
700 /* set Delta (0,360], StartAngle in [0,360) */
701 if ((Delta
= Delta
% 360) == 0)
708 if ((Angle
= Angle
% 360) < 0)
712 arc
= arc
+ Element
->ArcN
++;
716 arc
->Height
= Height
;
717 arc
->StartAngle
= Angle
;
719 arc
->Thickness
= Thickness
;
724 /* ---------------------------------------------------------------------------
725 * creates a new line for an element
728 CreateNewLineInElement (ElementTypePtr Element
,
729 LocationType X1
, LocationType Y1
,
730 LocationType X2
, LocationType Y2
,
731 BDimension Thickness
)
733 LineTypePtr line
= Element
->Line
;
737 /* realloc new memory if necessary and clear it */
738 if (Element
->LineN
>= Element
->LineMax
)
740 Element
->LineMax
+= STEP_ELEMENTLINE
;
741 line
= MyRealloc (line
, Element
->LineMax
* sizeof (LineType
),
742 "CreateNewLineInElement()");
743 Element
->Line
= line
;
744 memset (line
+ Element
->LineN
, 0, STEP_ELEMENTLINE
* sizeof (LineType
));
748 line
= line
+ Element
->LineN
++;
753 line
->Thickness
= Thickness
;
754 line
->Flags
= NoFlags ();
759 /* ---------------------------------------------------------------------------
760 * creates a new pin in an element
763 CreateNewPin (ElementTypePtr Element
,
764 LocationType X
, LocationType Y
,
765 BDimension Thickness
, BDimension Clearance
, BDimension Mask
,
766 BDimension DrillingHole
, char *Name
, char *Number
,
769 PinTypePtr pin
= GetPinMemory (Element
);
774 pin
->Thickness
= Thickness
;
775 pin
->Clearance
= Clearance
;
777 pin
->Name
= MyStrdup (Name
, "CreateNewPin()");
778 pin
->Number
= MyStrdup (Number
, "CreateNewPin()");
780 CLEAR_FLAG (WARNFLAG
, pin
);
781 SET_FLAG (PINFLAG
, pin
);
783 pin
->Element
= Element
;
786 * If there is no vendor drill map installed, this will simply
787 * return DrillingHole.
789 pin
->DrillingHole
= vendorDrillMap (DrillingHole
);
791 /* Unless we should not map drills on this element, map them! */
792 if (vendorIsElementMappable (Element
))
794 if (pin
->DrillingHole
< MIN_PINORVIASIZE
)
797 ("Did not map pin #%s (%s) drill hole because %6.2f mil is below the minimum allowed size\n"),
798 UNKNOWN (Number
), UNKNOWN (Name
),
799 0.01 * pin
->DrillingHole
);
800 pin
->DrillingHole
= DrillingHole
;
802 else if (pin
->DrillingHole
> MAX_PINORVIASIZE
)
805 ("Did not map pin #%s (%s) drill hole because %6.2f mil is above the maximum allowed size\n"),
806 UNKNOWN (Number
), UNKNOWN (Name
),
807 0.01 * pin
->DrillingHole
);
808 pin
->DrillingHole
= DrillingHole
;
810 else if (!TEST_FLAG (HOLEFLAG
, pin
)
811 && (pin
->DrillingHole
> pin
->Thickness
- MIN_PINORVIACOPPER
))
814 ("Did not map pin #%s (%s) drill hole because %6.2f mil does not leave enough copper\n"),
815 UNKNOWN (Number
), UNKNOWN (Name
),
816 0.01 * pin
->DrillingHole
);
817 pin
->DrillingHole
= DrillingHole
;
822 pin
->DrillingHole
= DrillingHole
;
825 if (pin
->DrillingHole
!= DrillingHole
)
828 ("Mapped pin drill hole to %.2f mils from %.2f mils per vendor table\n"),
829 0.01 * pin
->DrillingHole
, 0.01 * DrillingHole
);
835 /* ---------------------------------------------------------------------------
836 * creates a new pad in an element
839 CreateNewPad (ElementTypePtr Element
,
840 LocationType X1
, LocationType Y1
, LocationType X2
,
841 LocationType Y2
, BDimension Thickness
, BDimension Clearance
,
842 BDimension Mask
, char *Name
, char *Number
, FlagType Flags
)
844 PadTypePtr pad
= GetPadMemory (Element
);
847 if (X1
> X2
|| (X1
== X2
&& Y1
> Y2
))
861 pad
->Thickness
= Thickness
;
862 pad
->Clearance
= Clearance
;
864 pad
->Name
= MyStrdup (Name
, "CreateNewPad()");
865 pad
->Number
= MyStrdup (Number
, "CreateNewPad()");
867 CLEAR_FLAG (WARNFLAG
, pad
);
869 pad
->Element
= Element
;
873 /* ---------------------------------------------------------------------------
874 * creates a new textobject as part of an element
875 * copies the values to the appropriate text object
878 AddTextToElement (TextTypePtr Text
, FontTypePtr PCBFont
,
879 LocationType X
, LocationType Y
,
880 BYTE Direction
, char *TextString
, int Scale
, FlagType Flags
)
882 MYFREE (Text
->TextString
);
885 Text
->Direction
= Direction
;
888 Text
->TextString
= (TextString
&& *TextString
) ?
889 MyStrdup (TextString
, "AddTextToElement()") : NULL
;
891 /* calculate size of the bounding box */
892 SetTextBoundingBox (PCBFont
, Text
);
896 /* ---------------------------------------------------------------------------
897 * creates a new line in a symbol
900 CreateNewLineInSymbol (SymbolTypePtr Symbol
,
901 LocationType X1
, LocationType Y1
,
902 LocationType X2
, LocationType Y2
, BDimension Thickness
)
904 LineTypePtr line
= Symbol
->Line
;
906 /* realloc new memory if necessary and clear it */
907 if (Symbol
->LineN
>= Symbol
->LineMax
)
909 Symbol
->LineMax
+= STEP_SYMBOLLINE
;
910 line
= MyRealloc (line
, Symbol
->LineMax
* sizeof (LineType
),
911 "CreateNewLineInSymbol()");
913 memset (line
+ Symbol
->LineN
, 0, STEP_SYMBOLLINE
* sizeof (LineType
));
917 line
= line
+ Symbol
->LineN
++;
922 line
->Thickness
= Thickness
;
926 /* ---------------------------------------------------------------------------
927 * parses a file with font information and installs it
928 * checks directories given as colon separated list by resource fontPath
929 * if the fonts filename doesn't contain a directory component
932 CreateDefaultFont (void)
934 if (ParseFont (&PCB
->Font
, Settings
.FontFile
))
935 Message (_("Can't find font-symbol-file '%s'\n"), Settings
.FontFile
);
938 /* ---------------------------------------------------------------------------
939 * adds a new line to the rubberband list of 'Crosshair.AttachedObject'
940 * if Layer == 0 it is a rat line
943 CreateNewRubberbandEntry (LayerTypePtr Layer
,
944 LineTypePtr Line
, PointTypePtr MovedPoint
)
946 RubberbandTypePtr ptr
= GetRubberbandMemory ();
948 /* we toggle the RUBBERENDFLAG of the line to determine if */
949 /* both points are being moved. */
950 TOGGLE_FLAG (RUBBERENDFLAG
, Line
);
953 ptr
->MovedPoint
= MovedPoint
;
957 /* ---------------------------------------------------------------------------
958 * Add a new net to the netlist menu
961 CreateNewNet (LibraryTypePtr lib
, char *name
, char *style
)
963 LibraryMenuTypePtr menu
;
966 sprintf (temp
, " %s", name
);
967 menu
= GetLibraryMenuMemory (lib
);
968 menu
->Name
= MyStrdup (temp
, "CreateNewNet()");
969 menu
->flag
= 1; /* net is enabled by default */
970 if (style
== NULL
|| NSTRCMP ("(unknown)", style
) == 0)
973 menu
->Style
= MyStrdup (style
, "CreateNewNet()");
977 /* ---------------------------------------------------------------------------
978 * Add a connection to the net
981 CreateNewConnection (LibraryMenuTypePtr net
, char *conn
)
983 LibraryEntryTypePtr entry
= GetLibraryEntryMemory (net
);
985 entry
->ListEntry
= MyStrdup (conn
, "CreateNewConnection()");
989 /* ---------------------------------------------------------------------------
990 * Add an attribute to a list.
993 CreateNewAttribute (AttributeListTypePtr list
, char *name
, char *value
)
995 if (list
->Number
>= list
->Max
)
998 list
->List
= MyRealloc (list
->List
,
999 list
->Max
* sizeof (AttributeType
),
1000 "CreateNewAttribute");
1002 list
->List
[list
->Number
].name
= MyStrdup (name
, "CreateNewAttribute");
1003 list
->List
[list
->Number
].value
= MyStrdup (value
, "CreateNewAttribute");
1005 return &list
->List
[list
->Number
- 1];