~ubuntu-branches/ubuntu/precise/pcb/precise

« back to all changes in this revision

Viewing changes to src/create.c

  • Committer: Bazaar Package Importer
  • Author(s): Hamish Moffatt
  • Date: 2005-02-20 13:14:00 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20050220131400-pfz66g5vhx0azl8f
Tags: 1.99j+20050127-2
* Improved package description: (closes: #295405)
* Fixed dependency: tk84 -> tk8.4 (closes: #295404)
* Updated README.debian (closes: #269578)
* Applied patch to src/djopt.c to allow compilation with gcc-4.0
  (closes: #294319), thanks to Andreas Jochens for the patch.
* Prevent example files from being compressed

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $Id: create.c,v 1.20 2005/01/21 22:46:56 danmc Exp $ */
 
2
 
1
3
/*
2
4
 *                            COPYRIGHT
3
5
 *
24
26
 *
25
27
 */
26
28
 
27
 
static  char    *rcsid = "$Id: create.c,v 1.6 1998/02/24 22:54:47 cad Exp $";
28
 
 
29
29
/* functions used to create vias, pins ...
30
30
 */
31
31
 
 
32
#ifdef HAVE_CONFIG_H
 
33
#include "config.h"
 
34
#endif
 
35
 
 
36
#include <assert.h>
 
37
#include <memory.h>
 
38
#include <setjmp.h>
32
39
#include <stdlib.h>
33
 
#include <memory.h>
34
40
 
35
41
#include "global.h"
36
42
 
42
48
#include "mymem.h"
43
49
#include "misc.h"
44
50
#include "parse_l.h"
 
51
#include "rtree.h"
45
52
#include "search.h"
46
53
#include "set.h"
47
54
#include "undo.h"
 
55
#include "vendor.h"
 
56
 
 
57
#ifdef HAVE_LIBDMALLOC
 
58
#include <dmalloc.h>
 
59
#endif
 
60
 
 
61
RCSID("$Id: create.c,v 1.20 2005/01/21 22:46:56 danmc Exp $");
48
62
 
49
63
/* ---------------------------------------------------------------------------
50
64
 * some local identifiers
51
65
 */
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 */
54
68
 
55
69
/* ----------------------------------------------------------------------
56
70
 * some local prototypes
57
71
 */
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);
60
74
 
61
75
/* ---------------------------------------------------------------------------
62
76
 * creates a new paste buffer
63
77
 */
64
 
DataTypePtr CreateNewBuffer(void)
 
78
DataTypePtr
 
79
CreateNewBuffer (void)
65
80
{
66
 
        return((DataTypePtr) MyCalloc(1, sizeof(DataType), "CreateNewBuffer()"));
 
81
  DataTypePtr data;
 
82
  data = (DataTypePtr) MyCalloc (1, sizeof (DataType), "CreateNewBuffer()");
 
83
  return data;
67
84
}
68
85
 
69
86
/* ---------------------------------------------------------------------------
70
87
 * creates a new PCB
71
88
 */
72
 
PCBTypePtr CreateNewPCB(Boolean SetDefaultNames)
 
89
PCBTypePtr
 
90
CreateNewPCB (Boolean SetDefaultNames)
73
91
{
74
 
        PCBTypePtr      ptr;
75
 
        int             i;
76
 
 
77
 
                /* allocate memory, switch all layers on and copy resources */
78
 
        ptr = MyCalloc(1, sizeof(PCBType), "CreateNewPCB()");
79
 
        ptr->Data = CreateNewBuffer();
80
 
 
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++)
95
 
        {
96
 
                ptr->Data->Layer[i].Color = Settings.LayerColor[i];
97
 
                ptr->Data->Layer[i].SelectedColor = Settings.LayerSelectedColor[i];
98
 
        }
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;
105
 
        
106
 
        if (SetDefaultNames)
107
 
                for (i = 0; i < MAX_LAYER; i++)
108
 
                        ptr->Data->Layer[i].Name = MyStrdup(Settings.DefaultLayerName[i],
109
 
                                "CreateNewPCB()");
110
 
        ptr->Data->Layer[MAX_LAYER + COMPONENT_LAYER].Name = MyStrdup("silk", "CreateNewPCB()");
111
 
        ptr->Data->Layer[MAX_LAYER + SOLDER_LAYER].Name = MyStrdup("silk", "CreateNewPCB()");
112
 
 
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;
131
 
        ptr->ID = ID++;
132
 
        return(ptr);
 
92
  PCBTypePtr ptr;
 
93
  int i;
 
94
 
 
95
  /* allocate memory, switch all layers on and copy resources */
 
96
  ptr = MyCalloc (1, sizeof (PCBType), "CreateNewPCB()");
 
97
  ptr->Data = CreateNewBuffer ();
 
98
 
 
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++)
 
114
    {
 
115
      ptr->Data->Layer[i].Color = Settings.LayerColor[i];
 
116
      ptr->Data->Layer[i].SelectedColor = Settings.LayerSelectedColor[i];
 
117
    }
 
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;
 
128
 
 
129
  if (SetDefaultNames)
 
130
    for (i = 0; i < MAX_LAYER; i++)
 
131
      ptr->Data->Layer[i].Name = MyStrdup (Settings.DefaultLayerName[i],
 
132
                                           "CreateNewPCB()");
 
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()");
 
137
 
 
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;
 
157
  STYLE_LOOP (ptr);
 
158
  {
 
159
    *style = Settings.RouteStyle[n];
 
160
  }
 
161
  END_LOOP;
 
162
  ptr->Zoom = Settings.Zoom;
 
163
  ptr->MaxWidth = Settings.MaxWidth;
 
164
  ptr->MaxHeight = Settings.MaxHeight;
 
165
  ptr->ID = ID++;
 
166
  ptr->ThermScale = 0.5;
 
167
  return (ptr);
133
168
}
134
169
 
135
170
/* ---------------------------------------------------------------------------
136
171
 * creates a new via
137
172
 */
138
 
PinTypePtr CreateNewVia(DataTypePtr Data,
139
 
        Position X, Position Y,
140
 
        Dimension Thickness, Dimension Clearance,
141
 
        Dimension DrillingHole,
142
 
        char *Name, int Flags)
143
 
{
144
 
        PinTypePtr      Via;
145
 
 
146
 
        VIA_LOOP(Data,
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 */
151
 
        );
152
 
 
153
 
        Via = GetViaMemory(Data);
154
 
 
155
 
        if (!Via)
156
 
                return(Via);
157
 
                /* copy values */
158
 
        Via->X = X;
159
 
        Via->Y = Y;
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;
166
 
        Via->ID = ID++;
167
 
        return(Via);
168
 
}
 
173
PinTypePtr
 
174
CreateNewVia (DataTypePtr Data,
 
175
              LocationType X, LocationType Y,
 
176
              BDimension Thickness, BDimension Clearance, BDimension Mask,
 
177
              BDimension DrillingHole, char *Name, int Flags)
 
178
{
 
179
  PinTypePtr Via;
 
180
 
 
181
  VIA_LOOP (Data);
 
182
  {
 
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 */
 
186
  }
 
187
  END_LOOP;
 
188
 
 
189
  Via = GetViaMemory (Data);
 
190
 
 
191
  if (!Via)
 
192
    return (Via);
 
193
  /* copy values */
 
194
  Via->X = X;
 
195
  Via->Y = Y;
 
196
  Via->Thickness = Thickness;
 
197
  Via->Clearance = Clearance;
 
198
  Via->Mask = Mask;
 
199
  Via->DrillingHole = vendorDrillMap(DrillingHole);
 
200
  if (Via->DrillingHole != DrillingHole)
 
201
    {
 
202
      Message ("Mapped via drill hole to %.2f mils from %.2f mils per vendor table\n",
 
203
               0.01*Via->DrillingHole, 0.01*DrillingHole);
 
204
    }
 
205
 
 
206
  Via->Name = MyStrdup (Name, "CreateNewVia()");
 
207
  Via->Flags = Flags & ~WARNFLAG;
 
208
  Via->ID = ID++;
 
209
 
 
210
  /* 
 
211
   * don't complain about MIN_PINORVIACOPPER on a mounting hole (pure
 
212
   * hole)
 
213
   */
 
214
  if ( !TEST_FLAG (HOLEFLAG, Via) && 
 
215
       (Via->Thickness < Via->DrillingHole + MIN_PINORVIACOPPER) )
 
216
    {
 
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);
 
221
    }
 
222
 
 
223
  SetPinBoundingBox (Via);
 
224
  if (!Data->via_tree)
 
225
    Data->via_tree = r_create_tree (NULL, 0, 0);
 
226
  r_insert_entry (Data->via_tree, (BoxTypePtr) Via, 0);
 
227
  return (Via);
 
228
}
 
