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

« back to all changes in this revision

Viewing changes to src/dev_ps.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: dev_ps.c,v 1.14 2005/01/03 12:56:59 danmc Exp $ */
 
2
 
1
3
/*
2
4
 *                            COPYRIGHT
3
5
 *
30
32
 * silkscreen layer. Perhaps the design is not the best.
31
33
 */
32
34
 
33
 
static  char    *rcsid = "$Id: dev_ps.c,v 1.1 1998/02/19 18:06:34 sync Exp $";
34
 
 
35
35
/* PostScript device driver
36
36
 * code is shared for EPS and PS output
37
37
 */
 
38
#ifdef HAVE_CONFIG_H
 
39
#include "config.h"
 
40
#endif
 
41
 
38
42
#include <math.h>
39
43
#include <time.h>
40
44
#include <pwd.h>
41
45
#include <sys/types.h>
 
46
#ifdef HAVE_UNISTD_H
42
47
#include <unistd.h>
 
48
#endif
43
49
 
44
50
#include "global.h"
45
51
 
49
55
#include "misc.h"
50
56
#include "rotate.h"
51
57
 
 
58
#ifdef HAVE_LIBDMALLOC
 
59
#include <dmalloc.h>
 
60
#endif
 
61
 
 
62
RCSID("$Id: dev_ps.c,v 1.14 2005/01/03 12:56:59 danmc Exp $");
 
63
 
52
64
/* ---------------------------------------------------------------------------
53
65
 * some defines
54
66
 */
55
 
#define PS_UNIT         0.072           /* 1 mil in PostScript units */
 
67
#define PS_UNIT         0.00072 /* 0.01 mil in PostScript units */
 
68
#define POST_SCALE(x) ((int)((x) * PS_UNIT))
56
69
 
57
70
/* ---------------------------------------------------------------------------
58
71
 * some local prototypes
59
72
 */
60
 
static  void    PrintStringArray(char **, int, FILE *);
61
 
static  char    *PS_Preamble(PrintInitTypePtr, char *);
62
 
static  char    *EPS_Preamble(PrintInitTypePtr, char *);
63
 
static  char    *PS_EPS_Init(PrintInitTypePtr, char *,Boolean);
64
 
static  void    PS_Exit(void);
65
 
static  void    EPS_Exit(void);
66
 
static  void    EPS_Postamble(void);
67
 
static  void    PS_Postamble(void);
68
 
static  void    PS_EPS_Exit(Boolean);
69
 
static  void    PS_Init(PrintInitTypePtr);
70
 
static  void    EPS_Init(PrintInitTypePtr);
71
 
static  void    PS_SetColor(XColor);
72
 
static  void    PS_Invert(int);
73
 
static  void    PS_PrintLine(LineTypePtr, Boolean);
74
 
static  void    PS_PrintArc(ArcTypePtr, Boolean);
75
 
static  void    PS_PrintPolygon(PolygonTypePtr);
76
 
static  void    PS_PrintText(TextTypePtr);
77
 
static  void    PS_PrintTextLowLevel(TextTypePtr);
78
 
static  void    PS_PrintElementPackage(ElementTypePtr);
79
 
static  void    PS_PrintPad(PadTypePtr, int);
80
 
static  void    PS_PrintPinOrVia(PinTypePtr, int);
81
 
static  void    PS_Outline(Position, Position,
82
 
                        Position, Position);
83
 
static  void    PS_Alignment(Position, Position,
84
 
                        Position, Position);
85
 
static  void    PS_DrillHelper(PinTypePtr, int);
86
 
static  void    PS_FilledRectangle(Position, Position,
87
 
                        Position, Position);
 
73
static void PrintStringArray (char **, int, FILE *);
 
74
static char *PS_Preamble (PrintInitTypePtr, char *);
 
75
static char *EPS_Preamble (PrintInitTypePtr, char *);
 
76
static char *PS_EPS_Init (PrintInitTypePtr, char *, Boolean);
 
77
static void PS_Exit (void);
 
78
static void EPS_Exit (void);
 
79
static void EPS_Postamble (void);
 
80
static void PS_Postamble (void);
 
81
static void PS_EPS_Exit (Boolean);
 
82
static void PS_Init (PrintInitTypePtr);
 
83
static void EPS_Init (PrintInitTypePtr);
 
84
static void PS_SetColor (XColor);
 
85
static void PS_Invert (int);
 
86
static void PS_PrintLine (LineTypePtr, Boolean);
 
87
static void PS_PrintArc (ArcTypePtr, Boolean);
 
88
static void PS_PrintPolygon (PolygonTypePtr);
 
89
static void PS_PrintText (TextTypePtr);
 
90
static void PS_PrintTextLowLevel (TextTypePtr);
 
91
static void PS_PrintElementPackage (ElementTypePtr);
 
92
static void PS_PrintPad (PadTypePtr, int);
 
93
static void PS_PrintPinOrVia (PinTypePtr, int);
 
94
static void PS_Outline (LocationType, LocationType, LocationType, LocationType);
 
95
static void PS_Alignment (LocationType, LocationType, LocationType, LocationType);
 
96
static void PS_DrillHelper (PinTypePtr, int);
88
97
 
89
98
/* ----------------------------------------------------------------------
90
99
 * some local identifiers
116
125
 * some PS code for arcs comes from the output of 'Fig2Dev'. Thanks to
117
126
 * the author
118
127
 */
119
 
static  PrintDeviceType PS_QueryConstants = {
120
 
        "PostScript",
121
 
        "ps",
122
 
        PS_Init,
123
 
        PS_Exit,
124
 
        PS_Preamble,
125
 
        PS_Postamble,
126
 
        PS_SetColor,
127
 
        PS_Invert,
128
 
        PS_PrintLine,
129
 
        PS_PrintArc,
130
 
        PS_PrintPolygon,
131
 
        PS_PrintText,
132
 
        PS_PrintPad,
133
 
        PS_PrintPinOrVia,
134
 
        PS_PrintElementPackage,
135
 
        NULL,                           /* no drill information */
136
 
        PS_Outline,
137
 
        PS_Alignment,
138
 
        PS_DrillHelper,
139
 
        NULL,                           /* no group IDs */
140
 
        True,                           /* driver can handle color */
141
 
        False,                          /* handles no drill information */
142
 
        True,                           /* handles different media */
143
 
        True,                           /* allows mirroring */
144
 
        True },                         /* allows rotate */
145
 
 
146
 
        EPS_QueryConstants = {
147
 
        "encapsulated PostScript",
148
 
        "eps",
149
 
        EPS_Init,
150
 
        EPS_Exit,
151
 
        EPS_Preamble,
152
 
        EPS_Postamble,
153
 
        PS_SetColor,
154
 
        PS_Invert,
155
 
        PS_PrintLine,
156
 
        PS_PrintArc,
157
 
        PS_PrintPolygon,
158
 
        PS_PrintText,
159
 
        PS_PrintPad,
160
 
        PS_PrintPinOrVia,
161
 
        PS_PrintElementPackage,
162
 
        NULL,                           /* no drill information */
163
 
        PS_Outline,
164
 
        PS_Alignment,
165
 
        PS_DrillHelper,
166
 
        NULL,                           /* no group ID */
167
 
        True,
168
 
        False,
169
 
        False,          /* encapsulated doesn't allow media changes */
170
 
        True,
171
 
        True };                         /* allows rotate */
172
 
 
173
 
static  PrintInitType   PS_Flags;
174
 
 
175
 
