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