229
 
 
230
struct line_info
 
231
{
 
232
  LocationType X1, X2, Y1, Y2;
 
233
  BDimension Thickness;
 
234
  LineType test, *ans;
 
235
  jmp_buf env;
 
236
};
 
237
 
 
238
static int
 
239
line_callback (const BoxType * b, void *cl)
 
240
{
 
241
  LineTypePtr line = (LineTypePtr) b;
 
242
  struct line_info *i = (struct line_info *) cl;
 
243
 
 
244
  if (line->Point1.X == i->X1 &&
 
245
      line->Point2.X == i->X2 &&
 
246
      line->Point1.Y == i->Y1 && line->Point2.Y == i->Y2)
 
247
    {
 
248
      i->ans = (LineTypePtr) (-1);
 
249
      longjmp (i->env, 1);
 
250
    }
 
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)
 
255
    {
 
256
      i->ans = (LineTypePtr) (-1);
 
257
      longjmp (i->env, 1);
 
258
    }
 
259
  if (line->Point2.X == i->X1 &&
 
260
      line->Point1.X == i->X2 &&
 
261
      line->Point2.Y == i->Y1 && line->Point1.Y == i->Y2)
 
262
    {
 
263
      i->ans = (LineTypePtr) - 1;
 
264
      longjmp (i->env, 1);
 
265
    }
 
266
  /* remove unncessary line points */
 
267
  if (line->Thickness == i->Thickness)
 
268
    {
 
269
      if (line->Point1.X == i->X1 && line->Point1.Y == i->Y1)
 
270
        {
 
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))
 
276
            {
 
277
              i->ans = line;
 
278
              longjmp (i->env, 1);
 
279
            }
 
280
        }
 
281
      else if (line->Point2.X == i->X1 && line->Point2.Y == i->Y1)
 
282
        {
 
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))
 
288
            {
 
289
              i->ans = line;
 
290
              longjmp (i->env, 1);
 
291
            }
 
292
        }
 
293
      else if (line->Point1.X == i->X2 && line->Point1.Y == i->Y2)
 
294
        {
 
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))
 
300
            {
 
301
              i->ans = line;
 
302
              longjmp (i->env, 1);
 
303
            }
 
304
        }
 
305
      else if (line->Point2.X == i->X2 && line->Point2.Y == i->Y2)
 
306
        {
 
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))
 
312
            {
 
313
              i->ans = line;
 
314
              longjmp (i->env, 1);
 
315
            }
 
316
        }
 
317
    }
 
318
  return 0;
 
319
}
 
320
 
169
321
 
170
322
/* ---------------------------------------------------------------------------
171
 
 * creates a new line on a layer
 
323
 * creates a new line on a layer and checks for overlap and extension
172
324
 */
173
 
LineTypePtr CreateNewLineOnLayer(LayerTypePtr Layer,
174
 
        Position X1, Position Y1,
175
 
        Position X2, Position Y2,
176
 
        Dimension Thickness, Dimension Clearance,
177
 
        int Flags)
178
 