static  char    *PS_Functions[] = {
176
 
        "",
177
 
        "/PcbDict 200 dict def",
178
 
        "PcbDict begin",
179
 
        "PcbDict /DictMatrix matrix put",
180
 
        "",
181
 
        "% some constants",
182
 
        "/Black {0.0 mysetgray} def",
183
 
        "/White {1.0 mysetgray} def",
184
 
        "/TAN {0.207106781} def",
185
 
        "/MTAN {-0.207106781} def",
186
 
        "",
187
 
        "% draw a filled polygon",
188
 
        "% get (x,y)... and number of points from stack",
189
 
        "/PO {",
190
 
        "       /number exch def",
191
 
        "       newpath",
192
 
        "       moveto",
193
 
        "       number 1 sub { lineto } repeat",
194
 
        "       closepath fill stroke",
195
 
        "} def",
196
 
        "",
197
 
        "/P {",
198
 
        "% draw a pin-polygon,",
199
 
        "% get x, y and thickness from stack",
200
 
        "       /thickness exch def /y exch def /x exch def",
201
 
        "       gsave x y translate thickness thickness scale",
202
 
        "       0.5  MTAN",
203
 
        "       TAN  -0.5",
204
 
        "       MTAN -0.5",
205
 
        "       -0.5 MTAN",
206
 
        "       -0.5 TAN",
207
 
        "       MTAN 0.5",
208
 
        "       TAN  0.5",
209
 
        "       0.5  TAN",
210
 
        "       8 PO grestore",
211
 
        "} def",
212
 
        "",
213
 
        "/PV {",
214
 
        "% pin or via, x, y and thickness are on the stack",
215
 
        "       /drillinghole exch def /thickness exch def /y exch def /x exch def",
216
 
        "       x y thickness P",
217
 
        "% draw drilling hole",
218
 
        "       gsave White 0 setlinewidth",
219
 
        "   newpath x y drillinghole 2 div 0 360 arc closepath fill stroke",
220
 
        "   grestore",
221
 
        "} def",
222
 
        "",
223
 
        "/PVR {",
224
 
        "% pin or via, x, y and thickness are on the stack",
225
 
        "       /drillinghole exch def /thickness exch def /y exch def /x exch def",
226
 
        "       gsave 0 setlinewidth",
227
 
        "       newpath x y thickness 2 div 0 360 arc closepath fill stroke",
228
 
        "% draw drilling whole",
229
 
        "       White",
230
 
        "       newpath x y drillinghole 2 div 0 360 arc closepath fill stroke",
231
 
        "       grestore",
232
 
        "} def",
233
 
        "",
234
 
        "/PVSQ {",
235
 
        "% square pin or via, x, y and thickness are on the stack",
236
 
        "       /drillinghole exch def /thickness exch def /y exch def /x exch def",
237
 
        "       newpath x thickness 2 div sub y thickness 2 div sub moveto",
238
 
        "       thickness 0 rlineto 0 thickness rlineto",
239
 
        "       thickness neg 0 rlineto closepath fill stroke",
240
 
        "% draw drilling hole",
241
 
        "       gsave White 0 setlinewidth",
242
 
        "   newpath x y drillinghole 2 div 0 360 arc closepath fill stroke",
243
 
        "   grestore",
244
 
        "} def",
245
 
        "",
246
 
        "/DH {",
247
 
        "% drill helpher; x, y, hole, copper-thickness are on stack",
248
 
        "       /copper exch def /hole exch def /y exch def /x exch def",
249
 
        "   gsave copper setlinewidth",
250
 
        "   newpath x y hole copper add 2 div 0 360 arc closepath stroke",
251
 
        "   grestore",
252
 
        "} def",
253
 
        "",
254
 
        "/L {",
255
 
        "% line, get x1, y1, x2, y2 and thickness from stack",
256
 
        "       /thick exch def /y2 exch def /x2 exch def /y1 exch def /x1 exch def",
257
 
        "       gsave thick setlinewidth",
258
 
        "       x1 y1 moveto x2 y2 lineto stroke",
259
 
        "       grestore",
260
 
        "} def",
261
 
        "",
262
 
        "/CL {",
263
 
        "% line, get x1, y1, x2, y2 and thickness from stack",
264
 
        "       /thick exch def /y2 exch def /x2 exch def /y1 exch def /x1 exch def",
265
 
        "       gsave White thick setlinewidth",
266
 
        "       x1 y1 moveto x2 y2 lineto stroke",
267
 
        "       grestore",
268
 
        "} def",
269
 
        "",
270
 
        "/B {",
271
 
        "% filled box, get x1, y1, x2 and y2 from stack",
272
 
        "       /y2 exch def /x2 exch def /y1 exch def /x1 exch def",
273
 
        "       newpath",
274
 
        "       x1 y1 moveto x2 y1 lineto x2 y2 lineto x1 y2 lineto",
275
 
        "       closepath fill stroke",
276
 
        "} def",
277
 
        "",
278
 
        "/PA {",
279
 
        "% pad, same as line",
280
 
        "       L",
281
 
        "} def",
282
 
        "",
283
 
        "/A {",
284
 
        "% arc for elements, get x, y, width, height, thickness",
285
 
        "% startangle and delta-angle from stack",
286
 
        "  /delta exch def /start exch def /thickness exch def",
287
 
        "  /height exch def /width exch def /y exch def /x exch def",
288
 
        "% draw it",
289
 
        "       gsave thickness setlinewidth /save DictMatrix currentmatrix def",
290
 
        "% scaling is less then zero because the coord system has to be swapped",
291
 
        "       x y translate width neg height scale",
292
 
        "       0 0 1 start start delta add arc save setmatrix stroke",
293
 
        "       grestore",
294
 
        "} def",
295
 
        "",
296
 
        "/CA {",
297
 
        "% arc for elements, get x, y, width, height, thickness",
298
 
        "% startangle and delta-angle from stack",
299
 
        "  /delta exch def /start exch def /thickness exch def",
300
 
        "  /height exch def /width exch def /y exch def /x exch def",
301
 
        "% draw it",
302
 
        "       gsave White thickness setlinewidth /save DictMatrix currentmatrix def",
303
 
        "% scaling is less then zero because the coord system has to be swapped",
304
 
        "       x y translate width neg height scale",
305
 
        "       0 0 1 start start delta add arc save setmatrix stroke",
306
 
        "       grestore",
307
 
        "} def",
308
 
        "",
309
 
        "/CLRPV {",
310
 
        "% clears a pin/via for groundplane; x,y and thickness are on stack",
311
 
        "   /thickness exch def /y exch def /x exch def",
312
 
        "       gsave White x y thickness P grestore",
313
 
        "} def",
314
 
        "",
315
 
        "/CLRPVSQ {",
316
 
        "% clears a square pin, x,y and thickness are on stack",
317
 
        "       /thickness exch def /y exch def /x exch def",
318
 
        "   gsave White",
319
 
        "       newpath x thickness 2 div sub y thickness 2 div sub moveto",
320
 
        "       thickness 0 rlineto 0 thickness rlineto",
321
 
        "       thickness neg 0 rlineto closepath fill stroke",
322
 
        "       grestore",
323
 
        "} def",
324
 
        "",
325
 
        "/CLRPVR {",
326
 
        "% clears a round pin/via for groundplane; x,y and thickness are on the stack",
327
 
        "       /thickness exch def /y exch def /x exch def",
328
 
        "       gsave White 0 setlinewidth",
329
 
        "       newpath x y thickness 2 div 0 360 arc closepath fill stroke",
330
 
        "       grestore",
331
 
        "} def",
332
 
        "",
333
 
        "/CLRPA {",
334
 
        "% clear line, get x1, y1, x2, y2 and thickness from stack",
335
 
        "       /thick exch def /y2 exch def /x2 exch def /y1 exch def /x1 exch def",
336
 
        "       gsave White thick setlinewidth",
337
 
        "       x1 y1 moveto x2 y2 lineto stroke",
338
 
        "       grestore",
339
 
        "} def",
340
 
        "",
341
 
        "/CLRB {",
342
 
        "% cleared box, get x1, y1, x2 and y2 from stack",
343
 
        "       /y2 exch def /x2 exch def /y1 exch def /x1 exch def",
344
 
        "       gsave White newpath",
345
 
        "       x1 y1 moveto x2 y1 lineto x2 y2 lineto x1 y2 lineto",
346
 
        "       closepath fill stroke",
347
 
        "       grestore",
348
 
        "} def",
349
 
        "",
350
 
        "/FILL {",
351
 
        "% draw a filled rectangle for the ground plane",
352
 
        "% get x1, y1, x2 and y2 from stack",
353
 
        "       /y2 exch def /x2 exch def /y1 exch def /x1 exch def",
354
 
        "   gsave 0 setlinewidth",
355
 
        "       newpath",
356
 
        "       x1 y1 moveto x2 y1 lineto x2 y2 lineto x1 y2 lineto",
357
 
        "       closepath fill stroke",
358
 
        "   grestore",
359
 
        "} def",
360
 
        "",
361
 
        "/Outline {",
362
 
        "% outline, get x1, y1, x2 and y2 from stack",
363
 
        "       /y2 exch def /x2 exch def /y1 exch def /x1 exch def",
364
 
        "   gsave 0.175 setlinewidth",
365
 
        "       newpath",
366
 
        "       x1 y1 moveto x2 y1 lineto x2 y2 lineto x1 y2 lineto",
367
 
        "       closepath stroke",
368
 
        "   grestore",
369
 
        "} def",
370
 
        "",
371
 
        "/Alignment {",
372
 
        "% alignment targets, get x1, y1, x2, y2 and distance from stack",
373
 
        "       /dis exch def /y2 exch def /x2 exch def /y1 exch def /x1 exch def",
374
 
        "   gsave 0.175 setlinewidth",
375
 
        "   newpath x1 y1 dis add moveto",
376
 
        "      0 dis 2 mul neg rlineto",
377
 
        "      dis neg dis rmoveto",
378
 
        "      dis 2 mul 0 rlineto",
379
 
        "   stroke",
380
 
        "   newpath x1 y1 dis 0 90 arcn stroke",
381
 
        "   newpath x1 y2 dis sub moveto 0 dis rlineto dis 0 rlineto stroke",
382
 
        "   newpath x2 y2 dis sub moveto",
383
 
        "      0 2 dis mul rlineto",
384
 
        "      dis dup neg rmoveto",
385
 
        "      2 dis mul neg 0 rlineto"
386
 
        "   stroke",
387
 
        "   newpath x2 y1 dis add moveto 0 dis neg rlineto dis neg 0 rlineto stroke",
388
 
        "   grestore",
389
 
        "} def",
390
 
        "" };
391
 
 
392
 
static  char    *PS_ColorFunctions[] = {
393
 
        "/mysetgray { setgray } def",
394
 
        "/mysetrgbcolor { setrgbcolor } def",
395
 
        "" };
396
 
 
397
 
static  char    *PS_InvertColorFunctions[] = {
398
 
        "/mysetgray {neg 1.0 add setgray} def",
399
 
        "/mysetrgbcolor {",
400
 
        "  /blue exch def /green exch def /red exch def",
401
 
        "  1.0 red sub 1.0 green sub 1.0 blue sub setrgbcolor",
402
 
        "} def"
403
 
        "" };
404
 
 
405
 
static  char    *PS_Setup[] = {
406
 
        "0.0 setlinewidth",
407
 
        "1 setlinecap",
408
 
        "Black" };
 
128
static PrintDeviceType PS_QueryConstants = {
 
129
  "PostScript",
 
130
  "ps",
 
131
  PS_Init,
 
132
  PS_Exit,
 
133
  PS_Preamble,
 
134
  PS_Postamble,
 
135
  PS_SetColor,
 
136
  PS_Invert,
 
137
  PS_PrintLine,
 
138
  PS_PrintArc,
 
139
  PS_PrintPolygon,
 
140
  PS_PrintText,
 
141
  PS_PrintPad,
 
142
  PS_PrintPinOrVia,
 
143
  PS_PrintElementPackage,
 
144
  NULL,                         /* no drill information */
 
145
  PS_Outline,
 
146
  PS_Alignment,
 
147
  PS_DrillHelper,
 
148
  NULL,                         /* no group IDs */
 
149
  True,                         /* driver can handle color */
 
150
  False,                        /* handles no drill information */
 
151
  True,                         /* handles different media */
 
152
  True,                         /* allows mirroring */
 
153
  True,                         /* allows rotate */
 
154
  True
 
155
},                              /* allows scaling */
 
156
 
 
157
  EPS_QueryConstants =
 
158
{
 
159
  "encapsulated PostScript", "eps", EPS_Init, EPS_Exit, EPS_Preamble, EPS_Postamble, PS_SetColor, PS_Invert, PS_PrintLine, PS_PrintArc, PS_PrintPolygon, PS_PrintText, PS_PrintPad, PS_PrintPinOrVia, PS_PrintElementPackage, NULL,     /* no drill information */
 
160
    PS_Outline, PS_Alignment, PS_DrillHelper, NULL,     /* no group ID */
 
161
    True, False, False,         /* encapsulated doesn't allow media changes */
 
162
    True, True,                 /* allows rotate */
 
163
True};                          /* allows scaling */
 
164
 
 
165
static PrintInitType PS_Flags;
 
166
static Boolean preamble = False;
 
