6 * PCB, interactive printed circuit board design
7 * Copyright (C) 1994,1995,1996, 2003 Thomas Nau
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 * Contact addresses for paper mail and Email:
24 * Thomas Nau, Schlehenweg 15, 88471 Baustetten, Germany
25 * Thomas.Nau@rz.uni-ulm.de
30 * 10/11/96 11:37 AJF Added support for a Text() driver function.
31 * This was done out of a pressing need to force text to be printed on the
32 * silkscreen layer. Perhaps the design is not the best.
65 #ifdef HAVE_LIBDMALLOC
71 /* ---------------------------------------------------------------------------
72 * prints a FAB drawing.
76 #define TEXT_LINE 15000
77 #define FAB_LINE_W 800
80 fab_line (int x1
, int y1
, int x2
, int y2
)
82 gui
->draw_line (Output
.fgGC
, x1
, y1
, x2
, y2
);
86 fab_circle (int x
, int y
, int r
)
88 gui
->draw_arc (Output
.fgGC
, x
, y
, r
, r
, 0, 180);
89 gui
->draw_arc (Output
.fgGC
, x
, y
, r
, r
, 180, 180);
92 /* align is 0=left, 1=center, 2=right, add 8 for underline */
94 text_at (int x
, int y
, int align
, char *fmt
, ...)
100 FontTypePtr font
= &PCB
->Font
;
102 vsprintf (tmp
, fmt
, a
);
107 t
.Flags
= NoFlags ();
110 for (i
= 0; tmp
[i
]; i
++)
112 (font
->Symbol
[(int) tmp
[i
]].Width
+ font
->Symbol
[(int) tmp
[i
]].Delta
);
113 w
= w
* TEXT_SIZE
/ 100;
114 t
.X
-= w
* (align
& 3) / 2;
117 DrawTextLowLevel (&t
, 0);
121 font
->MaxHeight
* TEXT_SIZE
/
123 t
.Y
+ font
->MaxHeight
* TEXT_SIZE
/ 100 + 1000);
126 /* Y, +, X, circle, square */
128 drill_sym (int idx
, int x
, int y
)
132 int s2
= (size
+ 1) * 1600;
137 fab_line (x
, y
, x
, y
+ s2
);
138 fab_line (x
, y
, x
+ s2
* 13 / 15, y
- s2
/ 2);
139 fab_line (x
, y
, x
- s2
* 13 / 15, y
- s2
/ 2);
140 for (i
= 1; i
<= size
; i
++)
141 fab_circle (x
, y
, i
* 1600);
145 fab_line (x
, y
- s2
, x
, y
+ s2
);
146 fab_line (x
- s2
, y
, x
+ s2
, y
);
147 for (i
= 1; i
<= size
; i
++)
149 fab_line (x
- i
* 1600, y
- i
* 1600, x
+ i
* 1600, y
- i
* 1600);
150 fab_line (x
- i
* 1600, y
- i
* 1600, x
- i
* 1600, y
+ i
* 1600);
151 fab_line (x
- i
* 1600, y
+ i
* 1600, x
+ i
* 1600, y
+ i
* 1600);
152 fab_line (x
+ i
* 1600, y
- i
* 1600, x
+ i
* 1600, y
+ i
* 1600);
156 fab_line (x
- s2
* 3 / 4, y
- s2
* 3 / 4, x
+ s2
* 3 / 4,
158 fab_line (x
- s2
* 3 / 4, y
+ s2
* 3 / 4, x
+ s2
* 3 / 4,
160 for (i
= 1; i
<= size
; i
++)
162 fab_line (x
- i
* 1600, y
- i
* 1600, x
+ i
* 1600, y
- i
* 1600);
163 fab_line (x
- i
* 1600, y
- i
* 1600, x
- i
* 1600, y
+ i
* 1600);
164 fab_line (x
- i
* 1600, y
+ i
* 1600, x
+ i
* 1600, y
+ i
* 1600);
165 fab_line (x
+ i
* 1600, y
- i
* 1600, x
+ i
* 1600, y
+ i
* 1600);
168 case 3: /* circle */ ;
169 for (i
= 0; i
<= size
; i
++)
170 fab_circle (x
, y
, (i
+ 1) * 1600 - 800);
173 for (i
= 1; i
<= size
+ 1; i
++)
175 fab_line (x
- i
* 1600, y
- i
* 1600, x
+ i
* 1600, y
- i
* 1600);
176 fab_line (x
- i
* 1600, y
- i
* 1600, x
- i
* 1600, y
+ i
* 1600);
177 fab_line (x
- i
* 1600, y
+ i
* 1600, x
+ i
* 1600, y
+ i
* 1600);
178 fab_line (x
+ i
* 1600, y
- i
* 1600, x
+ i
* 1600, y
+ i
* 1600);
185 count_drill_lines (DrillInfoTypePtr AllDrills
)
188 for (n
= AllDrills
->DrillN
- 1; n
>= 0; n
--)
190 DrillTypePtr drill
= &(AllDrills
->Drill
[n
]);
191 if (drill
->PinCount
+ drill
->ViaCount
> drill
->UnplatedCount
)
193 if (drill
->UnplatedCount
)
201 PrintFab_overhang (void)
203 DrillInfoTypePtr AllDrills
= GetDrillInfo (PCB
->Data
);
204 int ds
= count_drill_lines (AllDrills
);
207 return (ds
+ 2) * TEXT_LINE
;
214 DrillInfoTypePtr AllDrills
;
215 int i
, n
, yoff
, total_drills
= 0, ds
= 0;
218 tmp_pin
.Flags
= NoFlags ();
219 AllDrills
= GetDrillInfo (PCB
->Data
);
220 RoundDrillInfo (AllDrills
, 100);
223 /* count how many drill description lines will be needed */
224 ds
= count_drill_lines (AllDrills
);
227 * When we only have a few drill sizes we need to make sure the
228 * drill table header doesn't fall on top of the board info
233 yoff
-= (4 - ds
) * TEXT_LINE
;
236 gui
->set_line_width (Output
.fgGC
, FAB_LINE_W
);
238 for (n
= AllDrills
->DrillN
- 1; n
>= 0; n
--)
240 int plated_sym
= -1, unplated_sym
= -1;
241 DrillTypePtr drill
= &(AllDrills
->Drill
[n
]);
242 if (drill
->PinCount
+ drill
->ViaCount
> drill
->UnplatedCount
)
244 if (drill
->UnplatedCount
)
246 gui
->set_color (Output
.fgGC
, PCB
->PinColor
);
247 for (i
= 0; i
< drill
->PinN
; i
++)
248 drill_sym (TEST_FLAG (HOLEFLAG
, drill
->Pin
[i
]) ?
249 unplated_sym
: plated_sym
, drill
->Pin
[i
]->X
,
251 if (plated_sym
!= -1)
253 drill_sym (plated_sym
, 100 * TEXT_SIZE
, yoff
+ 100 * TEXT_SIZE
/ 4);
254 text_at (135000, yoff
, 200, "YES");
255 text_at (98000, yoff
, 200, "%d",
256 drill
->PinCount
+ drill
->ViaCount
- drill
->UnplatedCount
);
258 if (unplated_sym
!= -1)
261 if (unplated_sym
!= -1)
263 drill_sym (unplated_sym
, 100 * TEXT_SIZE
,
264 yoff
+ 100 * TEXT_SIZE
/ 4);
265 text_at (140000, yoff
, 200, "NO");
266 text_at (98000, yoff
, 200, "%d", drill
->UnplatedCount
);
268 gui
->set_color (Output
.fgGC
, PCB
->ElementColor
);
269 text_at (45000, yoff
, 200, "%0.3f",
270 drill
->DrillSize
/ 100000. + 0.0004);
271 if (plated_sym
!= -1 && unplated_sym
!= -1)
272 text_at (45000, yoff
+ TEXT_LINE
, 200, "%0.3f",
273 drill
->DrillSize
/ 100000. + 0.0004);
275 total_drills
+= drill
->PinCount
;
276 total_drills
+= drill
->ViaCount
;
279 gui
->set_color (Output
.fgGC
, PCB
->ElementColor
);
280 text_at (0, yoff
, 900, "Symbol");
281 text_at (41000, yoff
, 900, "Diam. (Inch)");
282 text_at (95000, yoff
, 900, "Count");
283 text_at (130000, yoff
, 900, "Plated?");
286 "There are %d different drill sizes used in this layout, %d holes total",
287 AllDrills
->DrillN
, total_drills
);
288 /* Create a portable timestamp. */
289 currenttime
= time (NULL
);
291 /* avoid gcc complaints */
292 const char *fmt
= "%c UTC";
293 strftime (utcTime
, sizeof utcTime
, fmt
, gmtime (¤ttime
));
296 for (i
= 0; i
< max_copper_layer
; i
++)
298 LayerType
*l
= LAYER_PTR (i
);
299 if (l
->Name
&& (l
->LineN
|| l
->ArcN
))
301 if (strcmp ("route", l
->Name
) == 0)
303 if (strcmp ("outline", l
->Name
) == 0)
307 if (i
== max_copper_layer
)
309 gui
->set_line_width (Output
.fgGC
, 1000);
310 gui
->draw_line (Output
.fgGC
, 0, 0, PCB
->MaxWidth
, 0);
311 gui
->draw_line (Output
.fgGC
, 0, 0, 0, PCB
->MaxHeight
);
312 gui
->draw_line (Output
.fgGC
, PCB
->MaxWidth
, 0, PCB
->MaxWidth
,
314 gui
->draw_line (Output
.fgGC
, 0, PCB
->MaxHeight
, PCB
->MaxWidth
,
316 /*FPrintOutline (); */
317 gui
->set_line_width (Output
.fgGC
, FAB_LINE_W
);
318 text_at (200000, yoff
, 0,
319 "Maximum Dimensions: %d mils wide, %d mils high",
320 PCB
->MaxWidth
/ 100, PCB
->MaxHeight
/ 100);
321 text_at (PCB
->MaxWidth
/ 2, PCB
->MaxHeight
+ 2000, 1,
322 "Board outline is the centerline of this 10 mil"
323 " rectangle - 0,0 to %d,%d mils",
324 PCB
->MaxWidth
/ 100, PCB
->MaxHeight
/ 100);
328 LayerTypePtr layer
= LAYER_PTR (i
);
329 gui
->set_line_width (Output
.fgGC
, 1000);
332 gui
->draw_line (Output
.fgGC
, line
->Point1
.X
, line
->Point1
.Y
,
333 line
->Point2
.X
, line
->Point2
.Y
);
338 gui
->draw_arc (Output
.fgGC
, arc
->X
, arc
->Y
, arc
->Width
,
339 arc
->Height
, arc
->StartAngle
, arc
->Delta
);
344 DrawTextLowLevel (text
, 0);
347 gui
->set_line_width (Output
.fgGC
, FAB_LINE_W
);
348 text_at (PCB
->MaxWidth
/ 2, PCB
->MaxHeight
+ 2000, 1,
349 "Board outline is the centerline of this path");
352 text_at (200000, yoff
, 0, "Date: %s", utcTime
);
354 text_at (200000, yoff
, 0, "Author: %s", pcb_author ());
356 text_at (200000, yoff
, 0,
357 "Title: %s - Fabrication Drawing", UNKNOWN (PCB
->Name
));