{
179
 
        LineTypePtr     Line, project = NULL;
180
 
        LineType        test;
181
 
        Cardinal        i;
182
 
 
183
 
        test.Thickness = 0;
184
 
        test.Flags = NOFLAG;
185
 
                /* prevent stacking of duplicate lines
186
 
                 * and remove needless intermediate points
187
 
                 * verify that the layer is on the board first!
188
 
                 */
189
 
        for (i = 0; i < MAX_LAYER; i++)
190
 
                if (&PCB->Data->Layer[i] == Layer)
191
 
                {
192
 
                        LINE_LOOP(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))
198
 
                                        return(NULL);
199
 
                                /* remove unncessary line points */
200
 
                                if (line->Thickness == Thickness)
201
 
                                {
202
 
                                        if (line->Point1.X == X1 && line->Point1.Y == Y1)
203
 
                                        {
204
 
                                                test.Point1.X = line->Point2.X;
205
 
                                                test.Point1.Y = line->Point2.Y;
206
 
                                                test.Point2.X = X2;
207
 
                                                test.Point2.Y = Y2;
208
 
                                                if (IsPointOnLine((float) X1,
209
 
                                                    (float) Y1, 0.0, &test))
210
 
                                                {
211
 
                                                        project = line;
212
 
                                                        break;
213
 
                                                }
214
 
                                        }
215
 
                                        else if (line->Point2.X == X1 && line->Point2.Y == Y1)
216
 
                                        {
217
 
                                                test.Point1.X = line->Point1.X;
218
 
                                                test.Point1.Y = line->Point1.Y;
219
 
                                                test.Point2.X = X2;
220
 
                                                test.Point2.Y = Y2;
221
 
                                                if (IsPointOnLine((float) X1,
222
 
                                                   (float) Y1, 0.0, &test))
223
 
                                                {
224
 
                                                        project = line;
225
 
                                                        break;
226
 
                                                }
227
 
                                        }
228
 
                                        else if (line->Point1.X == X2 && line->Point1.Y == Y2)
229
 
                                        {
230
 
                                                test.Point1.X = line->Point2.X;
231
 
                                                test.Point1.Y = line->Point2.Y;
232
 
                                                test.Point2.X = X1;
233
 
                                                test.Point2.Y = Y1;
234
 
                                                if (IsPointOnLine((float) X2,
235
 
                                                   (float) Y2, 0.0, &test))
236
 
                                                {
237
 
                                                        project = line;
238
 
                                                        break;
239
 
                                                }
240
 
                                        }
241
 
                                        else if (line->Point2.X == X2 && line->Point2.Y == Y2)
242
 
                                        {
243
 
                                                test.Point1.X = line->Point1.X;
244
 
                                                test.Point1.Y = line->Point1.Y;
245
 
                                                test.Point2.X = X1;
246
 
                                                test.Point2.Y = Y1;
247
 
                                                if (IsPointOnLine((float) X2,
248
 
                                                    (float) Y2, 0.0, &test))
249
 
                                                {
250
 
                                                        project = line;
251
 
                                                        break;
252
 
                                                }
253
 
                                        }
254
 
                                }
255
 
                        );
256
 
                                /* remove unneccessary points */
257
 
                        if (project)
258
 
                        {
259
 
                                        /* must do this BEFORE getting new line memory */
260
 
                                MoveObjectToRemoveUndoList(LINE_TYPE, Layer, project, project);
261
 
                                X1 = test.Point1.X;
262
 
                                X2 = test.Point2.X;
263
 
                                Y1 = test.Point1.Y;
264
 
                                Y2 = test.Point2.Y;
265
 
                        }
266
 
                }
267
 
                /* now actually create the new line */
268
 
        Line = GetLineMemory(Layer);
269
 
        if (!Line)
270
 
                return(Line);
271
 
        Line->ID = ID++;
272
 
        Line->Flags = Flags;
273
 
        Line->Thickness = Thickness;
274
 
        Line->Clearance = Clearance;
275
 
        Line->Point1.X = X1;
276
 
        Line->Point1.Y = Y1;
277
 
        Line->Point1.ID = ID++;
278
 
        Line->Point2.X = X2;
279
 
        Line->Point2.Y = Y2;
280
 
        Line->Point2.ID = ID++;
281
 
        return(Line);
 
325
LineTypePtr
 
326
CreateDrawnLineOnLayer (LayerTypePtr Layer,
 
327
                        LocationType X1, LocationType Y1,
 
328
                        LocationType X2, LocationType Y2,
 
329
                        BDimension Thickness, BDimension Clearance, int Flags)
 
330
{
 
331
  struct line_info info;
 
332
  BoxType search;
 
333
 
 
334
  search.X1 = MIN (X1, X2);
 
335
  search.X2 = MAX (X1, X2);
 
336
  search.Y1 = MIN (Y1, Y2);
 
337
  search.Y2 = MAX (Y1, Y2);
 
338
  info.X1 = X1;
 
339
  info.X2 = X2;
 
340
  info.Y1 = Y1;
 
341
  info.Y2 = Y2;
 
342
  info.Thickness = Thickness;
 
343
  info.test.Thickness = 0;
 
344
  info.test.Flags = NOFLAG;
 
345
  info.ans = NULL;
 
346
  /* prevent stacking of duplicate lines
 
347
   * and remove needless intermediate points
 
348
   * verify that the layer is on the board first!
 
349
   */
 
350
  if (setjmp (info.env) == 0)
 
351
    {
 
352
      r_search (Layer->line_tree, &search, NULL, line_callback, &info);
 
353
      return CreateNewLineOnLayer (Layer, X1, Y1, X2, Y2,
 
354
                                   Thickness, Clearance, Flags);
 
355
    }
 
356
 
 
357
  if ((void *) info.ans == (void *) (-1))
 
358
    return NULL;                /* stacked line */
 
359
  /* remove unneccessary points */
 
360
  if (info.ans)
 
361
    {
 
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;
 
368
    }
 
369
  return CreateNewLineOnLayer (Layer, X1, Y1, X2, Y2,
 
370
                               Thickness, Clearance, Flags);
 
371
}
 
372
 
 
373
LineTypePtr
 
374
CreateNewLineOnLayer (LayerTypePtr Layer,
 
375
                      LocationType X1, LocationType Y1,
 
376
                      LocationType X2, LocationType Y2,
 
377
                      BDimension Thickness, BDimension Clearance, int Flags)
 
378
{
 
379
  LineTypePtr Line;
 
380
 
 
381
  Line = GetLineMemory (Layer);
 
382
  if (!Line)
 
383
    return (Line);
 
384
  Line->ID = ID++;
 
385
  Line->Flags = Flags;
 
386
  Line->Thickness = Thickness;
 
387
  Line->Clearance = Clearance;
 
388
  Line->Point1.X = X1;
 
389
  Line->Point1.Y = Y1;
 
390
  Line->Point1.ID = ID++;
 
391
  Line->Point2.X = X2;
 
392
  Line->Point2.Y = Y2;
 
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);
 