167
 
 
168
static char *PS_Functions[] = {
 
169
  "",
 
170
  "/PcbDict 200 dict def",
 
171
  "PcbDict begin",
 
172
  "PcbDict /DictMatrix matrix put",
 
173
  "",
 
174
  "% some constants",
 
175
  "/Black {0.0 mysetgray} def",
 
176
  "/White {1.0 mysetgray} def",
 
177
  "/TAN {0.207106781} def",
 
178
  "/MTAN {-0.207106781} def",
 
179
  "",
 
180
  "% draw a filled polygon",
 
181
  "% get (x,y)... and number of points from stack",
 
182
  "/PO {",
 
183
  "     /number exch def",
 
184
  "     newpath",
 
185
  "     moveto",
 
186
  "     number 1 sub { lineto } repeat",
 
187
  "     closepath fill stroke",
 
188
  "} def",
 
189
  "",
 
190
  "/P {",
 
191
  "% draw a pin-polygon,",
 
192
  "% get x, y and thickness from stack",
 
193
  "     /thickness exch def /y exch def /x exch def",
 
194
  "     gsave x y translate thickness thickness scale",
 
195
  "     0.5  MTAN",
 
196
  "     TAN  -0.5",
 
197
  "     MTAN -0.5",
 
198
  "     -0.5 MTAN",
 
199
  "     -0.5 TAN",
 
200
  "     MTAN 0.5",
 
201
  "     TAN  0.5",
 
202
  "     0.5  TAN",
 
203
  "     8 PO grestore",
 
204
  "} def",
 
205
  "",
 
206
  "/PV {",
 
207
  "% pin or via, x, y and thickness are on the stack",
 
208
  "     /drillinghole exch def /thickness exch def /y exch def /x exch def",
 
209
  "     x y thickness P",
 
210
  "% draw drilling hole",
 
211
  "     gsave White 0 setlinewidth",
 
212
  "   newpath x y drillinghole 2 div 0 360 arc closepath fill stroke",
 
213
  "   grestore",
 
214
  "} def",
 
215
  "",
 
216
  "/PVR {",
 
217
  "% pin or via, x, y and thickness are on the stack",
 
218
  "     /drillinghole exch def /thickness exch def /y exch def /x exch def",
 
219
  "     gsave 0 setlinewidth",
 
220
  "     newpath x y thickness 2 div 0 360 arc closepath fill stroke",
 
221
  "% draw drilling whole",
 
222
  "     White",
 
223
  "     newpath x y drillinghole 2 div 0 360 arc closepath fill stroke",
 
224
  "     grestore",
 
225
  "} def",
 
226
  "",
 
227
  "/PVSQ {",
 
228
  "% square pin or via, x, y and thickness are on the stack",
 
229
  "     /drillinghole exch def /thickness exch def /y exch def /x exch def",
 
230
  "     newpath x thickness 2 div sub y thickness 2 div sub moveto",
 
231
  "     thickness 0 rlineto 0 thickness rlineto",
 
232
  "     thickness neg 0 rlineto closepath fill stroke",
 
233
  "% draw drilling hole",
 
234
  "     gsave White 0 setlinewidth",
 
235
  "   newpath x y drillinghole 2 div 0 360 arc closepath fill stroke",
 
236
  "   grestore",
 
237
  "} def",
 
238
  "",
 
239
  "/DH {",
 
240
  "% drill helpher; x, y, hole, copper-thickness are on stack",
 
241
  "     /copper exch def /hole exch def /y exch def /x exch def",
 
242
  "   gsave copper setlinewidth",
 
243
  "   newpath x y hole copper add 2 div 0 360 arc closepath stroke",
 
244
  "   grestore",
 
245
  "} def",
 
246
  "",
 
247
  "/L {",
 
248
  "% line, get x1, y1, x2, y2 and thickness from stack",
 
249
  "     /thick exch def /y2 exch def /x2 exch def /y1 exch def /x1 exch def",
 
250
  "     gsave thick setlinewidth",
 
251
  "     x1 y1 moveto x2 y2 lineto stroke",
 
252
  "     grestore",
 
253
  "} def",
 
254
  "",
 
255
  "/CL {",
 
256
  "% line, get x1, y1, x2, y2 and thickness from stack",
 
257
  "     /thick exch def /y2 exch def /x2 exch def /y1 exch def /x1 exch def",
 
258
  "     gsave White thick setlinewidth",
 
259
  "     x1 y1 moveto x2 y2 lineto stroke",
 
260
  "     grestore",
 
261
  "} def",
 
262
  "",
 
263
  "/B {",
 
264
  "% filled box, get x1, y1, x2 and y2 from stack",
 
265
  "     /y2 exch def /x2 exch def /y1 exch def /x1 exch def",
 
266
  "     newpath",
 
267
  "     x1 y1 moveto x2 y1 lineto x2 y2 lineto x1 y2 lineto",
 
268
  "     closepath fill stroke",
 
269
  "} def",
 
270
  "",
 
271
  "/PA {",
 
272
  "% pad, same as line",
 
273
  "     L",
 
274
  "} def",
 
275
  "",
 
276
  "/A {",
 
277
  "% arc for elements, get x, y, width, height, thickness",
 
278
  "% startangle and delta-angle from stack",
 
279
  "  /delta exch def /start exch def /thickness exch def",
 
280
  "  /height exch def /width exch def /y exch def /x exch def",
 
281
  "% draw it",
 
282
  "     gsave thickness setlinewidth /save DictMatrix currentmatrix def",
 
283
  "% scaling is less then zero because the coord system has to be swapped",
 
284
  "     x y translate width neg height scale",
 
285
  "     0 0 1 start start delta add arc save setmatrix stroke",
 
286
  "     grestore",
 
287
  "} def",
 
288
  "",
 
289
  "/CA {",
 
290
  "% arc for elements, get x, y, width, height, thickness",
 
291
  "% startangle and delta-angle from stack",
 
292
  "  /delta exch def /start exch def /thickness exch def",
 
293
  "  /height exch def /width exch def /y exch def /x exch def",
 
294
  "% draw it",
 
295
  "     gsave White thickness setlinewidth /save DictMatrix currentmatrix def",
 
296
  "% scaling is less then zero because the coord system has to be swapped",
 
297
  "     x y translate width neg height scale",
 
298
  "     0 0 1 start start delta add arc save setmatrix stroke",
 
299
  "     grestore",
 
300
  "} def",
 
301
  "",
 
302
  "/CLRPV {",
 
303
  "% clears a pin/via for groundplane; x,y and thickness are on stack",
 
304
  "   /thickness exch def /y exch def /x exch def",
 
305
  "     gsave White x y thickness P grestore",
 
306
  "} def",
 
307
  "",
 
308
  "/CLRPVSQ {",
 
309
  "% clears a square pin, x,y and thickness are on stack",
 
310
  "     /thickness exch def /y exch def /x exch def",
 
311
  "   gsave White",
 
312
  "     newpath x thickness 2 div sub y thickness 2 div sub moveto",
 
313
  "     thickness 0 rlineto 0 thickness rlineto",
 
314
  "     thickness neg 0 rlineto closepath fill stroke",
 
315
  "     grestore",
 
316
  "} def",
 
317
  "",
 
318
  "/CLRPVR {",
 
319
  "% clears a round pin/via for groundplane; x,y and thickness are on the stack",
 
320
  "     /thickness exch def /y exch def /x exch def",
 
321
  "     gsave White 0 setlinewidth",
 
322
  "     newpath x y thickness 2 div 0 360 arc closepath fill stroke",
 
323
  "     grestore",
 
324
  "} def",
 
325
  "",
 
326
  "/CLRPA {",
 
327
  "% clear line, get x1, y1, x2, y2 and thickness from stack",
 
328
  "     /thick exch def /y2 exch def /x2 exch def /y1 exch def /x1 exch def",
 
329
  "     gsave White thick setlinewidth",
 
330
  "     x1 y1 moveto x2 y2 lineto stroke",
 
331
  "     grestore",
 
332
  "} def",
 
333
  "",
 
334
  "/CLRB {",
 
335
  "% cleared box, get x1, y1, x2 and y2 from stack",
 
336
  "     /y2 exch def /x2 exch def /y1 exch def /x1 exch def",
 
337
  "     gsave White newpath",
 
338
  "     x1 y1 moveto x2 y1 lineto x2 y2 lineto x1 y2 lineto",
 
339
  "     closepath fill stroke",
 
340
  "     grestore",
 
341
  "} def",
 
342
  "",
 
343
  "/FILL {",
 
344
  "% draw a filled rectangle for the ground plane",
 
345
  "% get x1, y1, x2 and y2 from stack",
 
346
  "     /y2 exch def /x2 exch def /y1 exch def /x1 exch def",
 
347
  "   gsave 0 setlinewidth",
 
348
  "     newpath",
 
349
  "     x1 y1 moveto x2 y1 lineto x2 y2 lineto x1 y2 lineto",
 
350
  "     closepath fill stroke",
 
351
  "   grestore",
 
352
  "} def",
 
353
  "",
 
354
  "/Outline {",
 
355
  "% outline, get x1, y1, x2 and y2 from stack",
 
356
  "     /y2 exch def /x2 exch def /y1 exch def /x1 exch def",
 
357
  "   gsave 0.175 setlinewidth",
 
358
  "     newpath",
 
359
  "     x1 y1 moveto x2 y1 lineto x2 y2 lineto x1 y2 lineto",
 
360
  "     closepath stroke",
 
361
  "   grestore",
 
362
  "} def",
 
363
  "",
 
364
  "/Alignment {",
 
365
  "% alignment targets, get x1, y1, x2, y2 and distance from stack",
 
366
  "     /dis exch def /y2 exch def /x2 exch def /y1 exch def /x1 exch def",
 
367
  "   gsave 0.175 setlinewidth",
 
368
  "   newpath x1 y1 dis add moveto",
 
369
  "      0 dis 2 mul neg rlineto",
 
370
  "      dis neg dis rmoveto",
 
371
  "      dis 2 mul 0 rlineto",
 
372
  "   stroke",
 
373
  "   newpath x1 y1 dis 0 90 arcn stroke",
 
374
  "   newpath x1 y2 dis sub moveto 0 dis rlineto dis 0 rlineto stroke",
 
375
  "   newpath x2 y2 dis sub moveto",
 
376
  "      0 2 dis mul rlineto",
 
377
  "      dis dup neg rmoveto",
 
378
  "      2 dis mul neg 0 rlineto" "   stroke",
 
379
  "   newpath x2 y1 dis add moveto 0 dis neg rlineto dis neg 0 rlineto stroke",
 
380
  "   grestore",
 
381
  "} def",
 
382
  ""
 
383
};
 
384
 
 
385
static char *PS_ColorFunctions[] = {
 
386
  "/mysetgray { setgray } def",
 
387
  "/mysetrgbcolor { setrgbcolor } def",
 
388
  ""
 
389
};
 
390
 
 
391
static char *PS_InvertColorFunctions[] = {
 
392
  "/mysetgray {neg 1.0 add setgray} def",
 
393
  "/mysetrgbcolor {",
 
394
  "  /blue exch def /green exch def /red exch def",
 
395
  "  1.0 red sub 1.0 green sub 1.0 blue sub setrgbcolor",
 
396
  "} def" ""
 
397
};
 
398
 
 
399
static char *PS_Setup[] = {
 
400
  "0.0 setlinewidth",
 
401
  "1 setlinecap",
 
402
  "Black"
 
403
};
409
404
 
410
405
/* ---------------------------------------------------------------------------
411
406
 * prints a string array
412
407
 */
413
 
static void PrintStringArray(char **Array, int Number, FILE *FP)
 
408
static void
 
409
PrintStringArray (char **Array, int Number, FILE * FP)
414
410
{
415
 
        for (; Number; Number--, Array++)
416
 
                fprintf(FP, "%s\n", *Array);
 
411
  for (; Number; Number--, Array++)
 
412
    fprintf (FP, "%s\n", *Array);
417
413
}
418
414
 
419
415
/* ---------------------------------------------------------------------------
420
416
 * returns information about the PostScript driver
421
417
 */
422
 
PrintDeviceTypePtr PS_Query(void)
 
418
PrintDeviceTypePtr
 
