44
50
#include "parse_l.h"
45
52
#include "search.h"
57
#ifdef HAVE_LIBDMALLOC
61
RCSID("$Id: create.c,v 1.20 2005/01/21 22:46:56 danmc Exp $");
49
63
/* ---------------------------------------------------------------------------
50
64
* some local identifiers
52
static int ID = 1; /* current object ID; incremented after */
66
static int ID = 1; /* current object ID; incremented after */
53
67
/* each creation of an object */
55
69
/* ----------------------------------------------------------------------
56
70
* some local prototypes
58
static void AddTextToElement(TextTypePtr, FontTypePtr,
59
Position, Position, BYTE, char *, int, int);
72
static void AddTextToElement (TextTypePtr, FontTypePtr,
73
LocationType, LocationType, BYTE, char *, int, int);
61
75
/* ---------------------------------------------------------------------------
62
76
* creates a new paste buffer
64
DataTypePtr CreateNewBuffer(void)
79
CreateNewBuffer (void)
66
return((DataTypePtr) MyCalloc(1, sizeof(DataType), "CreateNewBuffer()"));
82
data = (DataTypePtr) MyCalloc (1, sizeof (DataType), "CreateNewBuffer()");
69
86
/* ---------------------------------------------------------------------------
70
87
* creates a new PCB
72
PCBTypePtr CreateNewPCB(Boolean SetDefaultNames)
90
CreateNewPCB (Boolean SetDefaultNames)
77
/* allocate memory, switch all layers on and copy resources */
78
ptr = MyCalloc(1, sizeof(PCBType), "CreateNewPCB()");
79
ptr->Data = CreateNewBuffer();
81
/* copy default settings */
82
ptr->ConnectedColor = Settings.ConnectedColor;
83
ptr->ElementColor = Settings.ElementColor;
84
ptr->RatColor = Settings.RatColor;
85
ptr->InvisibleObjectsColor = Settings.InvisibleObjectsColor;
86
ptr->InvisibleMarkColor = Settings.InvisibleMarkColor;
87
ptr->ElementSelectedColor = Settings.ElementSelectedColor;
88
ptr->RatSelectedColor = Settings.RatSelectedColor;
89
ptr->PinColor = Settings.PinColor;
90
ptr->PinSelectedColor = Settings.PinSelectedColor;
91
ptr->ViaColor = Settings.ViaColor;
92
ptr->ViaSelectedColor = Settings.ViaSelectedColor;
93
ptr->WarnColor = Settings.WarnColor;
94
for (i = 0; i < MAX_LAYER; i++)
96
ptr->Data->Layer[i].Color = Settings.LayerColor[i];
97
ptr->Data->Layer[i].SelectedColor = Settings.LayerSelectedColor[i];
99
ptr->Data->Layer[MAX_LAYER + COMPONENT_LAYER].Color =
100
Settings.ShowSolderSide ? Settings.InvisibleObjectsColor : Settings.ElementColor;
101
ptr->Data->Layer[MAX_LAYER + COMPONENT_LAYER].SelectedColor = Settings.ElementSelectedColor;
102
ptr->Data->Layer[MAX_LAYER + SOLDER_LAYER].Color =
103
Settings.ShowSolderSide ? Settings.ElementColor : Settings.InvisibleObjectsColor;
104
ptr->Data->Layer[MAX_LAYER + SOLDER_LAYER].SelectedColor = Settings.ElementSelectedColor;
107
for (i = 0; i < MAX_LAYER; i++)
108
ptr->Data->Layer[i].Name = MyStrdup(Settings.DefaultLayerName[i],
110
ptr->Data->Layer[MAX_LAYER + COMPONENT_LAYER].Name = MyStrdup("silk", "CreateNewPCB()");
111
ptr->Data->Layer[MAX_LAYER + SOLDER_LAYER].Name = MyStrdup("silk", "CreateNewPCB()");
113
ptr->SilkActive = False;
114
SET_FLAG(NAMEONPCBFLAG, ptr);
115
if (Settings.AbsoluteGrid)
116
SET_FLAG(ABSOLUTEFLAG, ptr);
117
if (Settings.AllDirectionLines)
118
SET_FLAG(ALLDIRECTIONFLAG, ptr);
119
ptr->Clipping = 1; /* this is the most useful starting point for now */
120
if (Settings.RubberBandMode)
121
SET_FLAG(RUBBERBANDFLAG, ptr);
122
if (Settings.SwapStartDirection)
123
SET_FLAG(SWAPSTARTDIRFLAG, ptr);
124
ptr->Grid = Settings.Grid;
125
ptr->LayerGroups = Settings.LayerGroups;
126
for (i =0; i < NUM_STYLES; i++)
127
ptr->RouteStyle[i] = Settings.RouteStyle[i];
128
ptr->Zoom = Settings.Zoom;
129
ptr->MaxWidth = Settings.MaxWidth;
130
ptr->MaxHeight = Settings.MaxHeight;
95
/* allocate memory, switch all layers on and copy resources */
96
ptr = MyCalloc (1, sizeof (PCBType), "CreateNewPCB()");
97
ptr->Data = CreateNewBuffer ();
99
/* copy default settings */
100
ptr->ConnectedColor = Settings.ConnectedColor;
101
ptr->ElementColor = Settings.ElementColor;
102
ptr->RatColor = Settings.RatColor;
103
ptr->InvisibleObjectsColor = Settings.InvisibleObjectsColor;
104
ptr->InvisibleMarkColor = Settings.InvisibleMarkColor;
105
ptr->ElementSelectedColor = Settings.ElementSelectedColor;
106
ptr->RatSelectedColor = Settings.RatSelectedColor;
107
ptr->PinColor = Settings.PinColor;
108
ptr->PinSelectedColor = Settings.PinSelectedColor;
109
ptr->ViaColor = Settings.ViaColor;
110
ptr->ViaSelectedColor = Settings.ViaSelectedColor;
111
ptr->WarnColor = Settings.WarnColor;
112
ptr->MaskColor = Settings.MaskColor;
113
for (i = 0; i < MAX_LAYER; i++)
115
ptr->Data->Layer[i].Color = Settings.LayerColor[i];
116
ptr->Data->Layer[i].SelectedColor = Settings.LayerSelectedColor[i];
118
ptr->Data->Layer[MAX_LAYER + COMPONENT_LAYER].Color =
119
Settings.ShowSolderSide ? Settings.
120
InvisibleObjectsColor : Settings.ElementColor;
121
ptr->Data->Layer[MAX_LAYER + COMPONENT_LAYER].SelectedColor =
122
Settings.ElementSelectedColor;
123
ptr->Data->Layer[MAX_LAYER + SOLDER_LAYER].Color =
124
Settings.ShowSolderSide ? Settings.
125
ElementColor : Settings.InvisibleObjectsColor;
126
ptr->Data->Layer[MAX_LAYER + SOLDER_LAYER].SelectedColor =
127
Settings.ElementSelectedColor;
130
for (i = 0; i < MAX_LAYER; i++)
131
ptr->Data->Layer[i].Name = MyStrdup (Settings.DefaultLayerName[i],
133
ptr->Data->Layer[MAX_LAYER + COMPONENT_LAYER].Name =
134
MyStrdup ("silk", "CreateNewPCB()");
135
ptr->Data->Layer[MAX_LAYER + SOLDER_LAYER].Name =
136
MyStrdup ("silk", "CreateNewPCB()");
138
ptr->SilkActive = False;
139
ptr->RatDraw = False;
140
SET_FLAG (NAMEONPCBFLAG, ptr);
141
SET_FLAG (SHOWNUMBERFLAG, ptr);
142
if (Settings.AllDirectionLines)
143
SET_FLAG (ALLDIRECTIONFLAG, ptr);
144
ptr->Clipping = 1; /* this is the most useful starting point for now */
145
if (Settings.RubberBandMode)
146
SET_FLAG (RUBBERBANDFLAG, ptr);
147
if (Settings.SwapStartDirection)
148
SET_FLAG (SWAPSTARTDIRFLAG, ptr);
149
if (Settings.UniqueNames)
150
SET_FLAG (UNIQUENAMEFLAG, ptr);
151
if (Settings.SnapPin)
152
SET_FLAG (SNAPPINFLAG, ptr);
153
if (Settings.ClearLine)
154
SET_FLAG (CLEARNEWFLAG, ptr);
155
ptr->Grid = Settings.Grid;
156
ptr->LayerGroups = Settings.LayerGroups;
159
*style = Settings.RouteStyle[n];
162
ptr->Zoom = Settings.Zoom;
163
ptr->MaxWidth = Settings.MaxWidth;
164
ptr->MaxHeight = Settings.MaxHeight;
166
ptr->ThermScale = 0.5;
135
170
/* ---------------------------------------------------------------------------
136
171
* creates a new via
138
PinTypePtr CreateNewVia(DataTypePtr Data,
139
Position X, Position Y,
140
Dimension Thickness, Dimension Clearance,
141
Dimension DrillingHole,
142
char *Name, int Flags)
147
if ((float) (via->X - X) * (float) (via->X - X) +
148
(float) (via->Y - Y) * (float) (via->Y - Y) <=
149
((float) (via->Thickness/2 + Thickness/2)* (float) (via->Thickness/2 + Thickness/2)))
150
return(NULL); /* don't allow via stacking */
153
Via = GetViaMemory(Data);
160
Via->Thickness = Thickness;
161
Via->Clearance = Clearance;
162
Via->Mask = Thickness + Clearance;
163
Via->DrillingHole = DrillingHole;
164
Via->Name = MyStrdup(Name, "CreateNewVia()");
165
Via->Flags = Flags & ~WARNFLAG;
174
CreateNewVia (DataTypePtr Data,
175
LocationType X, LocationType Y,
176
BDimension Thickness, BDimension Clearance, BDimension Mask,
177
BDimension DrillingHole, char *Name, int Flags)
183
if (SQUARE (via->X - X) + SQUARE (via->Y - Y) <=
184
SQUARE (via->Thickness / 2 + Thickness / 2))
185
return (NULL); /* don't allow via stacking */
189
Via = GetViaMemory (Data);
196
Via->Thickness = Thickness;
197
Via->Clearance = Clearance;
199
Via->DrillingHole = vendorDrillMap(DrillingHole);
200
if (Via->DrillingHole != DrillingHole)
202
Message ("Mapped via drill hole to %.2f mils from %.2f mils per vendor table\n",
203
0.01*Via->DrillingHole, 0.01*DrillingHole);
206
Via->Name = MyStrdup (Name, "CreateNewVia()");
207
Via->Flags = Flags & ~WARNFLAG;
211
* don't complain about MIN_PINORVIACOPPER on a mounting hole (pure
214
if ( !TEST_FLAG (HOLEFLAG, Via) &&
215
(Via->Thickness < Via->DrillingHole + MIN_PINORVIACOPPER) )
217
Via->Thickness = Via->DrillingHole + MIN_PINORVIACOPPER;
218
Message ("Increased via thickness to %.2f mils to allow enough copper"
219
" at (%.2f,%.2f).\n",
220
0.01*Via->Thickness, 0.01*Via->X, 0.01*Via->Y);
223
SetPinBoundingBox (Via);
225
Data->via_tree = r_create_tree (NULL, 0, 0);
226
r_insert_entry (Data->via_tree, (BoxTypePtr) Via, 0);
232
LocationType X1, X2, Y1, Y2;
233
BDimension Thickness;
239
line_callback (const BoxType * b, void *cl)
241
LineTypePtr line = (LineTypePtr) b;
242
struct line_info *i = (struct line_info *) cl;
244
if (line->Point1.X == i->X1 &&
245
line->Point2.X == i->X2 &&
246
line->Point1.Y == i->Y1 && line->Point2.Y == i->Y2)
248
i->ans = (LineTypePtr) (-1);
251
/* check the other point order */
252
if (line->Point1.X == i->X1 &&
253
line->Point2.X == i->X2 &&
254
line->Point1.Y == i->Y1 && line->Point2.Y == i->Y2)
256
i->ans = (LineTypePtr) (-1);
259
if (line->Point2.X == i->X1 &&
260
line->Point1.X == i->X2 &&
261
line->Point2.Y == i->Y1 && line->Point1.Y == i->Y2)
263
i->ans = (LineTypePtr) - 1;
266
/* remove unncessary line points */
267
if (line->Thickness == i->Thickness)
269
if (line->Point1.X == i->X1 && line->Point1.Y == i->Y1)
271
i->test.Point1.X = line->Point2.X;
272
i->test.Point1.Y = line->Point2.Y;
273
i->test.Point2.X = i->X2;
274
i->test.Point2.Y = i->Y2;
275
if (IsPointOnLine ((float) i->X1, (float) i->Y1, 0.0, &i->test))
281
else if (line->Point2.X == i->X1 && line->Point2.Y == i->Y1)
283
i->test.Point1.X = line->Point1.X;
284
i->test.Point1.Y = line->Point1.Y;
285
i->test.Point2.X = i->X2;
286
i->test.Point2.Y = i->Y2;
287
if (IsPointOnLine ((float) i->X1, (float) i->Y1, 0.0, &i->test))
293
else if (line->Point1.X == i->X2 && line->Point1.Y == i->Y2)
295
i->test.Point1.X = line->Point2.X;
296
i->test.Point1.Y = line->Point2.Y;
297
i->test.Point2.X = i->X1;
298
i->test.Point2.Y = i->Y1;
299
if (IsPointOnLine ((float) i->X2, (float) i->Y2, 0.0, &i->test))
305
else if (line->Point2.X == i->X2 && line->Point2.Y == i->Y2)
307
i->test.Point1.X = line->Point1.X;
308
i->test.Point1.Y = line->Point1.Y;
309
i->test.Point2.X = i->X1;
310
i->test.Point2.Y = i->Y1;
311
if (IsPointOnLine ((float) i->X2, (float) i->Y2, 0.0, &i->test))
170
322
/* ---------------------------------------------------------------------------
171
* creates a new line on a layer
323
* creates a new line on a layer and checks for overlap and extension
173
LineTypePtr CreateNewLineOnLayer(LayerTypePtr Layer,
174
Position X1, Position Y1,
175
Position X2, Position Y2,
176
Dimension Thickness, Dimension Clearance,
179
LineTypePtr Line, project = NULL;
185
/* prevent stacking of duplicate lines
186
* and remove needless intermediate points
187
* verify that the layer is on the board first!
189
for (i = 0; i < MAX_LAYER; i++)
190
if (&PCB->Data->Layer[i] == Layer)
193
/* prevent stacked lines */
194
if ((line->Point1.X == X1 && line->Point1.Y == Y1
195
&& line->Point2.X == X2 && line->Point2.Y == Y2)
196
|| (line->Point1.X == X2 && line->Point1.Y == Y2
197
&& line->Point2.X == X1 && line->Point2.Y == Y1))
199
/* remove unncessary line points */
200
if (line->Thickness == Thickness)
202
if (line->Point1.X == X1 && line->Point1.Y == Y1)
204
test.Point1.X = line->Point2.X;
205
test.Point1.Y = line->Point2.Y;
208
if (IsPointOnLine((float) X1,
209
(float) Y1, 0.0, &test))
215
else if (line->Point2.X == X1 && line->Point2.Y == Y1)
217
test.Point1.X = line->Point1.X;
218
test.Point1.Y = line->Point1.Y;
221
if (IsPointOnLine((float) X1,
222
(float) Y1, 0.0, &test))
228
else if (line->Point1.X == X2 && line->Point1.Y == Y2)
230
test.Point1.X = line->Point2.X;
231
test.Point1.Y = line->Point2.Y;
234
if (IsPointOnLine((float) X2,
235
(float) Y2, 0.0, &test))
241
else if (line->Point2.X == X2 && line->Point2.Y == Y2)
243
test.Point1.X = line->Point1.X;
244
test.Point1.Y = line->Point1.Y;
247
if (IsPointOnLine((float) X2,
248
(float) Y2, 0.0, &test))
256
/* remove unneccessary points */
259
/* must do this BEFORE getting new line memory */
260
MoveObjectToRemoveUndoList(LINE_TYPE, Layer, project, project);
267
/* now actually create the new line */
268
Line = GetLineMemory(Layer);
273
Line->Thickness = Thickness;
274
Line->Clearance = Clearance;
277
Line->Point1.ID = ID++;
280
Line->Point2.ID = ID++;
326
CreateDrawnLineOnLayer (LayerTypePtr Layer,
327
LocationType X1, LocationType Y1,
328
LocationType X2, LocationType Y2,
329
BDimension Thickness, BDimension Clearance, int Flags)
331
struct line_info info;
334
search.X1 = MIN (X1, X2);
335
search.X2 = MAX (X1, X2);
336
search.Y1 = MIN (Y1, Y2);
337
search.Y2 = MAX (Y1, Y2);
342
info.Thickness = Thickness;
343
info.test.Thickness = 0;
344
info.test.Flags = NOFLAG;
346
/* prevent stacking of duplicate lines
347
* and remove needless intermediate points
348
* verify that the layer is on the board first!
350
if (setjmp (info.env) == 0)
352
r_search (Layer->line_tree, &search, NULL, line_callback, &info);
353
return CreateNewLineOnLayer (Layer, X1, Y1, X2, Y2,
354
Thickness, Clearance, Flags);
357
if ((void *) info.ans == (void *) (-1))
358
return NULL; /* stacked line */
359
/* remove unneccessary points */
362
/* must do this BEFORE getting new line memory */
363
MoveObjectToRemoveUndoList (LINE_TYPE, Layer, info.ans, info.ans);
364
X1 = info.test.Point1.X;
365
X2 = info.test.Point2.X;
366
Y1 = info.test.Point1.Y;
367
Y2 = info.test.Point2.Y;
369
return CreateNewLineOnLayer (Layer, X1, Y1, X2, Y2,
370
Thickness, Clearance, Flags);
374
CreateNewLineOnLayer (LayerTypePtr Layer,
375
LocationType X1, LocationType Y1,
376
LocationType X2, LocationType Y2,
377
BDimension Thickness, BDimension Clearance, int Flags)
381
Line = GetLineMemory (Layer);
386
Line->Thickness = Thickness;
387
Line->Clearance = Clearance;
390
Line->Point1.ID = ID++;
393
Line->Point2.ID = ID++;
394
SetLineBoundingBox (Line);
395
if (!Layer->line_tree)
396
Layer->line_tree = r_create_tree (NULL, 0, 0);
397
r_insert_entry (Layer->line_tree, (BoxTypePtr) Line, 0);
284
401
/* ---------------------------------------------------------------------------
285
402
* creates a new rat-line
287
RatTypePtr CreateNewRat(DataTypePtr Data, Position X1, Position Y1,
288
Position X2, Position Y2, Cardinal group1,
289
Cardinal group2, Dimension Thickness, int Flags)
405
CreateNewRat (DataTypePtr Data, LocationType X1, LocationType Y1,
406
LocationType X2, LocationType Y2, Cardinal group1,
407
Cardinal group2, BDimension Thickness, int Flags)
291
RatTypePtr Line = GetRatMemory(Data);
297
Line->Flags = Flags | RATFLAG;
298
Line->Thickness = Thickness;
301
Line->Point1.ID = ID++;
304
Line->Point2.ID = ID++;
305
Line->group1 = group1;
306
Line->group2 = group2;
409
RatTypePtr Line = GetRatMemory (Data);
415
Line->Flags = Flags | RATFLAG;
416
Line->Thickness = Thickness;
419
Line->Point1.ID = ID++;
422
Line->Point2.ID = ID++;
423
Line->group1 = group1;
424
Line->group2 = group2;
425
SetLineBoundingBox ((LineTypePtr) Line);
427
Data->rat_tree = r_create_tree (NULL, 0, 0);
428
r_insert_entry (Data->rat_tree, &Line->BoundingBox, 0);
310
432
/* ---------------------------------------------------------------------------
311
433
* creates a new arc on a layer
313
ArcTypePtr CreateNewArcOnLayer(LayerTypePtr Layer,
314
Position X1, Position Y1,
315
Dimension width, int sa,
316
int dir, Dimension Thickness,
317
Dimension Clearance, int Flags)
436
CreateNewArcOnLayer (LayerTypePtr Layer,
437
LocationType X1, LocationType Y1,
438
BDimension width, int sa,
439
int dir, BDimension Thickness,
440
BDimension Clearance, int Flags)
322
if (arc->X == X1 && arc->Y == Y1 && arc->Width == width &&
323
(arc->StartAngle + 360) % 360 == (sa + 360) % 360 &&
325
return(NULL); /* prevent stacked arcs */
327
Arc = GetArcMemory(Layer);
333
Arc->Thickness = Thickness;
334
Arc->Clearance = Clearance;
337
Arc->Width = Arc->Height = width;
338
Arc->StartAngle = sa;
340
SetArcBoundingBox(Arc);
446
if (arc->X == X1 && arc->Y == Y1 && arc->Width == width &&
447
(arc->StartAngle + 360) % 360 == (sa + 360) % 360 &&
449
return (NULL); /* prevent stacked arcs */
452
Arc = GetArcMemory (Layer);
458
Arc->Thickness = Thickness;
459
Arc->Clearance = Clearance;
462
Arc->Width = Arc->Height = width;
463
Arc->StartAngle = sa;
465
SetArcBoundingBox (Arc);
466
if (!Layer->arc_tree)
467
Layer->arc_tree = r_create_tree (NULL, 0, 0);
468
r_insert_entry (Layer->arc_tree, (BoxTypePtr) Arc, 0);
345
473
/* ---------------------------------------------------------------------------
346
474
* creates a new polygon from the old formats rectangle data
348
PolygonTypePtr CreateNewPolygonFromRectangle(LayerTypePtr Layer,
349
Position X1, Position Y1,
350
Position X2, Position Y2,
477
CreateNewPolygonFromRectangle (LayerTypePtr Layer,
478
LocationType X1, LocationType Y1,
479
LocationType X2, LocationType Y2, int Flags)
353
PolygonTypePtr polygon = CreateNewPolygon(Layer, Flags);
481
PolygonTypePtr polygon = CreateNewPolygon (Layer, Flags);
357
CreateNewPointInPolygon(polygon, X1, Y1);
358
CreateNewPointInPolygon(polygon, X2, Y1);
359
CreateNewPointInPolygon(polygon, X2, Y2);
360
CreateNewPointInPolygon(polygon, X1, Y2);
361
SetPolygonBoundingBox(polygon);
485
CreateNewPointInPolygon (polygon, X1, Y1);
486
CreateNewPointInPolygon (polygon, X2, Y1);
487
CreateNewPointInPolygon (polygon, X2, Y2);
488
CreateNewPointInPolygon (polygon, X1, Y2);
489
SetPolygonBoundingBox (polygon);
365
493
/* ---------------------------------------------------------------------------
366
494
* creates a new text on a layer
368
TextTypePtr CreateNewText(LayerTypePtr Layer, FontTypePtr PCBFont,
369
Position X, Position Y,
370
BYTE Direction, int Scale, char *TextString, int Flags)
497
CreateNewText (LayerTypePtr Layer, FontTypePtr PCBFont,
498
LocationType X, LocationType Y,
499
BYTE Direction, int Scale, char *TextString, int Flags)
372
TextTypePtr text = GetTextMemory(Layer);
376
/* copy values, width and height are set by drawing routine
377
* because at ths point we don't know which symbols are available
381
text->Direction = Direction;
384
text->TextString = MyStrdup(TextString, "CreateNewText()");
386
/* calculate size of the bounding box */
387
SetTextBoundingBox(PCBFont, text);
501
TextTypePtr text = GetTextMemory (Layer);
505
/* copy values, width and height are set by drawing routine
506
* because at ths point we don't know which symbols are available
510
text->Direction = Direction;
513
text->TextString = MyStrdup (TextString, "CreateNewText()");
515
/* calculate size of the bounding box */
516
SetTextBoundingBox (PCBFont, text);
518
if (!Layer->text_tree)
519
Layer->text_tree = r_create_tree (NULL, 0, 0);
520
r_insert_entry (Layer->text_tree, (BoxTypePtr) text, 0);
392
524
/* ---------------------------------------------------------------------------
393
525
* creates a new polygon on a layer
395
PolygonTypePtr CreateNewPolygon(LayerTypePtr Layer, int Flags)
528
CreateNewPolygon (LayerTypePtr Layer, int Flags)
397
PolygonTypePtr polygon = GetPolygonMemory(Layer);
530
PolygonTypePtr polygon = GetPolygonMemory (Layer);
400
polygon->Flags = Flags;
533
polygon->Flags = Flags;
405
538
/* ---------------------------------------------------------------------------
406
539
* creates a new point in a polygon
408
PointTypePtr CreateNewPointInPolygon(PolygonTypePtr Polygon,
409
Position X, Position Y)
542
CreateNewPointInPolygon (PolygonTypePtr Polygon, LocationType X, LocationType Y)
411
PointTypePtr point = GetPointMemoryInPolygon(Polygon);
544
PointTypePtr point = GetPointMemoryInPolygon (Polygon);
420
553
/* ---------------------------------------------------------------------------
421
554
* creates an new element
422
555
* memory is allocated if needed
424
ElementTypePtr CreateNewElement(DataTypePtr Data, ElementTypePtr Element,
427
char *Description, char *NameOnPCB, char *Value,
428
Position TextX, Position TextY, BYTE Direction,
429
int TextScale, int TextFlags, Boolean uniqueName)
558
CreateNewElement (DataTypePtr Data, ElementTypePtr Element,
561
char *Description, char *NameOnPCB, char *Value,
562
LocationType TextX, LocationType TextY, BYTE Direction,
563
int TextScale, int TextFlags, Boolean uniqueName)
432
Element = GetElementMemory(Data);
566
Element = GetElementMemory (Data);
434
/* copy values and set additional information */
435
AddTextToElement(&DESCRIPTION_TEXT(Element), PCBFont, TextX, TextY,
436
Direction, Description, TextScale, TextFlags);
438
NameOnPCB = UniqueElementName(Data, NameOnPCB);
439
AddTextToElement(&NAMEONPCB_TEXT(Element), PCBFont, TextX, TextY,
440
Direction, NameOnPCB, TextScale, TextFlags);
441
AddTextToElement(&VALUE_TEXT(Element), PCBFont, TextX, TextY,
442
Direction, Value, TextScale, TextFlags);
443
Element->Flags = Flags;
568
/* copy values and set additional information */
569
TextScale = MAX (MIN_TEXTSCALE, TextScale);
570
AddTextToElement (&DESCRIPTION_TEXT (Element), PCBFont, TextX, TextY,
571
Direction, Description, TextScale, TextFlags);
573
NameOnPCB = UniqueElementName (Data, NameOnPCB);
574
AddTextToElement (&NAMEONPCB_TEXT (Element), PCBFont, TextX, TextY,
575
Direction, NameOnPCB, TextScale, TextFlags);
576
AddTextToElement (&VALUE_TEXT (Element), PCBFont, TextX, TextY,
577
Direction, Value, TextScale, TextFlags);
578
DESCRIPTION_TEXT (Element).Element = Element;
579
NAMEONPCB_TEXT (Element).Element = Element;
580
VALUE_TEXT (Element).Element = Element;
581
Element->Flags = Flags;
448
586
/* ---------------------------------------------------------------------------
449
587
* creates a new arc in an element
451
ArcTypePtr CreateNewArcInElement(ElementTypePtr Element,
452
Position X, Position Y,
453
Dimension Width, Dimension Height,
454
int Angle, int Delta,
590
CreateNewArcInElement (ElementTypePtr Element,
591
LocationType X, LocationType Y,
592
BDimension Width, BDimension Height,
593
int Angle, int Delta, BDimension Thickness)
457
ArcTypePtr arc = Element->Arc;
459
/* realloc new memory if necessary and clear it */
460
if (Element->ArcN >= Element->ArcMax)
462
Element->ArcMax += STEP_ELEMENTARC;
463
arc = MyRealloc(arc, Element->ArcMax *sizeof(ArcType),
464
"CreateNewArcInElement()");
466
memset(arc +Element->ArcN, 0, STEP_ELEMENTARC*sizeof(ArcType));
469
/* set Delta (0,360], StartAngle in [0,360) */
470
if ((Delta = Delta % 360) == 0)
477
if ((Angle = Angle % 360) < 0)
481
arc = arc +Element->ArcN++;
485
arc->Height = Height;
486
arc->StartAngle = Angle;
488
arc->Thickness = Thickness;
595
ArcTypePtr arc = Element->Arc;
597
/* realloc new memory if necessary and clear it */
598
if (Element->ArcN >= Element->ArcMax)
600
Element->ArcMax += STEP_ELEMENTARC;
601
arc = MyRealloc (arc, Element->ArcMax * sizeof (ArcType),
602
"CreateNewArcInElement()");
604
memset (arc + Element->ArcN, 0, STEP_ELEMENTARC * sizeof (ArcType));
607
/* set Delta (0,360], StartAngle in [0,360) */
608
if ((Delta = Delta % 360) == 0)
615
if ((Angle = Angle % 360) < 0)
619
arc = arc + Element->ArcN++;
623
arc->Height = Height;
624
arc->StartAngle = Angle;
626
arc->Thickness = Thickness;
493
631
/* ---------------------------------------------------------------------------
494
632
* creates a new line for an element
496
LineTypePtr CreateNewLineInElement(ElementTypePtr Element,
497
Position X1, Position Y1,
498
Position X2, Position Y2,
635
CreateNewLineInElement (ElementTypePtr Element,
636
LocationType X1, LocationType Y1,
637
LocationType X2, LocationType Y2, BDimension Thickness)
501
LineTypePtr line = Element->Line;
639
LineTypePtr line = Element->Line;
503
/* realloc new memory if necessary and clear it */
504
if (Element->LineN >= Element->LineMax)
506
Element->LineMax += STEP_ELEMENTLINE;
507
line = MyRealloc(line, Element->LineMax *sizeof(LineType),
643
/* realloc new memory if necessary and clear it */
644
if (Element->LineN >= Element->LineMax)
646
Element->LineMax += STEP_ELEMENTLINE;
647
line = MyRealloc (line, Element->LineMax * sizeof (LineType),
508
648
"CreateNewLineInElement()");
509
Element->Line = line;
510
memset(line +Element->LineN, 0, STEP_ELEMENTLINE*sizeof(LineType));
649
Element->Line = line;
650
memset (line + Element->LineN, 0, STEP_ELEMENTLINE * sizeof (LineType));
514
line = line +Element->LineN++;
519
line->Thickness = Thickness;
654
line = line + Element->LineN++;
659
line->Thickness = Thickness;
660
line->Flags = NOFLAG;
524
665
/* ---------------------------------------------------------------------------
525
666
* creates a new pin in an element
527
PinTypePtr CreateNewPin(ElementTypePtr Element,
528
Position X, Position Y,
529
Dimension Thickness, Dimension Clearance, Dimension Mask,
530
Dimension DrillingHole, char *Name, char *Number, int Flags)
669
CreateNewPin (ElementTypePtr Element,
670
LocationType X, LocationType Y,
671
BDimension Thickness, BDimension Clearance, BDimension Mask,
672
BDimension DrillingHole, char *Name, char *Number, int Flags)
532
PinTypePtr pin = GetPinMemory(Element);
537
pin->Thickness = Thickness;
538
pin->Clearance = Clearance;
540
pin->DrillingHole = DrillingHole;
541
pin->Name = MyStrdup(Name, "CreateNewPin()");
542
pin->Number = MyStrdup(Number, "CreateNewPin()");
543
pin->Flags = Flags & ~WARNFLAG;
674
PinTypePtr pin = GetPinMemory (Element);
679
pin->Thickness = Thickness;
680
pin->Clearance = Clearance;
682
pin->Name = MyStrdup (Name, "CreateNewPin()");
683
pin->Number = MyStrdup (Number, "CreateNewPin()");
684
pin->Flags = Flags & ~WARNFLAG;
686
pin->Element = Element;
689
* If there is no vendor drill map installed, this will simply
690
* return DrillingHole.
692
pin->DrillingHole = vendorDrillMap(DrillingHole);
694
/* Unless we should not map drills on this element, map them! */
695
if ( vendorIsElementMappable(Element) )
697
if (pin->DrillingHole < MIN_PINORVIASIZE)
699
Message("Did not map pin #%s (%s) drill hole because %6.2f mil is below the minimum allowed size\n",
700
UNKNOWN (Number), UNKNOWN (Name), 0.01*pin->DrillingHole);
701
pin->DrillingHole = DrillingHole;
703
else if (pin->DrillingHole > MAX_PINORVIASIZE)
705
Message("Did not map pin #%s (%s) drill hole because %6.2f mil is above the maximum allowed size\n",
706
UNKNOWN (Number), UNKNOWN (Name), 0.01*pin->DrillingHole);
707
pin->DrillingHole = DrillingHole;
709
else if (!TEST_FLAG (HOLEFLAG, pin) && (pin->DrillingHole > pin->Thickness - MIN_PINORVIACOPPER) )
711
Message("Did not map pin #%s (%s) drill hole because %6.2f mil does not leave enough copper\n",
712
UNKNOWN (Number), UNKNOWN (Name), 0.01*pin->DrillingHole);
713
pin->DrillingHole = DrillingHole;
718
pin->DrillingHole = DrillingHole;
721
if (pin->DrillingHole != DrillingHole)
723
Message ("Mapped pin drill hole to %.2f mils from %.2f mils per vendor table\n",
724
0.01*pin->DrillingHole, 0.01*DrillingHole);
548
730
/* ---------------------------------------------------------------------------
549
731
* creates a new pad in an element
551
PadTypePtr CreateNewPad(ElementTypePtr Element,
552
Position X1, Position Y1, Position X2, Position Y2,
553
Dimension Thickness, Dimension Clearance, Dimension Mask,
554
char *Name, char *Number, int Flags)
734
CreateNewPad (ElementTypePtr Element,
735
LocationType X1, LocationType Y1, LocationType X2, LocationType Y2,
736
BDimension Thickness, BDimension Clearance, BDimension Mask,
737
char *Name, char *Number, int Flags)
556
PadTypePtr pad = GetPadMemory(Element);
739
PadTypePtr pad = GetPadMemory (Element);
563
pad->Thickness = Thickness;
564
pad->Clearance = Clearance;
566
pad->Name = MyStrdup(Name, "CreateNewPad()");
567
pad->Number = MyStrdup(Number, "CreateNewPad()");
568
pad->Flags = Flags & ~WARNFLAG;
742
if (X1 != X2 && Y1 != Y2)
744
Message ("Diagonal pads are forbidden!\n");
747
pad->Point1.X = MIN (X1, X2); /* works since either X1 == X2 or Y1 == Y2 */
748
pad->Point1.Y = MIN (Y1, Y2);
749
pad->Point2.X = MAX (X1, X2);
750
pad->Point2.Y = MAX (Y1, Y2);
751
pad->Thickness = Thickness;
752
pad->Clearance = Clearance;
754
pad->Name = MyStrdup (Name, "CreateNewPad()");
755
pad->Number = MyStrdup (Number, "CreateNewPad()");
756
pad->Flags = Flags & ~WARNFLAG;
758
pad->Element = Element;
573
762
/* ---------------------------------------------------------------------------
574
763
* creates a new textobject as part of an element
575
764
* copies the values to the appropriate text object
577
static void AddTextToElement(TextTypePtr Text, FontTypePtr PCBFont,
578
Position X, Position Y,
579
BYTE Direction, char *TextString, int Scale, int Flags)
767
AddTextToElement (TextTypePtr Text, FontTypePtr PCBFont,
768
LocationType X, LocationType Y,
769
BYTE Direction, char *TextString, int Scale, int Flags)
581
MyFree(&Text->TextString);
584
Text->Direction = Direction;
587
Text->TextString = (TextString && *TextString) ?
588
MyStrdup(TextString, "AddTextToElement()") : NULL;
771
MyFree (&Text->TextString);
774
Text->Direction = Direction;
777
Text->TextString = (TextString && *TextString) ?
778
MyStrdup (TextString, "AddTextToElement()") : NULL;
590
/* calculate size of the bounding box */
591
SetTextBoundingBox(PCBFont, Text);
780
/* calculate size of the bounding box */
781
SetTextBoundingBox (PCBFont, Text);
595
785
/* ---------------------------------------------------------------------------
596
786
* creates a new line in a symbol
598
LineTypePtr CreateNewLineInSymbol(SymbolTypePtr Symbol,
599
Position X1, Position Y1,
600
Position X2, Position Y2,
789
CreateNewLineInSymbol (SymbolTypePtr Symbol,
790
LocationType X1, LocationType Y1,
791
LocationType X2, LocationType Y2, BDimension Thickness)
603
LineTypePtr line = Symbol->Line;
793
LineTypePtr line = Symbol->Line;
605
/* realloc new memory if necessary and clear it */
606
if (Symbol->LineN >= Symbol->LineMax)
608
Symbol->LineMax += STEP_SYMBOLLINE;
609
line = MyRealloc(line, Symbol->LineMax *sizeof(LineType),
795
/* realloc new memory if necessary and clear it */
796
if (Symbol->LineN >= Symbol->LineMax)
798
Symbol->LineMax += STEP_SYMBOLLINE;
799
line = MyRealloc (line, Symbol->LineMax * sizeof (LineType),
610
800
"CreateNewLineInSymbol()");
612
memset(line +Symbol->LineN, 0, STEP_SYMBOLLINE*sizeof(LineType));
802
memset (line + Symbol->LineN, 0, STEP_SYMBOLLINE * sizeof (LineType));
616
line = line +Symbol->LineN++;
621
line->Thickness = Thickness;
806
line = line + Symbol->LineN++;
811
line->Thickness = Thickness;
625
815
/* ---------------------------------------------------------------------------