398
  return (Line);
282
399
}
283
400
 
284
401
/* ---------------------------------------------------------------------------
285
402
 * creates a new rat-line
286
403
 */
287
 
RatTypePtr CreateNewRat(DataTypePtr Data, Position X1, Position Y1,
288
 
        Position X2, Position Y2, Cardinal group1,
289
 
        Cardinal group2, Dimension Thickness, int Flags)
 
404
RatTypePtr
 
405
CreateNewRat (DataTypePtr Data, LocationType X1, LocationType Y1,
 
406
              LocationType X2, LocationType Y2, Cardinal group1,
 
407
              Cardinal group2, BDimension Thickness, int Flags)
290
408
{
291
 
        RatTypePtr      Line = GetRatMemory(Data);
292
 
 
293
 
        if (!Line)
294
 
                return(Line);
295
 
 
296
 
        Line->ID = ID++;
297
 
        Line->Flags = Flags | RATFLAG;
298
 
        Line->Thickness = Thickness;
299
 
        Line->Point1.X = X1;
300
 
        Line->Point1.Y = Y1;
301
 
        Line->Point1.ID = ID++;
302
 
        Line->Point2.X = X2;
303
 
        Line->Point2.Y = Y2;
304
 
        Line->Point2.ID = ID++;
305
 
        Line->group1 = group1;
306
 
        Line->group2 = group2;
307
 
        return(Line);
 
409
  RatTypePtr Line = GetRatMemory (Data);
 
410
 
 
411
  if (!Line)
 
412
    return (Line);
 
413
 
 
414
  Line->ID = ID++;
 
415
  Line->Flags = Flags | RATFLAG;
 
416
  Line->Thickness = Thickness;
 
417
  Line->Point1.X = X1;
 
418
  Line->Point1.Y = Y1;
 
419
  Line->Point1.ID = ID++;
 
420
  Line->Point2.X = X2;
 
421
  Line->Point2.Y = Y2;
 
422
  Line->Point2.ID = ID++;
 
423
  Line->group1 = group1;
 
424
  Line->group2 = group2;
 
425
  SetLineBoundingBox ((LineTypePtr) Line);
 
426
  if (!Data->rat_tree)
 
427
    Data->rat_tree = r_create_tree (NULL, 0, 0);
 
428
  r_insert_entry (Data->rat_tree, &Line->BoundingBox, 0);
 
429
  return (Line);
308
430
}
309
431
 
310
432
/* ---------------------------------------------------------------------------
311
433
 * creates a new arc on a layer
312
434
 */
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)
 
435
ArcTypePtr
 
436
CreateNewArcOnLayer (LayerTypePtr Layer,
 
437
                     LocationType X1, LocationType Y1,
 
438
                     BDimension width, int sa,
 
439
                     int dir, BDimension Thickness,
 
440
                     BDimension Clearance, int Flags)
318
441
{
319
 
        ArcTypePtr      Arc;
320
 
 
321
 
        ARC_LOOP(Layer,
322
 
                if (arc->X == X1 && arc->Y == Y1 && arc->Width == width &&
323
 
                        (arc->StartAngle + 360) % 360 == (sa + 360) % 360 &&
324
 
                        arc->Delta == dir)
325
 
                return(NULL); /* prevent stacked arcs */
326
 
        );
327
 
        Arc = GetArcMemory(Layer);
328
 
        if (!Arc)
329
 
                return(Arc);
330
 
 
331
 
        Arc->ID = ID++;
332
 
        Arc->Flags = Flags;
333
 
        Arc->Thickness = Thickness;
334
 
        Arc->Clearance = Clearance;
335
 
        Arc->X = X1;
336
 
        Arc->Y = Y1;
337
 
        Arc->Width = Arc->Height = width;
338
 
        Arc->StartAngle = sa;
339
 
        Arc->Delta = dir;
340
 
        SetArcBoundingBox(Arc);
341
 
        return(Arc);
 
442
  ArcTypePtr Arc;
 
443
 
 
444
  ARC_LOOP (Layer);
 
445
  {
 
446
    if (arc->X == X1 && arc->Y == Y1 && arc->Width == width &&
 
447
        (arc->StartAngle + 360) % 360 == (sa + 360) % 360 &&
 
448
        arc->Delta == dir)
 
449
      return (NULL);            /* prevent stacked arcs */
 
450
  }
 
451
  END_LOOP;
 
452
  Arc = GetArcMemory (Layer);
 
453
  if (!Arc)
 
454
    return (Arc);
 
455
 
 
456
  Arc->ID = ID++;
 
457
  Arc->Flags = Flags;
 
458
  Arc->Thickness = Thickness;
 
459
  Arc->Clearance = Clearance;
 
460
  Arc->X = X1;
 
461
  Arc->Y = Y1;
 
462
  Arc->Width = Arc->Height = width;
 
463
  Arc->StartAngle = sa;
 
464
  Arc->Delta = dir;
 
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);
 
469
  return (Arc);
342
470
}
343
471
 
344
472
 
345
473
/* ---------------------------------------------------------------------------
346
474
 * creates a new polygon from the old formats rectangle data
347
475
 */
348
 
PolygonTypePtr CreateNewPolygonFromRectangle(LayerTypePtr Layer,
349
 
        Position X1, Position Y1,
350
 
        Position X2, Position Y2,
351
 
        int Flags)
 
476
PolygonTypePtr
 
477
CreateNewPolygonFromRectangle (LayerTypePtr Layer,
 
478
                               LocationType X1, LocationType Y1,
 
479
                               LocationType X2, LocationType Y2, int Flags)