419
PS_Query (void)
423
420
{
424
 
        return(&PS_QueryConstants);
 
421
  return (&PS_QueryConstants);
425
422
}
426
423
 
427
424
/* ---------------------------------------------------------------------------
428
425
 * returns information about the encapsulated PostScript driver
429
426
 */
430
 
PrintDeviceTypePtr EPS_Query(void)
 
427
PrintDeviceTypePtr
 
428
EPS_Query (void)
431
429
{
432
 
        return(&EPS_QueryConstants);
 
430
  return (&EPS_QueryConstants);
433
431
}
434
432
 
435
433
/* ----------------------------------------------------------------------
436
434
 * call init routine for PostScript output
437
435
 */
438
 
static char *PS_Preamble(PrintInitTypePtr Flags, char *Description)
 
436
static char *
 
437
PS_Preamble (PrintInitTypePtr Flags, char *Description)
439
438
{
440
 
        return(PS_EPS_Init(Flags, Description, False));
 
439
  return (PS_EPS_Init (Flags, Description, False));
441
440
}
442
 
static void PS_Init(PrintInitTypePtr wasted)
 
441
static void
 
442
PS_Init (PrintInitTypePtr wasted)
443
443
{
444
444
}
445
445
 
446
446
/* ----------------------------------------------------------------------
447
447
 * call init routine for encapsulated PostScript output
448
448
 */
449
 
static char *EPS_Preamble(PrintInitTypePtr Flags, char *Description)
450
 
{
451
 
        return(PS_EPS_Init(Flags, Description, True));
452
 
}
453
 
static void EPS_Init(PrintInitTypePtr wasted)
454
 
{
455
 
}
456
 
static void PS_Invert(int mode)
457
 
