1 /*
2 * plotMain.c --
3 *
4 * This is the central file in the plot module. It contains tables
5 * that define the various styles of plotting that are available, and
6 * also contains central technology-file reading routines.
7 *
8 * *********************************************************************
9 * * Copyright (C) 1985, 1990 Regents of the University of California. *
10 * * Permission to use, copy, modify, and distribute this *
11 * * software and its documentation for any purpose and without *
12 * * fee is hereby granted, provided that the above copyright *
13 * * notice appear in all copies. The University of California *
14 * * makes no representations about the suitability of this *
15 * * software for any purpose. It is provided "as is" without *
16 * * express or implied warranty. Export of this software outside *
17 * * of the United States of America may require an export license. *
18 * *********************************************************************
19 */
20
21 #ifndef lint
22 static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/plot/plotMain.c,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $";
23 #endif /* not lint */
24
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28
29 #include "utils/magic.h"
30 #include "utils/geometry.h"
31 #include "tiles/tile.h"
32 #include "utils/hash.h"
33 #include "database/database.h"
34 #include "utils/tech.h"
35 #include "utils/malloc.h"
36 #include "plot/plotInt.h"
37 #include "textio/textio.h"
38 #include "utils/utils.h"
39
40 /* Magic can generate plots in several different ways, e.g. as a
41 * Gremlin file or as a direct raster plot to a Versatec printer.
42 * For each style of plot, there is a subsection of the plot section
43 * of technology files. The tables below define the names of those
44 * subsections, and the procedures to call to handle lines within
45 * those subsections. To add a new style of plot, extend the tables
46 * below and then modify the procedure CmdPlot to actually invoke
47 * the top-level plotting routine.
48 */
49
50 /* Note (10/8/04): All of the plot styles except PostScript and PNM */
51 /* have been removed in the default compilation. However, they should */
52 /* remain in the following lists so that magic doesn't complain when */
53 /* encountering these styles in the technology file. */
54
55 static char *plotStyles[] = /* Names of tech subsections. */
56 {
57 "postscript",
58 "pnm",
59 "gremlin",
60 "versatec",
61 "colorversatec",
62 "pixels",
63 NULL
64 };
65
66 /* These names need to match the plot types enumerated in plotInt.h */
67 static char *plotTypeNames[] =
68 {
69 "versatec_color",
70 "versatec_bw",
71 "hprtl",
72 "hpgl2",
73 NULL
74 };
75
76
77 static void (*plotInitProcs[])() = /* Initialization procedures for
78 * each style.
79 */
80 {
81 PlotPSTechInit,
82 PlotPNMTechInit,
83 PlotGremlinTechInit,
84 PlotVersTechInit,
85 PlotColorVersTechInit,
86 PlotPixTechInit,
87 NULL
88 };
89
90 static bool (*plotLineProcs[])() = /* Proc to call for each line in
91 * relevant subsection of tech file.
92 */
93 {
94 PlotPSTechLine,
95 PlotPNMTechLine,
96 PlotGremlinTechLine,
97 PlotVersTechLine,
98 PlotColorVersTechLine,
99 PlotPixTechLine,
100 NULL
101 };
102
103 static void (*plotFinalProcs[])() = /* Proc to call at end of reading
104 * tech files.
105 */
106 {
107 NULL,
108 PlotPNMTechFinal,
109 NULL,
110 NULL,
111 NULL,
112 NULL,
113 NULL
114 };
115
116 static int plotCurStyle = -1; /* Current style being processed in
117 * technology file. -1 means no
118 * "style" line seen yet. -2 means
119 * skipping to next "style" line.
120 */
121
122 bool PlotShowCellNames = TRUE; /* TRUE if cell names and use-ids
123 * should be printed inside cell
124 * bounding boxes; if this is FALSE,
125 * then only the bounding box is
126 * drawn.
127 */
128
129
130 /*
131 * ----------------------------------------------------------------------------
132 * PlotTechInit --
133 *
134 * Called once at beginning of technology file read-in to initialize
135 * data structures.
136 *
137 * Results:
138 * None.
139 *
140 * Side effects:
141 * Calls the initialization procedures (if any) for each of the
142 * various styles of plotting.
143 * ----------------------------------------------------------------------------
144 */
145
146 void
PlotTechInit()147 PlotTechInit()
148 {
149 int i;
150
151 PlotRastInit();
152
153 plotCurStyle = -1;
154 for (i = 0; plotStyles[i] != NULL; i++)
155 {
156 if (plotInitProcs[i] != NULL)
157 (*(plotInitProcs[i]))();
158 }
159 }
160
161 /*
162 * ----------------------------------------------------------------------------
163 * PlotTechLine --
164 *
165 * This procedure is invoked by the technology module once for
166 * each line in the "plot" section of the technology file. It
167 * processes "style x" lines directly, to change the current style
168 * of plot information. For other lines, it just passes the lines
169 * onto the procedure for the current style.
170 *
171 * Results:
172 * Returns whatever the handler for the current style returns when
173 * we call it.
174 *
175 * Side effects:
176 * Builds up plot technology information.
177 * ----------------------------------------------------------------------------
178 */
179
180 bool
PlotTechLine(sectionName,argc,argv)181 PlotTechLine(sectionName, argc, argv)
182 char *sectionName; /* Name of this section. */
183 int argc; /* Number of arguments on line. */
184 char *argv[]; /* Pointers to fields of line. */
185 {
186 int i;
187
188 if (strcmp(argv[0], "style") == 0)
189 {
190 if (argc != 2)
191 {
192 TechError("\"style\" lines must have exactly two arguments\n");
193 return TRUE;
194 }
195
196 /* Change the style of plot for which information is being read. */
197
198 plotCurStyle = -2;
199 for (i = 0; plotStyles[i] != NULL; i++)
200 {
201 if (strcmp(argv[1], plotStyles[i]) == 0)
202 {
203 plotCurStyle = i;
204 break;
205 }
206 }
207
208 if (plotCurStyle == -2)
209 {
210 TechError("Plot style \"%s\" doesn't exist. Ignoring.\n",
211 argv[1]);
212 }
213 return TRUE;
214 }
215
216 /* Not a new style. Just farm out this line to the handler for the
217 * current style.
218 */
219
220 if (plotCurStyle == -1)
221 {
222 TechError("Must declare a plot style before anything else.\n");
223 plotCurStyle = -2;
224 return TRUE;
225 }
226 else if (plotCurStyle == -2)
227 return TRUE;
228
229 if (plotLineProcs[plotCurStyle] == NULL)
230 return TRUE;
231 return (*(plotLineProcs[plotCurStyle]))(sectionName, argc, argv);
232 }
233
234 /*
235 * ----------------------------------------------------------------------------
236 * PlotTechFinal --
237 *
238 * Called once at the end of technology file read-in.
239 *
240 * Results:
241 * None.
242 *
243 * Side effects:
244 * Calls the finalization procedures (if any) for each of the
245 * various style of plotting.
246 * ----------------------------------------------------------------------------
247 */
248
249 void
PlotTechFinal()250 PlotTechFinal()
251 {
252 int i;
253
254 plotCurStyle = -1;
255 for (i = 0; plotStyles[i] != NULL; i++)
256 {
257 if (plotFinalProcs[i] != NULL)
258 (*(plotFinalProcs[i]))();
259 }
260 }
261
262 /*
263 * ----------------------------------------------------------------------------
264 *
265 * PlotPrintParams --
266 *
267 * Print out a list of all the plotting parameters and their
268 * current values.
269 *
270 * Results:
271 * None.
272 *
273 * Side effects:
274 * Stuff gets printed.
275 *
276 * ----------------------------------------------------------------------------
277 */
278
279 void
PlotPrintParams()280 PlotPrintParams()
281 {
282 TxPrintf("General plotting parameters are:\n");
283 TxPrintf(" showCellNames: %s\n", PlotShowCellNames ? "true" : "false");
284 TxPrintf("");
285 TxPrintf("Postscript plotting parameters are:\n");
286 TxPrintf(" PS_cellIdFont: \"%s\"\n", PlotPSIdFont);
287 TxPrintf(" PS_cellNameFont:\"%s\"\n", PlotPSNameFont);
288 TxPrintf(" PS_labelFont: \"%s\"\n", PlotPSLabelFont);
289 TxPrintf(" PS_cellIdSize: %d\n", PlotPSIdSize);
290 TxPrintf(" PS_cellNameSize:%d\n", PlotPSNameSize);
291 TxPrintf(" PS_labelSize: %d\n", PlotPSLabelSize);
292 TxPrintf(" PS_boundary: %s\n", PlotPSBoundary ? "true" : "false");
293 TxPrintf(" PS_width: %d (%.3f in)\n", PlotPSWidth,
294 (float)PlotPSWidth / 72);
295 TxPrintf(" PS_height: %d (%.3f in)\n", PlotPSHeight,
296 (float)PlotPSHeight / 72);
297 TxPrintf(" PS_margin: %d (%.3f in)\n", PlotPSMargin,
298 (float)PlotPSMargin / 72);
299
300 TxPrintf("");
301 TxPrintf("PNM plotting parameters are:\n");
302 TxPrintf(" pnmmaxmem: %d KB\n", PlotPNMmaxmem);
303 TxPrintf(" pnmdownsample: %d\n", PlotPNMdownsample);
304 TxPrintf(" pnmbackground: %d\n", PlotPNMBG);
305
306 #ifdef VERSATEC
307 TxPrintf(" pnmplotRTL: %s\n", PlotPNMRTL ? "true" : "false");
308 TxPrintf("");
309 TxPrintf("HP/Versatec plotting parameters are:\n");
310 TxPrintf(" cellIdFont: \"%s\"\n", PlotVersIdFont);
311 TxPrintf(" cellNameFont: \"%s\"\n", PlotVersNameFont);
312 TxPrintf(" directory: \"%s\"\n", PlotTempDirectory);
313 TxPrintf(" dotsPerInch: %d\n", PlotVersDotsPerInch);
314 TxPrintf(" labelFont: \"%s\"\n", PlotVersLabelFont);
315 TxPrintf(" printer: \"%s\"\n", PlotVersPrinter);
316 TxPrintf(" spoolCommand: \"%s\"\n", PlotVersCommand);
317 TxPrintf(" swathHeight: %d\n", PlotVersSwathHeight);
318 TxPrintf(" width: %d\n", PlotVersWidth);
319 TxPrintf(" plotType: %s\n", plotTypeNames[PlotVersPlotType]);
320 #endif
321 #ifdef LLNL
322 TxPrintf("");
323 TxPrintf("Pixel plotting parameters are:\n");
324 TxPrintf(" pixheight: %d\n", PlotPixHeight);
325 TxPrintf(" pixwidth: %d\n", PlotPixWidth);
326 #endif /* LLNL */
327 }
328
329 /*
330 * ----------------------------------------------------------------------------
331 *
332 * PlotSetParam --
333 *
334 * This procedure is called to change the value of one
335 * of the plotting parameters.
336 *
337 * Results:
338 * None.
339 *
340 * Side effects:
341 * Whichever parameter is named by "name" is set to "value".
342 * The interpretation of "value" depends on the parameter.
343 *
344 * ----------------------------------------------------------------------------
345 */
346
347 typedef enum {
348 SHOWCELLNAMES=0,
349 PSCELLIDFONT,
350 PSNAMEFONT,
351 PSLABELFONT,
352 PSIDSIZE,
353 PSNAMESIZE,
354 PSLABELSIZE,
355 PSBOUNDARY,
356 PSWIDTH,
357 PSHEIGHT,
358 PSMARGIN,
359 #ifdef VERSATEC
360 CELLIDFONT,
361 CELLNAMEFONT,
362 LABELFONT,
363 DIRECTORY,
364 DOTSPERINCH,
365 PRINTER,
366 SPOOLCOMMAND,
367 SWATHHEIGHT,
368 WIDTH,
369 PLOTTYPE,
370 PNMRTL,
371 #endif
372 #ifdef LLNL
373 PIXWIDTH,
374 PIXHEIGHT,
375 #endif
376 PNMMAXMEM,
377 PNMDOWNSAMPLE,
378 PNMBACKGROUND
379 } PlotParameterOptions;
380
381 void
PlotSetParam(name,value)382 PlotSetParam(name, value)
383 char *name; /* Name of a parameter. */
384 char *value; /* New value for the parameter. */
385 {
386 int indx, i;
387 static char *tfNames[] = { "false", "true", 0 };
388 static char *paramNames[] =
389 {
390 "showcellnames",
391 "ps_cellidfont",
392 "ps_namefont",
393 "ps_labelfont",
394 "ps_cellidsize",
395 "ps_namesize",
396 "ps_labelsize",
397 "ps_boundary",
398 "ps_width",
399 "ps_height",
400 "ps_margin",
401 #ifdef VERSATEC
402 "cellidfont",
403 "cellnamefont",
404 "labelfont",
405 "directory",
406 "dotsperinch",
407 "printer",
408 "spoolcommand",
409 "swathheight",
410 "width",
411 "plottype",
412 "pnmplotRTL", /* PNM output piped through an HP plotter */
413 #endif
414 #ifdef LLNL
415 "pixwidth",
416 "pixheight",
417 #endif
418 "pnmmaxmem",
419 "pnmdownsample",
420 "pnmbackground",
421 NULL
422 };
423
424 indx = Lookup(name, paramNames);
425 if (indx < 0)
426 {
427 TxError("\"%s\" isn't a valid plot parameter.\n", name);
428 PlotPrintParams();
429 return;
430 }
431
432 i = atoi(value);
433 switch (indx)
434 {
435 case SHOWCELLNAMES:
436 i = Lookup(value, tfNames);
437 if (i < 0)
438 {
439 TxError("ShowCellNames can only be \"true\" or \"false\".\n");
440 return;
441 }
442 PlotShowCellNames = i;
443 break;
444 case PSCELLIDFONT:
445 StrDup(&PlotPSIdFont, value);
446 break;
447 case PSNAMEFONT:
448 StrDup(&PlotPSNameFont, value);
449 break;
450 case PSLABELFONT:
451 StrDup(&PlotPSLabelFont, value);
452 break;
453 case PSIDSIZE:
454 if (!StrIsInt(value) || (i <= 0))
455 {
456 TxError("PS_cellIdSize must be an integer greater than zero.\n");
457 return;
458 }
459 else PlotPSIdSize = i;
460 break;
461 case PSNAMESIZE:
462 if (!StrIsInt(value) || (i <= 0))
463 {
464 TxError("PS_cellNameSize must be an integer greater than zero.\n");
465 return;
466 }
467 else PlotPSNameSize = i;
468 break;
469 case PSLABELSIZE:
470 if (!StrIsInt(value) || (i <= 0))
471 {
472 TxError("PS_labelSize must be an integer greater than zero.\n");
473 return;
474 }
475 else PlotPSLabelSize = i;
476 break;
477 case PSBOUNDARY:
478 i = Lookup(value, tfNames);
479 if (i < 0)
480 {
481 TxError("PS_boundary can only be \"true\" or \"false\".\n");
482 return;
483 }
484 PlotPSBoundary = i;
485 break;
486 case PSWIDTH:
487 if (!StrIsInt(value) || (i <= 0))
488 {
489 TxError("PS_Width must be an integer greater than zero.\n");
490 return;
491 }
492 else PlotPSWidth = i;
493 break;
494 case PSHEIGHT:
495 if (!StrIsInt(value) || (i <= 0))
496 {
497 TxError("PS_Height must be an integer greater than zero.\n");
498 return;
499 }
500 else PlotPSHeight = i;
501 break;
502 case PSMARGIN:
503 if (!StrIsInt(value) || (i < 0))
504 {
505 TxError("PS_Margin must be an integer greater than or equal to zero.\n");
506 return;
507 }
508 else PlotPSMargin = i;
509 break;
510
511 #ifdef VERSATEC
512 case CELLIDFONT:
513 StrDup(&PlotVersIdFont, value);
514 break;
515 case CELLNAMEFONT:
516 StrDup(&PlotVersNameFont, value);
517 break;
518 case LABELFONT:
519 StrDup(&PlotVersLabelFont, value);
520 break;
521 case DIRECTORY:
522 StrDup(&PlotTempDirectory, value);
523 break;
524 case DOTSPERINCH:
525 if (!StrIsInt(value) || (i <= 0))
526 {
527 TxError("DotsPerInch must be an integer greater than zero.\n");
528 return;
529 }
530 else PlotVersDotsPerInch = i;
531 break;
532 case PRINTER:
533 StrDup(&PlotVersPrinter, value);
534 break;
535 case PLOTTYPE:
536 i = Lookup(value, plotTypeNames);
537 if (i < 0)
538 {
539 int j;
540
541 TxError("%s is not a supported plot type. Plot types are:\n",
542 value);
543 for (j = 0 ; plotTypeNames[j] != NULL; j++)
544 {
545 TxError("\t%s\n", plotTypeNames[j]);
546 }
547 return;
548 }
549 PlotVersPlotType = i;
550 switch(PlotVersPlotType)
551 {
552 case VERSATEC_COLOR:
553 PlotVersDotsPerInch = 215;
554 PlotVersWidth = 7904;
555 break;
556 case VERSATEC_BW:
557 PlotVersDotsPerInch = 215;
558 PlotVersWidth = 7904;
559 break;
560 case HPRTL:
561 PlotVersDotsPerInch = 316;
562 PlotVersWidth = 2400;
563 break;
564 case HPGL2:
565 PlotVersDotsPerInch = 300;
566 PlotVersWidth = 10650;
567 break;
568 }
569 break;
570 case SPOOLCOMMAND:
571 StrDup(&PlotVersCommand, value);
572 break;
573 case SWATHHEIGHT:
574 if (!StrIsInt(value) || (i <= 0))
575 {
576 TxError("SwathHeight must be an integer greater than zero.\n");
577 return;
578 }
579 else PlotVersSwathHeight= i;
580 break;
581 case WIDTH:
582 if (!StrIsInt(value) || (i <= 0))
583 {
584 TxError("Width must be an integer greater than zero.\n");
585 return;
586 }
587 else PlotVersWidth = i;
588 break;
589
590 case PNMRTL:
591 i = Lookup(value, tfNames);
592 if (i < 0)
593 {
594 TxError("pnmplotRTL can only be \"true\" or \"false\".\n");
595 return;
596 }
597 PlotPNMRTL = i;
598 break;
599
600 #endif /* VERSATEC */
601
602 #ifdef LLNL
603
604 case PIXWIDTH:
605 if (!StrIsInt(value) || (i <= 0))
606 {
607 TxError("PixWidth must be an integer greater than zero.\n");
608 return;
609 }
610 else PlotPixWidth = i;
611 break;
612 case PIXHEIGHT:
613 if (!StrIsInt(value) || (i <= 0))
614 {
615 TxError("PixHeight must be an integer greater than zero.\n");
616 return;
617 }
618 else PlotPixHeight = i;
619 break;
620
621 #endif /* LLNL */
622
623 case PNMMAXMEM:
624 if (!StrIsInt(value) || (i <= 0))
625 {
626 TxError("pnmmaxmem must be an integer greater than zero.\n");
627 return;
628 }
629 else PlotPNMmaxmem = i;
630 break;
631
632 case PNMDOWNSAMPLE:
633 if (!StrIsInt(value) || (i < 0))
634 {
635 TxError("pnmdownsample must be an integer zero or larger.\n");
636 return;
637 }
638 else PlotPNMdownsample = i;
639 break;
640
641 case PNMBACKGROUND:
642 if (!StrIsInt(value) || (i < 0) || (i > 255))
643 {
644 TxError("pnmbackground must be an integer 0-255.\n");
645 return;
646 }
647 else PlotPNMBG = (unsigned char)i;
648 break;
649 }
650 }
651