352
480
{
353
 
        PolygonTypePtr  polygon = CreateNewPolygon(Layer, Flags);
354
 
        if (!polygon)
355
 
                return(polygon);
 
481
  PolygonTypePtr polygon = CreateNewPolygon (Layer, Flags);
 
482
  if (!polygon)
 
483
    return (polygon);
356
484
 
357
 
        CreateNewPointInPolygon(polygon, X1, Y1);
358
 
        CreateNewPointInPolygon(polygon, X2, Y1);
359
 
        CreateNewPointInPolygon(polygon, X2, Y2);
360
 
        CreateNewPointInPolygon(polygon, X1, Y2);
361
 
        SetPolygonBoundingBox(polygon);
362
 
        return(polygon);
 
485
  CreateNewPointInPolygon (polygon, X1, Y1);
 
486
  CreateNewPointInPolygon (polygon, X2, Y1);
 
487
  CreateNewPointInPolygon (polygon, X2, Y2);
 
488
  CreateNewPointInPolygon (polygon, X1, Y2);
 
489
  SetPolygonBoundingBox (polygon);
 
490
  return (polygon);
363
491
}
364
492
 
365
493
/* ---------------------------------------------------------------------------
366
494
 * creates a new text on a layer
367
495
 */
368
 
TextTypePtr CreateNewText(LayerTypePtr Layer, FontTypePtr PCBFont,
369
 
        Position X, Position Y,
370
 
        BYTE Direction, int Scale, char *TextString, int Flags)
 
496
TextTypePtr
 
497
CreateNewText (LayerTypePtr Layer, FontTypePtr PCBFont,
 
498
               LocationType X, LocationType Y,
 
499
               BYTE Direction, int Scale, char *TextString, int Flags)
371
500
{
372
 
        TextTypePtr     text = GetTextMemory(Layer);
373
 
        if (!text)
374
 
                return(text);
375
 
 
376
 
                /* copy values, width and height are set by drawing routine
377
 
                 * because at ths point we don't know which symbols are available
378
 
                 */
379
 
        text->X = X;
380
 
        text->Y = Y;
381
 
        text->Direction = Direction;
382
 
        text->Flags = Flags;
383
 
        text->Scale = Scale;
384
 
        text->TextString = MyStrdup(TextString, "CreateNewText()");
385
 
 
386
 
                /* calculate size of the bounding box */
387
 
        SetTextBoundingBox(PCBFont, text);
388
 
        text->ID = ID++;
389
 
        return(text);
 
501
  TextTypePtr text = GetTextMemory (Layer);
 
502
  if (!text)
 
503
    return (text);
 
504
 
 
505
  /* copy values, width and height are set by drawing routine
 
506
   * because at ths point we don't know which symbols are available
 
507
   */
 
508
  text->X = X;
 
509
  text->Y = Y;
 
510
  text->Direction = Direction;
 
511
  text->Flags = Flags;
 
512
  text->Scale = Scale;
 
513
  text->TextString = MyStrdup (TextString, "CreateNewText()");
 
514
 
 
515
  /* calculate size of the bounding box */
 
516
  SetTextBoundingBox (PCBFont, text);
 
517
  text->ID = ID++;
 
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);
 
521
  return (text);
390
522
}
391
523
 
392
524
/* ---------------------------------------------------------------------------
393
525
 * creates a new polygon on a layer
394
526
 */
395
 
PolygonTypePtr CreateNewPolygon(LayerTypePtr Layer, int Flags)
 
527
PolygonTypePtr
 
528
CreateNewPolygon (LayerTypePtr Layer, int Flags)
396
529
{
397
 
        PolygonTypePtr  polygon = GetPolygonMemory(Layer);
 
530
  PolygonTypePtr polygon = GetPolygonMemory (Layer);
398
531
 
399
 
                /* copy values */
400
 
        polygon->Flags = Flags;
401
 
        polygon->ID = ID++;
402
 
        return(polygon);
 
532
  /* copy values */
 
533
  polygon->Flags = Flags;
 
534
  polygon->ID = ID++;
 
535
  return (polygon);
403
536
}
404
537
 
405
538
/* ---------------------------------------------------------------------------
406
539
 * creates a new point in a polygon
407
540
 */
408
 
PointTypePtr CreateNewPointInPolygon(PolygonTypePtr Polygon,
409
 
        Position X, Position Y)
 
541
PointTypePtr
 
542
CreateNewPointInPolygon (PolygonTypePtr Polygon, LocationType X, LocationType Y)
410
543
{
411
 
        PointTypePtr    point = GetPointMemoryInPolygon(Polygon);
 
544
  PointTypePtr point = GetPointMemoryInPolygon (Polygon);
412
545
 
413
 
                /* copy values */
414
 
        point->X = X;
415
 
        point->Y = Y;
416
 
        point->ID = ID++;
417
 
        return(point);
 
546
  /* copy values */
 
547
  point->X = X;
 
548
  point->Y = Y;
 
549
  point->ID = ID++;
 
550
  return (point);
418
551
}
419
552
 
420
553
/* ---------------------------------------------------------------------------
421
554
 * creates an new element
422
555
 * memory is allocated if needed
423
556
 */
424
 
ElementTypePtr CreateNewElement(DataTypePtr Data, ElementTypePtr Element,
425
 
        FontTypePtr PCBFont,
426
 
        int Flags,
427
 
        char *Description, char *NameOnPCB, char *Value,
428
 
        Position TextX, Position TextY, BYTE Direction,
429
 
        int TextScale, int TextFlags, Boolean uniqueName)
 
557
ElementTypePtr
 
558
CreateNewElement (DataTypePtr Data, ElementTypePtr Element,
 
559
                  FontTypePtr PCBFont,
 
560
                  int Flags,
 
561
                  char *Description, char *NameOnPCB, char *Value,
 
562
                  LocationType TextX, LocationType TextY, BYTE Direction,
 
563
                  int TextScale, int TextFlags, Boolean uniqueName)
430
564
{
431
 
        if (!Element)
432
 
                Element = GetElementMemory(Data);
 
565
  if (!Element)
 
566
    Element = GetElementMemory (Data);
433
567
 
434
 
                /* copy values and set additional information */
435
 
        AddTextToElement(&DESCRIPTION_TEXT(Element), PCBFont, TextX, TextY,
436
 
                Direction, Description, TextScale, TextFlags);
437
 
        if (uniqueName)
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;
444
 
        Element->ID = ID++;
445
 
        return(Element);
 
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);
 
572
  if (uniqueName)
 
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;
 
582
  Element->ID = ID++;
 
583
  return (Element);