{
458
 
        if (mode == 1)
459
 
        {
460
 
                if (PS_Flags.InvertFlag)
461
 
                        PrintStringArray(PS_ColorFunctions,
462
 
                                ENTRIES(PS_ColorFunctions), PS_Flags.FP);
463
 
                else
464
 
                        PrintStringArray(PS_InvertColorFunctions,
465
 
                                ENTRIES(PS_InvertColorFunctions), PS_Flags.FP);
466
 
        }
 
449
static char *
 
450
EPS_Preamble (PrintInitTypePtr Flags, char *Description)
 
451
{
 
452
  return (PS_EPS_Init (Flags, Description, True));
 
453
}
 
454
static void
 
455
EPS_Init (PrintInitTypePtr wasted)
 
456
{
 
457
}
 
458
static void
 
459
PS_Invert (int mode)
 
460
{
 
461
  if (mode == 1)
 
462
    {
 
463
      if (PS_Flags.InvertFlag)
 
464
        PrintStringArray (PS_ColorFunctions,
 
465
                          ENTRIES (PS_ColorFunctions), PS_Flags.FP);
 
466
      else
 
467
        PrintStringArray (PS_InvertColorFunctions,
 
468
                          ENTRIES (PS_InvertColorFunctions), PS_Flags.FP);
 
469
    }
467
470
}
468
471
 
469
472
/* ----------------------------------------------------------------------
470
473
 * prints PostScript or enc. PostScript header with function definition
471
474
 * info struct is are passed in
472
475
 */
473
 
static char *PS_EPS_Init(PrintInitTypePtr Flags, char *Description,
474
 
        Boolean CreateEPS)
 
476
static char *
 
477
PS_EPS_Init (PrintInitTypePtr Flags, char *Description, Boolean CreateEPS)
475
478
{
476
 
        BoxType         box;
477
 
        time_t          currenttime;
478
 
        float           dx, dy;
479
 
        struct  passwd  *pwentry;
480
 
 
481
 
                /* save passed-in data */
482
 
        PS_Flags = *Flags;
483
 
        currenttime = time(NULL);
484
 
 
485
 
                /* adjust the 'mirror' flag because (0,0) is in the lower/left
486
 
                 * corner which is different to X11
487
 
                 */
488
 
        if (!Settings.ShowSolderSide)
489
 
                PS_Flags.MirrorFlag = !PS_Flags.MirrorFlag;
490
 
 
491
 
                /* adjusting the offsets is also necessary because the
492
 
                 * passed coordinates are X11 ones (upper/left corner is 0,0)
493
 
                 */
494
 
        dx = dy = PS_Flags.Scale;
495
 
        dx *= (float) (PS_Flags.BoundingBox.X2 -PS_Flags.BoundingBox.X1);
496
 
        dy *= (float) (PS_Flags.BoundingBox.Y2 -PS_Flags.BoundingBox.Y1);
497
 
 
498
 
                /* create standard PS header */
499
 
        if (CreateEPS)
500
 
        {
501
 
                PS_Flags.OffsetX = 0;
502
 
                PS_Flags.OffsetY = 0;
503
 
                fputs("%!PS-Adobe-3.0 EPSF-3.0\n", PS_Flags.FP);
504
 
        }
505
 
        else
506
 
        {
507
 
                PS_Flags.OffsetY = PS_Flags.SelectedMedia->Height -PS_Flags.OffsetY;
508
 
                PS_Flags.OffsetY -= (Dimension) (PS_Flags.RotateFlag ? dx : dy);
509
 
                fputs("%!PS-Adobe-3.0\n", PS_Flags.FP);
510
 
        }
511
 
        fprintf(PS_Flags.FP, "%%%%Title: %s, %s\n", UNKNOWN(PCB->Name),
512
 
                UNKNOWN(Description));
513
 
        fprintf(PS_Flags.FP, "%%%%Creator: %s "RELEASE"\n", Progname);
514
 
        fprintf(PS_Flags.FP, "%%%%CreationDate: %s",
515
 
                asctime(localtime(&currenttime)));
516
 
        pwentry = getpwuid(getuid());
517
 
        fprintf(PS_Flags.FP, "%%%%For: %s (%s)\n", pwentry->pw_name,
518
 
                pwentry->pw_gecos);
519
 
        fputs("%%LanguageLevel: 1\n", PS_Flags.FP);
520
 
        fputs("%%Orientation: Portrait\n", PS_Flags.FP);
521
 
 
522
 
                /* - calculate the width and height of the bounding box;
523
 
                 * - write bounding box data to file
524
 
                 * - rotate it
525
 
                 * - transform to PS coordinates#
526
 
                 */
527
 
        box.X1 = (Position) ((float) PS_Flags.OffsetX * PS_UNIT) -1;
528
 
        box.Y1 = (Position) ((float) PS_Flags.OffsetY * PS_UNIT) -1;
529
 
        if (!PS_Flags.RotateFlag)
530
 
        {
531
 
                box.X2= (Position)((dx +PS_Flags.OffsetX) *PS_UNIT) +1;
532
 
                box.Y2= (Position)((dy +PS_Flags.OffsetY) *PS_UNIT) +1;
533
 
        }
534
 
        else
535
 
        {
536
 
                box.X2= (Position)((dy +PS_Flags.OffsetX) *PS_UNIT) +1;
537
 
                box.Y2= (Position)((dx +PS_Flags.OffsetY) *PS_UNIT) +1;
538
 
        }
539
 
 
540
 
                /* print it if encapsulated PostScript has been requested
541
 
                 * and add the appropriate structured comments
542
 
                 */
543
 
        if (CreateEPS)
544
 
        {
545
 
                fprintf(PS_Flags.FP, "%%%%BoundingBox: %i %i %i %i\n",
546
 
                        (int) box.X1, (int) box.Y1, (int) box.X2, (int) box.Y2);
547
 
                fputs("%%Pages: 0\n", PS_Flags.FP);
548
 
        }
549
 
        else
550
 
        {
551
 
                fputs("%%Pages: 1\n", PS_Flags.FP);
552
 
                fputs("%%PageOrder: Ascend\n", PS_Flags.FP);
553
 
                fprintf(PS_Flags.FP, "%%%%IncludeFeature: *PageSize %s\n",
554
 
                        PS_Flags.SelectedMedia->Name);
555
 
        }
556
 
 
557
 
                /* OK, continue with structured comments */
558
 
        fputs("%%EndComments\n", PS_Flags.FP);
559
 
        fputs("%%BeginProlog\n", PS_Flags.FP);
560
 
        PrintStringArray(PS_Functions, ENTRIES(PS_Functions), PS_Flags.FP);
561
 
        if (PS_Flags.InvertFlag)
562
 
                PrintStringArray(PS_InvertColorFunctions,
563
 
                        ENTRIES(PS_InvertColorFunctions), PS_Flags.FP);
564
 
        else
565
 
                PrintStringArray(PS_ColorFunctions,
566
 
                        ENTRIES(PS_ColorFunctions), PS_Flags.FP);
567
 
        fputs("%%EndProlog\n", PS_Flags.FP);
568
 
        fputs("%%BeginDefaults\n", PS_Flags.FP);
569
 
        fputs("%%EndDefaults\n", PS_Flags.FP);
570
 
        fputs("%%BeginSetup\n", PS_Flags.FP);
571
 
        if (!CreateEPS && strcmp(PS_Flags.SelectedMedia->Name, USERMEDIANAME))
572
 
                fprintf(PS_Flags.FP, "%s\n", PS_Flags.SelectedMedia->Name);
573
 
        PrintStringArray(PS_Setup, ENTRIES(PS_Setup), PS_Flags.FP);
574
 
        fputs("%%EndSetup\n", PS_Flags.FP);
575
 
 
576
 
        if (!CreateEPS)
577
 
        {
578
 
                fputs("%%Page: 1 1\n", PS_Flags.FP);
579
 
                fputs("%%BeginPageSetup\n", PS_Flags.FP);
580
 
                fputs("%%EndPageSetup\n", PS_Flags.FP);
581
 
        }
582
 
 
583
 
                /* clear the area */
584
 
        fputs("gsave White newpath\n", PS_Flags.FP);
585
 
        fprintf(PS_Flags.FP,
586
 
                "%i %i moveto %i %i lineto %i %i lineto %i %i lineto\n",
587
 
                (int) box.X1, (int) box.Y1,
588
 
                (int) box.X2, (int) box.Y1,
589
 
                (int) box.X2, (int) box.Y2,
590
 
                (int) box.X1, (int) box.Y2);
591
 
        fputs("closepath fill stroke grestore\n", PS_Flags.FP);
592
 
 
593
 
                /* add information about layout size, offset ... */
594
 
        fprintf(PS_Flags.FP, "%% PCBMIN(%d,%d), PCBMAX(%d,%d)\n",
595
 
                (int) PS_Flags.BoundingBox.X1,
596
 
                (int) PS_Flags.BoundingBox.Y1,
597
 
                (int) PS_Flags.BoundingBox.X2,
598
 
                (int) PS_Flags.BoundingBox.Y2);
599
 
        fprintf(PS_Flags.FP, "%% PCBOFFSET(%d,%d), PCBSCALE(%.5f)\n",
600
 
                PS_Flags.OffsetX,
601
 
                PS_Flags.OffsetY,
602
 
                PS_Flags.Scale);
603
 
        fputs("% PCBSTARTDATA --- do not remove ---\n", PS_Flags.FP);
604
 
        fputs("gsave\n", PS_Flags.FP);
605
 
 
606
 
                /* now insert transformation commands (reverse order):
607
 
                 * - move upper/left edge of layout to (0,0)
608
 
                 * - mirror it to transform X to PostScript coordinates
609
 
                 * - move to (0,0) again
610
 
                 * - if rotation is required, rotate and move to (0,0)
611
 
                 * - apply user scaling
612
 
                 * - move to new offset
613
 
                 * - scale to PostScript (72 dots per inch)
614
 
                 */ 
615
 
        fprintf(PS_Flags.FP, "%.5f %.5f scale\n",
616
 
                PS_UNIT, PS_UNIT);
617
 
        fprintf(PS_Flags.FP, "%i %i translate\n",
618
 
                PS_Flags.OffsetX,
619
 
                PS_Flags.OffsetY);
620
 
        fprintf(PS_Flags.FP, "%.3f %.3f scale\n",
621
 
                PS_Flags.Scale,
622
 
                PS_Flags.Scale);
623
 
        if (PS_Flags.RotateFlag)
624
 
        {
625
 
                fprintf(PS_Flags.FP, "%i 0 translate\n",
626
 
                        (int) PS_Flags.BoundingBox.Y2 -PS_Flags.BoundingBox.Y1);
627
 
                fputs("90 rotate\n", PS_Flags.FP);
628
 
        }
629
 
        if (PS_Flags.MirrorFlag)
630
 
        {
631
 
                fprintf(PS_Flags.FP, "0 %i translate\n",
632
 
                        (int) (PS_Flags.BoundingBox.Y2 -PS_Flags.BoundingBox.Y1));
633
 
                fputs("1 -1 scale\n", PS_Flags.FP);
634
 
        }
635
 
        fprintf(PS_Flags.FP, "%i %i translate\n",
636
 
                -PS_Flags.BoundingBox.X1,
637
 
                -PS_Flags.BoundingBox.Y1);
638
 
        return(NULL);
 
479
  BoxType box;
 
480
  time_t currenttime;
 
481
  float dx, dy;
 
482
  struct passwd *pwentry;
 
483
 
 
484
  /* save passed-in data */
 
485
  PS_Flags = *Flags;
 
486
  /* adjust the 'mirror' flag because (0,0) is in the lower/left
 
487
   * corner which is different from X coordinates
 
488
   */
 
489
  if (!Settings.ShowSolderSide)
 
490
    PS_Flags.MirrorFlag = !PS_Flags.MirrorFlag;
 
491
 
 
492
  /* adjusting the offsets is also necessary because the
 
493
   * passed coordinates are X (upper/left corner is 0,0)
 
494
   */
 
495
  dx = dy = PS_Flags.Scale;
 
496
  dx *= (float) (PS_Flags.BoundingBox.X2 - PS_Flags.BoundingBox.X1);
 
497
  dy *= (float) (PS_Flags.BoundingBox.Y2 - PS_Flags.BoundingBox.Y1);
 
498
 
 
499
  /* create standard PS header */
 
500
  if (CreateEPS)
 
501
    {
 
502
      PS_Flags.OffsetX = 0;
 
503
      PS_Flags.OffsetY = 0;
 
504
    }
 
505
  else
 
506
    {
 
507
      PS_Flags.OffsetY = PS_Flags.SelectedMedia->Height - PS_Flags.OffsetY;
 
508
      PS_Flags.OffsetY -= (BDimension) (PS_Flags.RotateFlag ? dx : dy);
 
509
    }
 
510
  if (!preamble)
 
511
    {
 
512
      preamble = True;
 
513
      if (CreateEPS)
 
514
        fputs ("%!PS-Adobe-3.0 EPSF-3.0\n", PS_Flags.FP);
 
515
      else
 
516
        fputs ("%!PS-Adobe-3.0\n", PS_Flags.FP);
 
517
      currenttime = time (NULL);
 
518
 
 
519
      fprintf (PS_Flags.FP, "%%%%Title: %s, %s\n", UNKNOWN (PCB->Name),
 
520
               UNKNOWN (Description));
 
521
      fprintf (PS_Flags.FP, "%%%%Creator: %s " VERSION "\n", Progname);
 
522
      fprintf (PS_Flags.FP, "%%%%CreationDate: %s",
 
523
               asctime (localtime (&currenttime)));
 
524
      pwentry = getpwuid (getuid ());
 
525
      fprintf (PS_Flags.FP, "%%%%For: %s (%s)\n", pwentry->pw_name,
 
526
               pwentry->pw_gecos);
 
527
      fputs ("%%LanguageLevel: 1\n", PS_Flags.FP);
 
528
      fputs ("%%Orientation: Portrait\n", PS_Flags.FP);
 
529
 
 
530
      /* - calculate the width and height of the bounding box;
 
531
       * - write bounding box data to file
 
532
       * - rotate it
 
533
       * - transform to PS coordinates#
 
534
       */
 
535
      box.X1 = (LocationType) ((float) PS_Flags.OffsetX * PS_UNIT) - 1;
 
536
      box.Y1 = (LocationType) ((float) PS_Flags.OffsetY * PS_UNIT) - 1;
 
537
      if (!PS_Flags.RotateFlag)
 
538
        {
 
539
          box.X2 = (LocationType) ((dx + PS_Flags.OffsetX) * PS_UNIT) + 1;
 
540
          box.Y2 = (LocationType) ((dy + PS_Flags.OffsetY) * PS_UNIT) + 1;
 
541
        }
 
542
      else
 
543
        {
 
544
          box.X2 = (LocationType) ((dy + PS_Flags.OffsetX) * PS_UNIT) + 1;
 
545
          box.Y2 = (LocationType) ((dx + PS_Flags.OffsetY) * PS_UNIT) + 1;
 
546
        }
 
547
 
 
548
      /* print it if encapsulated PostScript has been requested
 
549
       * and add the appropriate structured comments
 
550
       */
 
551
      if (CreateEPS)
 
552
        {
 
553
          fprintf (PS_Flags.FP, "%%%%BoundingBox: %i %i %i %i\n",
 
554
                   (int) box.X1, (int) box.Y1, (int) box.X2, (int) box.Y2);
 
555
          fputs ("%%Pages: 0\n", PS_Flags.FP);
 
556
        }
 
557
      else
 
558
        {
 
559
          fputs ("%%Pages: 1\n", PS_Flags.FP);
 
560
          fputs ("%%PageOrder: Ascend\n", PS_Flags.FP);
 
561
          fprintf (PS_Flags.FP, "%%%%DocumentMedia: %s %d %d\n",
 
562
                   PS_Flags.SelectedMedia->Name,
 
563
                   POST_SCALE(PS_Flags.SelectedMedia->Width),
 
564
                   POST_SCALE(PS_Flags.SelectedMedia->Height));
 
565
        }
 
566
 
 
567
      /* OK, continue with structured comments */
 
568
      fputs ("%%EndComments\n", PS_Flags.FP);
 
569
      fputs ("%%BeginProlog\n", PS_Flags.FP);
 
570
      PrintStringArray (PS_Functions, ENTRIES (PS_Functions), PS_Flags.FP);
 
571
      if (PS_Flags.InvertFlag)
 
572
        PrintStringArray (PS_InvertColorFunctions,
 
573
                          ENTRIES (PS_InvertColorFunctions), PS_Flags.FP);
 
574
      else
 
575
        PrintStringArray (PS_ColorFunctions,
 
576
                          ENTRIES (PS_ColorFunctions), PS_Flags.FP);
 
577
      fputs ("%%EndProlog\n", PS_Flags.FP);
 
578
      fputs ("%%BeginDefaults\n", PS_Flags.FP);
 
579
      fputs ("%%EndDefaults\n", PS_Flags.FP);
 
580
      fputs ("%%BeginSetup\n", PS_Flags.FP);
 
581
      PrintStringArray (PS_Setup, ENTRIES (PS_Setup), PS_Flags.FP);
 
582
      fputs ("%%EndSetup\n", PS_Flags.FP);
 
583
 
 
584
      if (!CreateEPS)
 
585
        {
 
586
          fputs ("%%Page: 1 1\n", PS_Flags.FP);
 
587
          fputs ("%%BeginPageSetup\n", PS_Flags.FP);
 
588
          fputs ("%%EndPageSetup\n", PS_Flags.FP);
 
589
        }
 
590
 
 
591
      /* clear the area */
 
592
      fputs ("gsave White newpath\n", PS_Flags.FP);
 
593
      fprintf (PS_Flags.FP,
 
594
               "%i %i moveto %i %i lineto %i %i lineto %i %i lineto\n",
 
595
               (int) box.X1, (int) box.Y1,
 
596
               (int) box.X2, (int) box.Y1,
 
597
               (int) box.X2, (int) box.Y2, (int) box.X1, (int) box.Y2);
 
598
      fputs ("closepath fill stroke grestore\n", PS_Flags.FP);
 
599
 
 
600
      /* add information about layout size, offset ... */
 
601
      fprintf (PS_Flags.FP, "%% PCBMIN(%d,%d), PCBMAX(%d,%d)\n",
 
602
               (int) PS_Flags.BoundingBox.X1,
 
603
               (int) PS_Flags.BoundingBox.Y1,
 
604
               (int) PS_Flags.BoundingBox.X2, (int) PS_Flags.BoundingBox.Y2);
 
605
      fprintf (PS_Flags.FP, "%% PCBOFFSET(%d,%d), PCBSCALE(%.5f)\n",
 
606
               PS_Flags.OffsetX, PS_Flags.OffsetY, PS_Flags.Scale);
 
607
      fputs ("% PCBSTARTDATA --- do not remove ---\n", PS_Flags.FP);
 
608
      fputs ("gsave\n", PS_Flags.FP);
 
609
    }
 
610
  else
 
611
    fputs ("grestore\ngsave\n", PS_Flags.FP);
 
612
 
 
613
 
 
614
  /* now insert transformation commands (reverse order):
 
615
   * - move upper/left edge of layout to (0,0)
 
616
   * - mirror it to transform X to PostScript coordinates
 
617
   * - move to (0,0) again
 
618
   * - if rotation is required, rotate and move to (0,0)
 
619
   * - apply user scaling
 
620
   * - move to new offset
 
621
   * - scale to PostScript (72 dots per inch)
 
622
   */
 
623
  fprintf (PS_Flags.FP, "%.5f %.5f scale\n", PS_UNIT, PS_UNIT);
 
624
  fprintf (PS_Flags.FP, "%i %i translate\n",
 
625
           PS_Flags.OffsetX, PS_Flags.OffsetY);
 
626
  fprintf (PS_Flags.FP, "%.3f %.3f scale\n", PS_Flags.Scale, PS_Flags.Scale);
 
627
  if (PS_Flags.RotateFlag)
 
628
    {
 
629
      fprintf (PS_Flags.FP, "%i 0 translate\n",
 
630
               (int) PS_Flags.BoundingBox.Y2 - PS_Flags.BoundingBox.Y1);
 
631
      fputs ("90 rotate\n", PS_Flags.FP);
 
632
    }
 
633
  if (PS_Flags.MirrorFlag)
 
634
    {
 
635
      fprintf (PS_Flags.FP, "0 %i translate\n",
 
636
               (int) (PS_Flags.BoundingBox.Y2 - PS_Flags.BoundingBox.Y1));
 
637
      fputs ("1 -1 scale\n", PS_Flags.FP);
 
638
    }
 
639
  fprintf (PS_Flags.FP, "%i %i translate\n",
 
640
           -PS_Flags.BoundingBox.X1, -PS_Flags.BoundingBox.Y1);
 
641
  return (NULL);
639
642
}
640
643
 
641
644
/* ----------------------------------------------------------------------
642
645
 * call exit routine for PostScript output
643
646
 */
644
 
static void PS_Postamble(void)
 
647
static void
 
648
PS_Postamble (void)
645
649
{
646
 
        PS_EPS_Exit(False);
 
650
  preamble = False;
 
651
  PS_EPS_Exit (False);
647
652
}
648
 
static void PS_Exit(void)
 
653
static void
 
654
PS_Exit (void)
649
655
{
650
656
}
651
657
 
652
658
/* ----------------------------------------------------------------------
653
659
 * call exit routine for encapsulated PostScript output
654
660
 */
655
 
static void EPS_Postamble(void)
 
661
static void
 
662
EPS_Postamble (void)
656
663
{
657
 
        PS_EPS_Exit(True);
 
664
  preamble = False;
 
665
  PS_EPS_Exit (True);
658
666
}
659
 
static void EPS_Exit(void)
 
667
static void
 
668
EPS_Exit (void)
660
669
{
661
670
}
662
671
 
663
672
/* ---------------------------------------------------------------------------
664
673
 * exit code for this driver is empty
665
674
 */
666
 
static void PS_EPS_Exit(Boolean CreateEPS)
 
675
static void
 
676
PS_EPS_Exit (Boolean CreateEPS)
667
677
{
668
 
                /* print trailing commands */
669
 
        fputs("grestore\n", PS_Flags.FP);
670
 
        fputs("% PCBENDDATA --- do not remove ---\n", PS_Flags.FP);
671
 
        if (!CreateEPS)
672
 
                fputs("showpage\n", PS_Flags.FP);
673
 
        fputs("%%EOF\n", PS_Flags.FP);
 
678
  /* print trailing commands */
 
679
  fputs ("grestore\n", PS_Flags.FP);
 
680
  fputs ("% PCBENDDATA --- do not remove ---\n", PS_Flags.FP);
 
681
  if (!CreateEPS)
 
682
    fputs ("showpage\n", PS_Flags.FP);
 
683
  fputs ("%%EOF\n", PS_Flags.FP);
674
684
}
675
685
 
676
686
/* ----------------------------------------------------------------------
677
687
 * prints a line
678
688
 */
679
 
static void PS_PrintLine(LineTypePtr Line, Boolean Clear)
 
689
static void
 
690
PS_PrintLine (LineTypePtr Line, Boolean Clear)
680
691
{
681
 
        if (Clear)
682
 
                fprintf(PS_Flags.FP, "%d %d %d %d %d CL\n",
683
 
                        (int) Line->Point1.X,
684
 
                        (int) Line->Point1.Y,
685
 
                        (int) Line->Point2.X,
686
 
                        (int) Line->Point2.Y,
687
 
                        (int) Line->Thickness + (int) Line->Clearance);
688
 
        else
689
 
                fprintf(PS_Flags.FP, "%d %d %d %d %d L\n",
690
 
                        (int) Line->Point1.X,
691
 
                        (int) Line->Point1.Y,
692
 
                        (int) Line->Point2.X,
693
 
                        (int) Line->Point2.Y,
694
 
                        (int) Line->Thickness);
 
692
  if (Clear)
 
693
    fprintf (PS_Flags.FP, "%d %d %d %d %d CL\n",
 
694
             (int) Line->Point1.X,
 
695
             (int) Line->Point1.Y,
 
696
             (int) Line->Point2.X,
 
697
             (int) Line->Point2.Y,
 
698
             (int) Line->Thickness + (int) Line->Clearance);
 
699
  else
 
700
    fprintf (PS_Flags.FP, "%d %d %d %d %d L\n",
 
701
             (int) Line->Point1.X,
 
702
             (int) Line->Point1.Y,
 
703
             (int) Line->Point2.X,
 
704
             (int) Line->Point2.Y, (int) Line->Thickness);
695
705
}
696
706
 
697
707
/* ---------------------------------------------------------------------------
698
708
 * prints an arc 
699
709
 */
700
 
static void PS_PrintArc(ArcTypePtr arc, Boolean Clear)
 
710
static void
 
711
PS_PrintArc (ArcTypePtr arc, Boolean Clear)
701
712
{
702
 
        if (Clear)
703
 
                fprintf(PS_Flags.FP, "%d %d %d %d %d %d %d CA\n",
704
 
                        (int) arc->X,
705
 
                        (int) arc->Y,
706
 
                        (int) arc->Width,
707
 
                        (int) arc->Height,
708
 
                        (int) arc->Thickness + (int) arc->Clearance,
709
 
                        (arc->Delta < 0) ? arc->StartAngle + arc->Delta : arc->StartAngle,
710
 
                        (arc->Delta < 0) ? -arc->Delta : arc->Delta);
711
 
        else
712
 
                fprintf(PS_Flags.FP, "%d %d %d %d %d %d %d A\n",
713
 
                        (int) arc->X,
714
 
                        (int) arc->Y,
715
 
                        (int) arc->Width,
716
 
                        (int) arc->Height,
717
 
                        (int) arc->Thickness,
718
 
                        (arc->Delta < 0) ? arc->StartAngle + arc->Delta : arc->StartAngle,
719
 
                        (arc->Delta < 0) ? -arc->Delta : arc->Delta);
 
713
  if (Clear)
 
714
    fprintf (PS_Flags.FP, "%d %d %d %d %d %ld %ld CA\n",
 
715
             (int) arc->X,
 
716
             (int) arc->Y,
 
717
             (int) arc->Width,
 
718
             (int) arc->Height,
 
719
             (int) arc->Thickness + (int) arc->Clearance,
 
720
             (arc->Delta <
 
721
              0) ? arc->StartAngle + arc->Delta : arc->StartAngle,
 
722
             (arc->Delta < 0) ? -arc->Delta : arc->Delta);
 
723
  else
 
724
    fprintf (PS_Flags.FP, "%d %d %d %d %d %ld %ld A\n", (int) arc->X,
 
725
             (int) arc->Y, (int) arc->Width, (int) arc->Height,
 
726
             (int) arc->Thickness,
 
727
             (arc->Delta <
 
728
              0) ? arc->StartAngle + arc->Delta : arc->StartAngle,
 
729
             (arc->Delta < 0) ? -arc->Delta : arc->Delta);
720
730
}
721
731
 
722
732
/* ---------------------------------------------------------------------------
723
733
 * prints a filled polygon
724
734
 */
725
 
static void PS_PrintPolygon(PolygonTypePtr Ptr)
 
735
static void
 
736
PS_PrintPolygon (PolygonTypePtr Ptr)
726
737
{
727
 
        int i = 0;
 
738
  int i = 0;
728
739
 
729
 
        POLYGONPOINT_LOOP(Ptr,
730
 
                {
731
 
                        if (i++ % 9 == 8)
732
 
                                fputc('\n', PS_Flags.FP);
733
 
                        fprintf(PS_Flags.FP, "%i %i ",
734
 
                                (int) point->X,
735
 
                                (int) point->Y);
736
 
                }
737
 
        );
738
 
        fprintf(PS_Flags.FP, "%d PO\n", Ptr->PointN);
 
740
  POLYGONPOINT_LOOP (Ptr);
 
741
  {
 
742
    if (i++ % 9 == 8)
 
743
      fputc ('\n', PS_Flags.FP);
 
744
    fprintf (PS_Flags.FP, "%i %i ", (int) point->X, (int) point->Y);
 
745
  }
 
746
  END_LOOP;
 
747
  fprintf (PS_Flags.FP, "%d PO\n", Ptr->PointN);
739
748
}
740
749
 
741
750
/* ----------------------------------------------------------------------
744
753
 * that DrawLine() and DrawRectangle() are replaced by their corresponding
745
754
 * printing routines
746
755
 */
747
 
static void PS_PrintTextLowLevel(TextTypePtr Text)
 
756
static void
 
757
PS_PrintTextLowLevel (TextTypePtr Text)
748
758
{
749
 
        Position                x = 0,
750
 
                                width;
751
 
        unsigned char   *string = (unsigned char *) Text->TextString;
752
 
        Cardinal                n;
753
 
        FontTypePtr             font = &PCB->Font;
754
 
 
755
 
                /* get the center of the text for mirroring */
756
 
        width = Text->Direction & 0x01 ? 
757
 
                Text->BoundingBox.Y2 -Text->BoundingBox.Y1 :
758
 
                Text->BoundingBox.X2 -Text->BoundingBox.X1;
759
 
        while (string && *string)
760
 
        {
761
 
                        /* draw lines if symbol is valid and data is present */
762
 
                if (*string <= MAX_FONTPOSITION && font->Symbol[*string].Valid)
763
 
                {
764
 
                        LineTypePtr     line = font->Symbol[*string].Line;
765
 
                        LineType        newline;
766
 
 
767
 
                        for (n = font->Symbol[*string].LineN; n; n--, line++)
768
 
                        {
769
 
                                        /* create one line, scale, move, rotate and swap it */
770
 
                                newline = *line;
771
 
                                newline.Point1.X = (newline.Point1.X +x) *Text->Scale /100;
772
 
                                newline.Point1.Y = newline.Point1.Y      *Text->Scale /100;
773
 
                                newline.Point2.X = (newline.Point2.X +x) *Text->Scale /100;
774
 
                                newline.Point2.Y = newline.Point2.Y      *Text->Scale /100;
775
 
                                newline.Thickness = newline.Thickness *Text->Scale /100;
776
 
 
777
 
                                RotateLineLowLevel(&newline, 0, 0, Text->Direction);
778
 
 
779
 
                                        /* the labels of SMD objects on the bottom
780
 
                                         * side haven't been swapped yet, only their offset
781
 
                                         */
782
 
                                if (TEST_FLAG(ONSOLDERFLAG, Text))
783
 
                                {
784
 
                                        newline.Point1.X = SWAP_SIGN_X(newline.Point1.X);
785
 
                                        newline.Point1.Y = SWAP_SIGN_Y(newline.Point1.Y);
786
 
                                        newline.Point2.X = SWAP_SIGN_X(newline.Point2.X);
787
 
                                        newline.Point2.Y = SWAP_SIGN_Y(newline.Point2.Y);
788
 
                                }
789
 
                                        /* add offset and draw line */
790
 
                                newline.Point1.X += Text->X;
791
 
                                newline.Point1.Y += Text->Y;
792
 
                                newline.Point2.X += Text->X;
793
 
                                newline.Point2.Y += Text->Y;
794
 
                                PS_PrintLine(&newline, False);
795
 
                        }
796
 
 
797
 
                                /* move on to next cursor position */
798
 
                        x += (font->Symbol[*string].Width +font->Symbol[*string].Delta);
799
 
                }
800
 
                else
801
 
                {
802
 
                                /* the default symbol is a filled box */
803
 
                        BoxType         defaultsymbol = PCB->Font.DefaultSymbol;
804
 
                        Position        size = (defaultsymbol.X2 -defaultsymbol.X1) *6/5;
805
 
 
806
 
                        defaultsymbol.X1 = (defaultsymbol.X1 +x) *Text->Scale /100;
807
 
                        defaultsymbol.Y1 = defaultsymbol.Y1      *Text->Scale /100;
808
 
                        defaultsymbol.X2 = (defaultsymbol.X2 +x) *Text->Scale /100;
809
 
                        defaultsymbol.Y2 = defaultsymbol.Y2      *Text->Scale /100;
810
 
 
811
 
                        RotateBoxLowLevel(&defaultsymbol, 0, 0, Text->Direction);
812
 
 
813
 
                                /* add offset and draw box */
814
 
                        defaultsymbol.X1 += Text->X;
815
 
                        defaultsymbol.Y1 += Text->Y;
816
 
                        defaultsymbol.X2 += Text->X;
817
 
                        defaultsymbol.Y2 += Text->Y;
818
 
                        fprintf(PS_Flags.FP, "%d %d %d %d B\n",
819
 
                                (int) defaultsymbol.X1,
820
 
                                (int) defaultsymbol.Y1,
821
 
                                (int) defaultsymbol.X2,
822
 
                                (int) defaultsymbol.Y2);
823
 
 
824
 
                                /* move on to next cursor position */
825
 
                        x += size;
826
 
                }
827
 
                string++;
828
 
        }
 
759
  LocationType x = 0, width;
 
760
  unsigned char *string = (unsigned char *) Text->TextString;
 
761
  Cardinal n;
 
762
  FontTypePtr font = &PCB->Font;
 
763
 
 
764
  /* get the center of the text for mirroring */
 
765
  width = Text->Direction & 0x01 ?
 
766
    Text->BoundingBox.Y2 - Text->BoundingBox.Y1 :
 
767
    Text->BoundingBox.X2 - Text->BoundingBox.X1;
 
768
  while (string && *string)
 
769
    {
 
770
      /* draw lines if symbol is valid and data is present */
 
771
      if (*string <= MAX_FONTPOSITION && font->Symbol[*string].Valid)
 
772
        {
 
773
          LineTypePtr line = font->Symbol[*string].Line;
 
774
          LineType newline;
 
775
 
 
776
          for (n = font->Symbol[*string].LineN; n; n--, line++)
 
777
            {
 
778
              /* create one line, scale, move, rotate and swap it */
 
779
              newline = *line;
 
780
              newline.Point1.X = (newline.Point1.X + x) * Text->Scale / 100;
 
781
              newline.Point1.Y = newline.Point1.Y * Text->Scale / 100;
 
782
              newline.Point2.X = (newline.Point2.X + x) * Text->Scale / 100;
 
783
              newline.Point2.Y = newline.Point2.Y * Text->Scale / 100;
 
784
              newline.Thickness = newline.Thickness * Text->Scale / 200;
 
785
              if (newline.Thickness < 8)
 
786
                newline.Thickness = 8;
 
787
 
 
788
              RotateLineLowLevel (&newline, 0, 0, Text->Direction);
 
789
 
 
790
              /* the labels of SMD objects on the bottom
 
791
               * side haven't been swapped yet, only their offset
 
792
               */
 
793
              if (TEST_FLAG (ONSOLDERFLAG, Text))
 
794
                {
 
795
                  newline.Point1.X = SWAP_SIGN_X (newline.Point1.X);
 
796
                  newline.Point1.Y = SWAP_SIGN_Y (newline.Point1.Y);
 
797
                  newline.Point2.X = SWAP_SIGN_X (newline.Point2.X);
 
798
                  newline.Point2.Y = SWAP_SIGN_Y (newline.Point2.Y);
 
799
                }
 
800
              /* add offset and draw line */
 
801
              newline.Point1.X += Text->X;
 
802
              newline.Point1.Y += Text->Y;
 
803
              newline.Point2.X += Text->X;
 
804
              newline.Point2.Y += Text->Y;
 
805
              PS_PrintLine (&newline, False);
 
806
            }
 
807
 
 
808
          /* move on to next cursor position */
 
809
          x += (font->Symbol[*string].Width + font->Symbol[*string].Delta);
 
810
        }
 
811
      else
 
812
        {
 
813
          /* the default symbol is a filled box */
 
814
          BoxType defaultsymbol = PCB->Font.DefaultSymbol;
 
815
          LocationType size = (defaultsymbol.X2 - defaultsymbol.X1) * 6 / 5;
 
816
 
 
817
          defaultsymbol.X1 = (defaultsymbol.X1 + x) * Text->Scale / 100;
 
818
          defaultsymbol.Y1 = defaultsymbol.Y1 * Text->Scale / 100;
 
819
          defaultsymbol.X2 = (defaultsymbol.X2 + x) * Text->Scale / 100;
 
820
          defaultsymbol.Y2 = defaultsymbol.Y2 * Text->Scale / 100;
 
821
 
 
822
          RotateBoxLowLevel (&defaultsymbol, 0, 0, Text->Direction);
 
823
 
 
824
          /* add offset and draw box */
 
825
          defaultsymbol.X1 += Text->X;
 
826
          defaultsymbol.Y1 += Text->Y;
 
827
          defaultsymbol.X2 += Text->X;
 
828
          defaultsymbol.Y2 += Text->Y;
 
829
          fprintf (PS_Flags.FP, "%d %d %d %d B\n",
 
830
                   (int) defaultsymbol.X1,
 
831
                   (int) defaultsymbol.Y1,
 
832
                   (int) defaultsymbol.X2, (int) defaultsymbol.Y2);
 
833
 
 
834
          /* move on to next cursor position */
 
835
          x += size;
 
836
        }
 
837
      string++;
 
838
    }
829
839
}
830
840
 
831
841
/* ----------------------------------------------------------------------
833
843
 * Albert John FitzPatrick III <ajf_nylorac@acm.org>
834
844
 * see ../CHANGES for details
835
845
 */
836
 
static void PS_PrintText(TextTypePtr Text)
 
846
static void
 
847
PS_PrintText (TextTypePtr Text)
837
848
{
838
 
        PS_PrintTextLowLevel(Text);
 
849
  PS_PrintTextLowLevel (Text);
839
850
}
840
851
 
841
852
/* ----------------------------------------------------------------------
842
853
 * prints package outline
843
854
 */
844
 
static void PS_PrintElementPackage(ElementTypePtr Element)
 
855
static void
 
856
PS_PrintElementPackage (ElementTypePtr Element)
845
857
{
846
 
        ELEMENTLINE_LOOP(Element, PS_PrintLine(line, False););
847
 
        ARC_LOOP(Element, 
848
 
                fprintf(PS_Flags.FP, "%d %d %d %d %d %d %d A\n",
849
 
                        (int) arc->X,
850
 
                        (int) arc->Y,
851
 
                        (int) arc->Width,
852
 
                        (int) arc->Height,
853
 
                        (int) arc->Thickness,
854
 
                        arc->StartAngle,
855
 
                        arc->Delta);
856
 
        );
857
 
        if (!TEST_FLAG(HIDENAMEFLAG, Element))
858
 
                PS_PrintTextLowLevel(&ELEMENT_TEXT(PCB, Element));
 
858
  ELEMENTLINE_LOOP (Element);
 
859
  {
 
860
    PS_PrintLine (line, False);
 
861
  }
 
862
  END_LOOP;
 
863
  ARC_LOOP (Element);
 
864
  {
 
865
    fprintf (PS_Flags.FP, "%d %d %d %d %d %ld %ld A\n",
 
866
             (int) arc->X,
 
867
             (int) arc->Y,
 
868
             (int) arc->Width,
 
869
             (int) arc->Height,
 
870
             (int) arc->Thickness, arc->StartAngle, arc->Delta);
 
871
  }
 
872
  END_LOOP;
 
873
  if (!TEST_FLAG (HIDENAMEFLAG, Element))
 
874
    PS_PrintTextLowLevel (&ELEMENT_TEXT (PCB, Element));
859
875
}
860
876
 
861
877
/* ----------------------------------------------------------------------
862
878
 * prints a pad
863
879
 */
864
 
static void PS_PrintPad(PadTypePtr Pad, int mode)
 
880
static void
 
881
PS_PrintPad (PadTypePtr Pad, int mode)
865
882
{
866
 
        Dimension scrunch = 0;
867
 
 
868
 
        switch (mode)
869
 
        {
870
 
                case 0:
871
 
                case 3:
872
 
                        scrunch = Pad->Thickness;
873
 
                        break;
874
 
                case 1:
875
 
                        scrunch = (Pad->Thickness + Pad->Clearance);
876
 
                        break;
877
 
                case 2:
878
 
                        scrunch = Pad->Mask;
879
 
                        break;
880
 
        }
881
 
                        
882
 
        if (TEST_FLAG(SQUAREFLAG, Pad))
883
 
        {
884
 
                scrunch /= 2;
885
 
        fprintf(PS_Flags.FP, "%d %d %d %d %s\n",
886
 
                ((Pad->Point1.X > Pad->Point2.X) ? Pad->Point2.X  : Pad->Point1.X) - scrunch,
887
 
                ((Pad->Point1.Y > Pad->Point2.Y) ? Pad->Point2.Y  : Pad->Point1.Y) - scrunch,
888
 
                ((Pad->Point1.X > Pad->Point2.X) ? Pad->Point1.X  : Pad->Point2.X) + scrunch,
889
 
                ((Pad->Point1.Y > Pad->Point2.Y) ? Pad->Point1.Y  : Pad->Point2.Y) + scrunch,
890
 
                (mode == 1 || mode == 2) ? "CLRB" : "B");
891
 
        }
892
 
        else
893
 
        fprintf(PS_Flags.FP, "%d %d %d %d %d %s\n",
894
 
                (int) Pad->Point1.X,
895
 
                (int) Pad->Point1.Y,
896
 
                (int) Pad->Point2.X,
897
 
                (int) Pad->Point2.Y,
898
 
                (int) scrunch,
899
 
                (mode == 1 || mode == 2) ? "CLRPA" : "PA");
 
883
  Dimension scrunch = 0;
 
884
 
 
885
  switch (mode)
 
886
    {
 
887
    case 0:
 
888
    case 3:
 
889
      scrunch = Pad->Thickness;
 
890
      break;
 
891
    case 1:
 
892
      scrunch = (Pad->Thickness + Pad->Clearance);
 
893
      break;
 
894
    case 2:
 
895
      scrunch = Pad->Mask;
 
896
      break;
 
897
    }
 
898
 
 
899
  if (TEST_FLAG (SQUAREFLAG, Pad))
 
900
    {
 
901
      scrunch /= 2;
 
902
      fprintf (PS_Flags.FP, "%d %d %d %d %s\n",
 
903
               ((Pad->Point1.X > Pad->Point2.X) ? Pad->Point2.X : Pad->
 
904
                Point1.X) - scrunch,
 
905
               ((Pad->Point1.Y > Pad->Point2.Y) ? Pad->Point2.Y : Pad->
 
906
                Point1.Y) - scrunch,
 
907
               ((Pad->Point1.X > Pad->Point2.X) ? Pad->Point1.X : Pad->
 
908
                Point2.X) + scrunch,
 
909
               ((Pad->Point1.Y > Pad->Point2.Y) ? Pad->Point1.Y : Pad->
 
910
                Point2.Y) + scrunch, (mode == 1 || mode == 2) ? "CLRB" : "B");
 
911
    }
 
912
  else
 
913
    fprintf (PS_Flags.FP, "%d %d %d %d %d %s\n",
 
914
             (int) Pad->Point1.X,
 
915
             (int) Pad->Point1.Y,
 
916
             (int) Pad->Point2.X,
 
917
             (int) Pad->Point2.Y,
 
918
             (int) scrunch, (mode == 1 || mode == 2) ? "CLRPA" : "PA");
900
919
}
901
920
 
902
921
/* ----------------------------------------------------------------------
903
922
 * prints a via or pin
904
923
 */
905
 
static void PS_PrintPinOrVia(PinTypePtr Ptr, int mode)
906
 
{
907
 
        int size = 0;
908
 
 
909
 
        switch (mode)
910
 
        {
911
 
                case 0:
912
 
                        size = Ptr->Thickness;
913
 
                        break;
914
 
                case 1:
915
 
                        size = Ptr->Thickness + Ptr->Clearance;
916
 
                        break;
917
 
                case 2:
918
 
                        size = Ptr->Mask;
919
 
                        break;
920
 
        }
921
 
 
922
 
        if (mode)
923
 
                fprintf(PS_Flags.FP, "%d %d %d %s\n",
924
 
                        (int) Ptr->X,
925
 
                        (int) Ptr->Y,
926
 
                        size,
927
 
                        TEST_FLAG(SQUAREFLAG, Ptr) ? "CLRPVSQ" 
928
 
                        : TEST_FLAG(OCTAGONFLAG, Ptr) ? "CLRPV" : "CLRPVR");
929
 
        else
930
 
        {
931
 
                if (TEST_FLAG(USETHERMALFLAG, Ptr))
932
 
                {
933
 
                        int size2 = (size + Ptr->Clearance)/2;
934
 
                        if (!TEST_FLAG(SQUAREFLAG, Ptr))
935
 
                                size2 = (7 * size2) / 10;
936
 
                        fprintf(PS_Flags.FP, "%d %d %d %d %d L\n",
937
 
                                Ptr->X - size2, Ptr->Y - size2,
938
 
                                Ptr->X + size2, Ptr->Y + size2,
939
 
                                Ptr->Clearance/2);
940
 
                        fprintf(PS_Flags.FP, "%d %d %d %d %d L\n",
941
 
                                Ptr->X - size2, Ptr->Y + size2,
942
 
                                Ptr->X + size2, Ptr->Y - size2,
943
 
                                Ptr->Clearance/2);
944
 
                        CLEAR_FLAG(USETHERMALFLAG, Ptr);
945
 
                }
946
 
                fprintf(PS_Flags.FP, "%d %d %d %d %s\n",
947
 
                        (int) Ptr->X,
948
 
                        (int) Ptr->Y,
949
 
                        size,
950
 
                        (int) Ptr->DrillingHole,
951
 
                        TEST_FLAG(SQUAREFLAG, Ptr) ? "PVSQ" 
952
 
                        : TEST_FLAG(OCTAGONFLAG, Ptr) ? "PV" : "PVR");
953
 
        }
954
 
}
955
 
 
956
 
/* ---------------------------------------------------------------------------
957
 
 * draws a filled rectangle for the ground plane
958
 
 */
959
 
static void PS_FilledRectangle(Position X1, Position Y1,
960
 
        Position X2, Position Y2)
961
 
{
962
 
        fprintf(PS_Flags.FP, "%d %d %d %d FILL\n",
963
 
                (int) X1,
964
 
                (int) Y1,
965
 
                (int) X2,
966
 
                (int) Y2);
 
924
static void
 
925
PS_PrintPinOrVia (PinTypePtr Ptr, int mode)
 
926
{
 
927
  int size = 0;
 
928
 
 
929
  switch (mode)
 
930
    {
 
931
    case 0:
 
932
      size = Ptr->Thickness;
 
933
      break;
 
934
    case 1:
 
935
      size = Ptr->Thickness + Ptr->Clearance;
 
936
      break;
 
937
    case 2:
 
938
      size = Ptr->Mask;
 
939
      if (size == 0)
 
940
        return;
 
941
      break;
 
942
    }
 
943
 
 
944
  if (mode)
 
945
    fprintf (PS_Flags.FP, "%d %d %d %s\n",
 
946
             (int) Ptr->X,
 
947
             (int) Ptr->Y,
 
948
             size,
 
949
             TEST_FLAG (SQUAREFLAG, Ptr) ? "CLRPVSQ"
 
950
             : TEST_FLAG (OCTAGONFLAG, Ptr) ? "CLRPV" : "CLRPVR");
 
951
  else
 
952
    {
 
953
      if (TEST_FLAG (USETHERMALFLAG, Ptr))
 
954
        {
 
955
          int size2 = (size + Ptr->Clearance) / 2;
 
956
          int finger = (Ptr->Thickness - Ptr->DrillingHole) * PCB->ThermScale;
 
957
 
 
958
          if (!TEST_FLAG (SQUAREFLAG, Ptr))
 
959
            size2 = (7 * size2) / 10;
 
960
          fprintf (PS_Flags.FP, "%d %d %d %d %d L\n",
 
961
                   Ptr->X - size2, Ptr->Y - size2,
 
962
                   Ptr->X + size2, Ptr->Y + size2, finger);
 
963
          fprintf (PS_Flags.FP, "%d %d %d %d %d L\n",
 
964
                   Ptr->X - size2, Ptr->Y + size2,
 
965
                   Ptr->X + size2, Ptr->Y - size2, finger);
 
966
          CLEAR_FLAG (USETHERMALFLAG, Ptr);
 
967
        }
 
968
      fprintf (PS_Flags.FP, "%d %d %d %d %s\n",
 
969
               (int) Ptr->X,
 
970
               (int) Ptr->Y,
 
971
               size,
 
972
               (int) Ptr->DrillingHole,
 
973
               TEST_FLAG (SQUAREFLAG, Ptr) ? "PVSQ"
 
974
               : TEST_FLAG (OCTAGONFLAG, Ptr) ? "PV" : "PVR");
 
975
    }
967
976
}
968
977
 
969
978
/* ---------------------------------------------------------------------------
970
979
 * draw the outlines of a layout;
971
980
 * the upper/left and lower/right corner are passed
972
981
 */
973
 
static void PS_Outline(Position X1, Position Y1,
974
 
        Position X2, Position Y2)
 
982
static void
 
983
PS_Outline (LocationType X1, LocationType Y1, LocationType X2, LocationType Y2)
975
984
{
976
 
        fprintf(PS_Flags.FP, "%d %d %d %d Outline\n",
977
 
                (int) X1,
978
 
                (int) Y1,
979
 
                (int) X2,
980
 
                (int) Y2);
 
985
  fprintf (PS_Flags.FP, "%d %d %d %d Outline\n",
 
986
           (int) X1, (int) Y1, (int) X2, (int) Y2);
981
987
}
982
988
 
983
989
/* ---------------------------------------------------------------------------
984
990
 * draw the alignment targets;
985
991
 * the upper/left and lower/right corner are passed
986
992
 */
987
 
static void PS_Alignment(Position X1, Position Y1,
988
 
        Position X2, Position Y2)
 
993
static void
 
994
PS_Alignment (LocationType X1, LocationType Y1, LocationType X2, LocationType Y2)
989
995
{
990
 
        fprintf(PS_Flags.FP, "%d %d %d %d %d Alignment\n",
991
 
                (int) X1,
992
 
                (int) Y1,
993
 
                (int) X2,
994
 
                (int) Y2,
995
 
                (int) Settings.AlignmentDistance);
 
996
  fprintf (PS_Flags.FP, "%d %d %d %d %d Alignment\n",
 
997
           (int) X1,
 
998
           (int) Y1, (int) X2, (int) Y2, (int) Settings.AlignmentDistance);
996
999
}
997
1000
 
998
1001
/* ----------------------------------------------------------------------
999
1002
 * prints a via or pin
1000
1003
 */
1001
 
static void PS_DrillHelper(PinTypePtr Ptr, int unused)
 
1004
static void
 
1005
PS_DrillHelper (PinTypePtr Ptr, int unused)
1002
1006
{
1003
 
        if (Ptr->DrillingHole >= 4*MIN_PINORVIAHOLE)
1004
 
                fprintf(PS_Flags.FP, "%d %d %d %d DH\n",
1005
 
                        (int) Ptr->X,
1006
 
                        (int) Ptr->Y,
1007
 
                        (int) 2*MIN_PINORVIAHOLE,
1008
 
                        (int) MIN_PINORVIAHOLE);
 
1007
  if (Ptr->DrillingHole >= 4 * MIN_PINORVIAHOLE)
 
1008
    fprintf (PS_Flags.FP, "%d %d %d %d DH\n",
 
1009
             (int) Ptr->X,
 
1010
             (int) Ptr->Y,
 
1011
             (int) 2 * MIN_PINORVIAHOLE, (int) MIN_PINORVIAHOLE);
1009
1012
}
1010
1013
 
1011
1014
/* ----------------------------------------------------------------------
1012
 
 * queries color from X11 database and generates PostScript command
1013
 
 * set PostScript identifier to the calculated value or to black by 
1014
 
 * default
 
1015
 * Convert X color to postscript
1015
1016
 */
1016
 
static void PS_SetColor(XColor RGB)
 
1017
static void
 
1018
PS_SetColor (XColor RGB)
1017
1019
{
1018
 
        fprintf(PS_Flags.FP,
1019
 
                "/Color {%.3f %.3f %.3f mysetrgbcolor} def Color\n",
1020
 
                (float) RGB.red /65535.0,
1021
 
                (float) RGB.green /65535.0,
1022
 
                (float) RGB.blue /65535.0);
 
1020
  fprintf (PS_Flags.FP,
 
1021
           "/Color {%.3f %.3f %.3f mysetrgbcolor} def Color\n",
 
1022
           (float) RGB.red / 65535.0,
 
1023
           (float) RGB.green / 65535.0, (float) RGB.blue / 65535.0);
1023
1024
}