446
584
}
447
585
 
448
586
/* ---------------------------------------------------------------------------
449
587
 * creates a new arc in an element
450
588
 */
451
 
ArcTypePtr CreateNewArcInElement(ElementTypePtr Element,
452
 
        Position X, Position Y,
453
 
        Dimension Width, Dimension Height,
454
 
        int Angle, int Delta,
455
 
        Dimension Thickness)
 
589
ArcTypePtr
 
590
CreateNewArcInElement (ElementTypePtr Element,
 
591
                       LocationType X, LocationType Y,
 
592
                       BDimension Width, BDimension Height,
 
593
                       int Angle, int Delta, BDimension Thickness)
456
594
{
457
 
        ArcTypePtr      arc = Element->Arc;
458
 
 
459
 
                /* realloc new memory if necessary and clear it */
460
 
        if (Element->ArcN >= Element->ArcMax)
461
 
        {
462
 
                Element->ArcMax += STEP_ELEMENTARC;     
463
 
                arc = MyRealloc(arc, Element->ArcMax *sizeof(ArcType),
464
 
                        "CreateNewArcInElement()");
465
 
                Element->Arc = arc;
466
 
                memset(arc +Element->ArcN, 0, STEP_ELEMENTARC*sizeof(ArcType));
467
 
        }
468
 
 
469
 
                /* set Delta (0,360], StartAngle in [0,360) */
470
 
        if ((Delta = Delta % 360) == 0)
471
 
                Delta = 360;
472
 
        if (Delta < 0)
473
 
        {
474
 
                Angle += Delta;
475
 
                Delta = -Delta;
476
 
        }
477
 
        if ((Angle = Angle % 360) < 0)
478
 
                Angle += 360;
479
 
 
480
 
                /* copy values */
481
 
        arc = arc +Element->ArcN++;
482
 
        arc->X = X;
483
 
        arc->Y = Y;
484
 
        arc->Width = Width;
485
 
        arc->Height = Height;
486
 
        arc->StartAngle = Angle;
487
 
        arc->Delta = Delta;
488
 
        arc->Thickness = Thickness;
489
 
        arc->ID = ID++;
490
 
        return(arc);
 
595
  ArcTypePtr arc = Element->Arc;
 
596
 
 
597
  /* realloc new memory if necessary and clear it */
 
598
  if (Element->ArcN >= Element->ArcMax)
 
599
    {
 
600
      Element->ArcMax += STEP_ELEMENTARC;
 
601
      arc = MyRealloc (arc, Element->ArcMax * sizeof (ArcType),
 
602
                       "CreateNewArcInElement()");
 
603
      Element->Arc = arc;
 
604
      memset (arc + Element->ArcN, 0, STEP_ELEMENTARC * sizeof (ArcType));
 
605
    }
 
606
 
 
607
  /* set Delta (0,360], StartAngle in [0,360) */
 
608
  if ((Delta = Delta % 360) == 0)
 
609
    Delta = 360;
 
610
  if (Delta < 0)
 
611
    {
 
612
      Angle += Delta;
 
613
      Delta = -Delta;
 
614
    }
 
615
  if ((Angle = Angle % 360) < 0)
 
616
    Angle += 360;
 
617
 
 
618
  /* copy values */
 
619
  arc = arc + Element->ArcN++;
 
620
  arc->X = X;
 
621
  arc->Y = Y;
 
622
  arc->Width = Width;
 
623
  arc->Height = Height;
 
624
  arc->StartAngle = Angle;
 
625
  arc->Delta = Delta;
 
626
  arc->Thickness = Thickness;
 
627
  arc->ID = ID++;
 
628
  return (arc);
491
629
}
492
630
 
493
631
/* ---------------------------------------------------------------------------
494
632
 * creates a new line for an element
495
633
 */
496
 
LineTypePtr CreateNewLineInElement(ElementTypePtr Element,
497
 
        Position X1, Position Y1,
498
 
        Position X2, Position Y2,
499
 
        Dimension Thickness)
 
634
LineTypePtr
 
635
CreateNewLineInElement (ElementTypePtr Element,
 
636
                        LocationType X1, LocationType Y1,
 
637
                        LocationType X2, LocationType Y2, BDimension Thickness)
500
638
{
501
 
        LineTypePtr     line = Element->Line;
 
639
  LineTypePtr line = Element->Line;
502
640
 
503
 
                /* realloc new memory if necessary and clear it */
504
 
        if (Element->LineN >= Element->LineMax)
505
 
        {
506
 
                Element->LineMax += STEP_ELEMENTLINE;   
507
 
                line = MyRealloc(line, Element->LineMax *sizeof(LineType),
 
641
  if (Thickness == 0)
 
642
    return (NULL);
 
643
  /* realloc new memory if necessary and clear it */
 
644
  if (Element->LineN >= Element->LineMax)
 
645
    {
 
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));
511
 
        }
 
649
      Element->Line = line;
 
650
      memset (line + Element->LineN, 0, STEP_ELEMENTLINE * sizeof (LineType));
 
651
    }
512
652
 
513
 
                /* copy values */
514
 
        line = line +Element->LineN++;
515
 
        line->Point1.X = X1;
516
 
        line->Point1.Y = Y1;
517
 
        line->Point2.X = X2;
518
 
        line->Point2.Y = Y2;
519
 
        line->Thickness = Thickness;
520
 
        line->ID = ID++;
521
 
        return(line);
 
653
  /* copy values */
 
654
  line = line + Element->LineN++;
 
655
  line->Point1.X = X1;
 
656
  line->Point1.Y = Y1;
 
657
  line->Point2.X = X2;
 
658
  line->Point2.Y = Y2;
 
659
  line->Thickness = Thickness;
 
660
  line->Flags = NOFLAG;
 
661
  line->ID = ID++;
 
662
  return (line);
522
663
}
523
664
 
524
665
/* ---------------------------------------------------------------------------
525
666
 * creates a new pin in an element
526
667
 */
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)
 
668
PinTypePtr
 
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)
531
673
{
532
 
        PinTypePtr pin = GetPinMemory(Element);
533
 
 
534
 
                /* copy values */
535
 
        pin->X = X;
536
 
        pin->Y = Y;
537
 
        pin->Thickness = Thickness;
538
 
        pin->Clearance = Clearance;
539
 
        pin->Mask = Mask;
540
 
        pin->DrillingHole = DrillingHole;
541
 
        pin->Name = MyStrdup(Name, "CreateNewPin()");
542
 
        pin->Number = MyStrdup(Number, "CreateNewPin()");
543
 
        pin->Flags = Flags & ~WARNFLAG;
544
 
        pin->ID = ID++;
545
 
        return(pin);
 
674
  PinTypePtr pin = GetPinMemory (Element);
 
675
 
 
676
  /* copy values */
 
677
  pin->X = X;
 
678
  pin->Y = Y;
 
679
  pin->Thickness = Thickness;
 
680
  pin->Clearance = Clearance;
 
681
  pin->Mask = Mask;
 
682
  pin->Name = MyStrdup (Name, "CreateNewPin()");
 
683
  pin->Number = MyStrdup (Number, "CreateNewPin()");
 
684
  pin->Flags = Flags & ~WARNFLAG;
 
685
  pin->ID = ID++;
 
686
  pin->Element = Element;
 
687
 
 
688
  /* 
 
689
   * If there is no vendor drill map installed, this will simply
 
690
   * return DrillingHole.
 
691
   */
 
692
  pin->DrillingHole = vendorDrillMap(DrillingHole);
 
693
 
 
694
  /* Unless we should not map drills on this element, map them! */
 
695
  if ( vendorIsElementMappable(Element) ) 
 
696
    {
 
697
      if (pin->DrillingHole < MIN_PINORVIASIZE)
 
698
        {
 
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;
 
702
        }
 
703
      else if (pin->DrillingHole > MAX_PINORVIASIZE)
 
704
        {
 
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;
 
708
        }
 
709
      else if (!TEST_FLAG (HOLEFLAG, pin) && (pin->DrillingHole > pin->Thickness - MIN_PINORVIACOPPER) )
 
710
        {
 
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;
 
714
        }
 
715
    }
 
716
  else
 
717
    {
 
718
      pin->DrillingHole = DrillingHole;
 
719
    }
 
720
 
 
721
  if (pin->DrillingHole != DrillingHole)
 
722
    {
 
723
      Message ("Mapped pin drill hole to %.2f mils from %.2f mils per vendor table\n",
 
724
               0.01*pin->DrillingHole, 0.01*DrillingHole);
 
725
    }
 
726
 
 
727
  return (pin);
546
728
}
547
729
 
548
730
/* ---------------------------------------------------------------------------
549
731
 * creates a new pad in an element
550
732
 */
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)
 
733
PadTypePtr
 
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)
555
738
{
556
 
        PadTypePtr pad = GetPadMemory(Element);
 
739
  PadTypePtr pad = GetPadMemory (Element);
557
740
 
558
 
                /* copy values */
559
 
        pad->Point1.X = X1;
560
 
        pad->Point1.Y = Y1;
561
 
        pad->Point2.X = X2;
562
 
        pad->Point2.Y = Y2;
563
 
        pad->Thickness = Thickness;
564
 
        pad->Clearance = Clearance;
565
 
        pad->Mask = Mask;
566
 
        pad->Name = MyStrdup(Name, "CreateNewPad()");
567
 
        pad->Number = MyStrdup(Number, "CreateNewPad()");
568
 
        pad->Flags = Flags & ~WARNFLAG;
569
 
        pad->ID = ID++;
570
 
        return(pad);
 
741
  /* copy values */
 
742
  if (X1 != X2 && Y1 != Y2)
 
743
   {
 
744
     Message ("Diagonal pads are forbidden!\n");
 
745
     return NULL;
 
746
   }
 
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;
 
753
  pad->Mask = Mask;
 
754
  pad->Name = MyStrdup (Name, "CreateNewPad()");
 
755
  pad->Number = MyStrdup (Number, "CreateNewPad()");
 
756
  pad->Flags = Flags & ~WARNFLAG;
 
757
  pad->ID = ID++;
 
758
  pad->Element = Element;
 
759
  return (pad);
571
760
}
572
761
 
573
762
/* ---------------------------------------------------------------------------
574
763
 * creates a new textobject as part of an element
575
764
 * copies the values to the appropriate text object
576
765
 */
577
 
static void AddTextToElement(TextTypePtr Text, FontTypePtr PCBFont,
578
 
        Position X, Position Y,
579
 
        BYTE Direction, char *TextString, int Scale, int Flags)
 
766
static void
 
767
AddTextToElement (TextTypePtr Text, FontTypePtr PCBFont,
 
768
                  LocationType X, LocationType Y,
 
769
                  BYTE Direction, char *TextString, int Scale, int Flags)
580
770
{
581
 
        MyFree(&Text->TextString);
582
 
        Text->X = X;
583
 
        Text->Y = Y;
584
 
        Text->Direction = Direction;
585
 
        Text->Flags = Flags;
586
 
        Text->Scale = Scale;
587
 
        Text->TextString = (TextString && *TextString) ?
588
 
                MyStrdup(TextString, "AddTextToElement()") : NULL;
 
771
  MyFree (&Text->TextString);
 
772
  Text->X = X;
 
773
  Text->Y = Y;
 
774
  Text->Direction = Direction;
 
775
  Text->Flags = Flags;
 
776
  Text->Scale = Scale;
 
777
  Text->TextString = (TextString && *TextString) ?
 
778
    MyStrdup (TextString, "AddTextToElement()") : NULL;
589
779
 
590
 
                /* calculate size of the bounding box */
591
 
        SetTextBoundingBox(PCBFont, Text);
592
 
        Text->ID = ID++;
 
780
  /* calculate size of the bounding box */
 
781
  SetTextBoundingBox (PCBFont, Text);
 
782
  Text->ID = ID++;
593
783
}
594
784
 
595
785
/* ---------------------------------------------------------------------------
596
786
 * creates a new line in a symbol
597
787
 */
598
 
LineTypePtr CreateNewLineInSymbol(SymbolTypePtr Symbol,
599
 
        Position X1, Position Y1,
600
 
        Position X2, Position Y2,
601
 
        Dimension Thickness)
 
788
LineTypePtr
 
789
CreateNewLineInSymbol (SymbolTypePtr Symbol,
 
790
                       LocationType X1, LocationType Y1,
 
791
                       LocationType X2, LocationType Y2, BDimension Thickness)
602
792
{
603
 
        LineTypePtr     line = Symbol->Line;
 
793
  LineTypePtr line = Symbol->Line;
604
794
 
605
 
                /* realloc new memory if necessary and clear it */
606
 
        if (Symbol->LineN >= Symbol->LineMax)
607
 
        {
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)
 
797
    {
 
798
      Symbol->LineMax += STEP_SYMBOLLINE;
 
799
      line = MyRealloc (line, Symbol->LineMax * sizeof (LineType),
610
800
                        "CreateNewLineInSymbol()");
611
 
                Symbol->Line = line;
612
 
                memset(line +Symbol->LineN, 0, STEP_SYMBOLLINE*sizeof(LineType));
613
 
        }
 
801
      Symbol->Line = line;
 
802
      memset (line + Symbol->LineN, 0, STEP_SYMBOLLINE * sizeof (LineType));
 
803
    }
614
804
 
615
 
                /* copy values */
616
 
        line = line +Symbol->LineN++;
617
 
        line->Point1.X = X1;
618
 
        line->Point1.Y = Y1;
619
 
        line->Point2.X = X2;
620
 
        line->Point2.Y = Y2;
621
 
        line->Thickness = Thickness;
622
 
        return(line);
 
805
  /* copy values */
 
806
  line = line + Symbol->LineN++;
 
807
  line->Point1.X = X1;
 
808
  line->Point1.Y = Y1;
 
809
  line->Point2.X = X2;
 
810
  line->Point2.Y = Y2;
 
811
  line->Thickness = Thickness;
 
812
  return (line);
623
813
}
624
814
 
625
815
/* ---------------------------------------------------------------------------
627
817
 * checks directories given as colon seperated list by resource fontPath
628
818
 * if the fonts filename doesn't contain a directory component
629
819
 */
630
 
void CreateDefaultFont(void)
 
820
void
 
821
CreateDefaultFont (void)
631
822
{
632
 
        if (ParseFont(&PCB->Font, Settings.FontFile))
633
 
                Message("can't find font-symbol-file '%s'\n", Settings.FontFile);
 
823
  if (ParseFont (&PCB->Font, Settings.FontFile))
 
824
    Message ("can't find font-symbol-file '%s'\n", Settings.FontFile);
634
825
}
635
826
 
636
827
/* ---------------------------------------------------------------------------
637
828
 * adds a new line to the rubberband list of 'Crosshair.AttachedObject'
638
829
 * if Layer == 0  it is a rat line
639
830
 */
640
 
RubberbandTypePtr CreateNewRubberbandEntry(LayerTypePtr Layer,
641
 
        LineTypePtr Line, PointTypePtr MovedPoint)
 
831
RubberbandTypePtr
 
832
CreateNewRubberbandEntry (LayerTypePtr Layer,
 
833
                          LineTypePtr Line, PointTypePtr MovedPoint)
642
834
{
643
 
        RubberbandTypePtr       ptr = GetRubberbandMemory();
 
835
  RubberbandTypePtr ptr = GetRubberbandMemory ();
644
836
 
645
 
                /* we toggle the RUBBERENDFLAG of the line to determine if */
646
 
                /* both points are being moved. */
647
 
        Line->Flags ^= RUBBERENDFLAG;
648
 
        ptr->Layer = Layer;
649
 
        ptr->Line = Line;
650
 
        ptr->MovedPoint = MovedPoint;
651
 
        return(ptr);
 
837
  /* we toggle the RUBBERENDFLAG of the line to determine if */
 
838
  /* both points are being moved. */
 
839
  Line->Flags ^= RUBBERENDFLAG;
 
840
  ptr->Layer = Layer;
 
841
  ptr->Line = Line;
 
842
  ptr->MovedPoint = MovedPoint;
 
843
  return (ptr);
652
844
}
653
845
 
654
846
/* ---------------------------------------------------------------------------
655
847
 * Add a new net to the netlist menu
656
848
 */
657
 
LibraryMenuTypePtr CreateNewNet(LibraryTypePtr lib, char *name, char *style)
 
849
LibraryMenuTypePtr
 
850
CreateNewNet (LibraryTypePtr lib, char *name, char *style)
658
851
{
659
 
        LibraryMenuTypePtr menu;
660
 
        char temp[64];
 
852
  LibraryMenuTypePtr menu;
 
853
  char temp[64];
661
854
 
662
 
        sprintf(temp, "  %s", name);
663
 
        menu = GetLibraryMenuMemory(lib);
664
 
        menu->Name = MyStrdup(temp, "CreateNewNet()");
665
 
        if (strcmp("(unknown)", style) == 0)
666
 
                menu->Style = NULL;
667
 
        else
668
 
                menu->Style = MyStrdup(style, "CreateNewNet()");
669
 
        return(menu);
 
855
  sprintf (temp, "  %s", name);
 
856
  menu = GetLibraryMenuMemory (lib);
 
857
  menu->Name = MyStrdup (temp, "CreateNewNet()");
 
858
  if (NSTRCMP ("(unknown)", style) == 0)
 
859
    menu->Style = NULL;
 
860
  else
 
861
    menu->Style = MyStrdup (style, "CreateNewNet()");
 
862
  return (menu);
670
863
}
671
864
 
672
865
/* ---------------------------------------------------------------------------
673
866
 * Add a connection to the net
674
867
 */
675
 
LibraryEntryTypePtr CreateNewConnection(LibraryMenuTypePtr net, char *conn)
 
868
LibraryEntryTypePtr
 
869
CreateNewConnection (LibraryMenuTypePtr net, char *conn)
676
870
{
677
 
        LibraryEntryTypePtr entry = GetLibraryEntryMemory(net);
 
871
  LibraryEntryTypePtr entry = GetLibraryEntryMemory (net);
678
872
 
679
 
        entry->ListEntry = MyStrdup(conn, "CreateNewConnection()");
680
 
        return(entry);
 
873
  entry->ListEntry = MyStrdup (conn, "CreateNewConnection()");
 
874
  return (entry);
681
875
}