/* * plotMain.c -- * * This is the central file in the plot module. It contains tables * that define the various styles of plotting that are available, and * also contains central technology-file reading routines. * * ********************************************************************* * * Copyright (C) 1985, 1990 Regents of the University of California. * * * Permission to use, copy, modify, and distribute this * * * software and its documentation for any purpose and without * * * fee is hereby granted, provided that the above copyright * * * notice appear in all copies. The University of California * * * makes no representations about the suitability of this * * * software for any purpose. It is provided "as is" without * * * express or implied warranty. Export of this software outside * * * of the United States of America may require an export license. * * ********************************************************************* */ #ifndef lint static char rcsid[]="$Header: /ufs/repository/magic/plot/plotMain.c,v 1.7 2001/07/24 18:03:43 tim Exp $"; #endif not lint #include #include "misc/magic.h" #include "utils/geometry.h" #include "tiles/tile.h" #include "utils/hash.h" #include "database/database.h" #include "tech/tech.h" #include "utils/malloc.h" #include "plot/plotInt.h" #include "textio/textio.h" #include "utils/utils.h" /* Magic can generate plots in several different ways, e.g. as a * Gremlin file or as a direct raster plot to a Versatec printer. * For each style of plot, there is a subsection of the plot section * of technology files. The tables below define the names of those * subsections, and the procedures to call to handle lines within * those subsections. To add a new style of plot, extend the tables * below and then modify the procedure CmdPlot to actually invoke * the top-level plotting routine. */ static char *plotStyles[] = /* Names of tech subsections. */ { "postscript", "gremlin", "versatec", "pnm", "colorversatec", "pixels", NULL }; static Void (*plotInitProcs[])() = /* Initialization procedures for * each style. */ { PlotPSTechInit, PlotGremlinTechInit, PlotVersTechInit, PlotPNMTechInit, PlotColorVersTechInit, PlotPixTechInit, NULL }; static bool (*plotLineProcs[])() = /* Proc to call for each line in * relevant subsection of tech file. */ { PlotPSTechLine, PlotGremlinTechLine, PlotVersTechLine, PlotPNMTechLine, PlotColorVersTechLine, PlotPixTechLine, NULL }; static Void (*plotFinalProcs[])() = /* Proc to call at end of reading * tech files. */ { NULL, NULL, NULL, NULL, NULL, NULL }; static int plotCurStyle = -1; /* Current style being processed in * technology file. -1 means no * "style" line seen yet. -2 means * skipping to next "style" line. */ bool PlotShowCellNames = TRUE; /* TRUE if cell names and use-ids * should be printed inside cell * bounding boxes; if this is FALSE, * then only the bounding box is * drawn. */ /* * ---------------------------------------------------------------------------- * PlotTechInit -- * * Called once at beginning of technology file read-in to initialize * data structures. * * Results: * None. * * Side effects: * Calls the initialization procedures (if any) for each of the * various styles of plotting. * ---------------------------------------------------------------------------- */ Void PlotTechInit() { int i; PlotRastInit(); plotCurStyle = -1; for (i = 0; plotStyles[i] != NULL; i++) { if (plotInitProcs[i] != NULL) (*(plotInitProcs[i]))(); } } /* * ---------------------------------------------------------------------------- * PlotTechLine -- * * This procedure is invoked by the technology module once for * each line in the "plot" section of the technology file. It * processes "style x" lines directly, to change the current style * of plot information. For other lines, it just passes the lines * onto the procedure for the current style. * * Results: * Returns whatever the handler for the current style returns when * we call it. * * Side effects: * Builds up plot technology information. * ---------------------------------------------------------------------------- */ bool PlotTechLine(sectionName, argc, argv) char *sectionName; /* Name of this section. */ int argc; /* Number of arguments on line. */ char *argv[]; /* Pointers to fields of line. */ { int i; if (strcmp(argv[0], "style") == 0) { if (argc != 2) { TechError("\"style\" lines must have exactly two arguments\n"); return TRUE; } /* Change the style of plot for which information is being read. */ plotCurStyle = -2; for (i = 0; plotStyles[i] != NULL; i++) { if (strcmp(argv[1], plotStyles[i]) == 0) { plotCurStyle = i; break; } } if (plotCurStyle == -2) { TechError("Plot style \"%s\" doesn't exist. Ignoring.\n", argv[1]); } return TRUE; } /* Not a new style. Just farm out this line to the handler for the * current style. */ if (plotCurStyle == -1) { TechError("Must declare a plot style before anything else.\n"); plotCurStyle = -2; return TRUE; } else if (plotCurStyle == -2) return TRUE; if (plotLineProcs[plotCurStyle] == NULL) return TRUE; return (*(plotLineProcs[plotCurStyle]))(sectionName, argc, argv); } /* * ---------------------------------------------------------------------------- * PlotTechFinal -- * * Called once at the end of technology file read-in. * * Results: * None. * * Side effects: * Calls the finalization procedures (if any) for each of the * various style of plotting. * ---------------------------------------------------------------------------- */ Void PlotTechFinal() { int i; plotCurStyle = -1; for (i = 0; plotStyles[i] != NULL; i++) { if (plotFinalProcs[i] != NULL) (*(plotFinalProcs[i]))(); } } /* * ---------------------------------------------------------------------------- * * PlotPrintParams -- * * Print out a list of all the plotting parameters and their * current values. * * Results: * None. * * Side effects: * Stuff gets printed. * * ---------------------------------------------------------------------------- */ void PlotPrintParams() { TxPrintf("General plotting parameters are:\n"); TxPrintf(" showCellNames: %s\n", PlotShowCellNames ? "true" : "false"); TxPrintf("Postscript plotting parameters are:\n"); TxPrintf(" PS_cellIdFont: \"%s\"\n", PlotPSIdFont); TxPrintf(" PS_cellNameFont:\"%s\"\n", PlotPSNameFont); TxPrintf(" PS_labelFont: \"%s\"\n", PlotPSLabelFont); TxPrintf(" PS_cellIdSize: %d\n", PlotPSIdSize); TxPrintf(" PS_cellNameSize:%d\n", PlotPSNameSize); TxPrintf(" PS_labelSize: %d\n", PlotPSLabelSize); TxPrintf(" PS_boundary: %s\n", PlotPSBoundary ? "true" : "false"); TxPrintf(" PS_width: %d (%.3f in)\n", PlotPSWidth, (float)PlotPSWidth / 72); TxPrintf(" PS_height: %d (%.3f in)\n", PlotPSHeight, (float)PlotPSHeight / 72); TxPrintf(" PS_margin: %d (%.3f in)\n", PlotPSMargin, (float)PlotPSMargin / 72); TxPrintf("Versatec plotting parameters are:\n"); TxPrintf(" cellIdFont: \"%s\"\n", PlotVersIdFont); TxPrintf(" cellNameFont: \"%s\"\n", PlotVersNameFont); TxPrintf(" directory: \"%s\"\n", PlotTempDirectory); TxPrintf(" dotsPerInch: %d\n", PlotVersDotsPerInch); TxPrintf(" labelFont: \"%s\"\n", PlotVersLabelFont); TxPrintf(" printer: \"%s\"\n", PlotVersPrinter); TxPrintf(" spoolCommand: \"%s\"\n", PlotVersCommand); TxPrintf(" swathHeight: %d\n", PlotVersSwathHeight); TxPrintf(" width: %d\n", PlotVersWidth); TxPrintf(" color: %s\n", PlotVersColor ? "true" : "false"); TxPrintf("Pixel plotting parameters are:\n"); TxPrintf(" pixheight: %d\n", PlotPixHeight); TxPrintf(" pixwidth: %d\n", PlotPixWidth); TxPrintf("PNM plotting parameters are:\n"); TxPrintf(" pnmmaxmem: %d KB\n", PlotPNMmaxmem); TxPrintf(" pnmbg: (%3d %3d %3d)\n", PlotPNMBGr, PlotPNMBGg, PlotPNMBGb); } /* * ---------------------------------------------------------------------------- * * PlotSetParam -- * * This procedure is called to change the value of one * of the plotting parameters. * * Results: * None. * * Side effects: * Whichever parameter is named by "name" is set to "value". * The interpretation of "value" depends on the parameter. * * ---------------------------------------------------------------------------- */ #define SHOWCELLNAMES 0 #define PSCELLIDFONT 1 #define PSNAMEFONT 2 #define PSLABELFONT 3 #define PSIDSIZE 4 #define PSNAMESIZE 5 #define PSLABELSIZE 6 #define PSBOUNDARY 7 #define PSWIDTH 8 #define PSHEIGHT 9 #define PSMARGIN 10 #define CELLIDFONT 11 #define CELLNAMEFONT 12 #define LABELFONT 13 #define DIRECTORY 14 #define DOTSPERINCH 15 #define PRINTER 16 #define SPOOLCOMMAND 17 #define SWATHHEIGHT 18 #define WIDTH 19 #define COLOR 20 #define PIXWIDTH 21 #define PIXHEIGHT 22 #define PNMMAXMEM 23 #define PNMBGRED 24 #define PNMBGGREEN 25 #define PNMBGBLUE 26 void PlotSetParam(name, value) char *name; /* Name of a parameter. */ char *value; /* New value for the parameter. */ { int indx, i; static char *tfNames[] = { "false", "true", 0 }; static char *paramNames[] = { "showcellnames", "ps_cellidfont", "ps_namefont", "ps_labelfont", "ps_cellidsize", "ps_namesize", "ps_labelsize", "ps_boundary", "ps_width", "ps_height", "ps_margin", "cellidfont", "cellnamefont", "labelfont", "directory", "dotsperinch", "printer", "spoolcommand", "swathheight", "width", "color", "pixwidth", "pixheight", "pnmmaxmem", "pnmbgr", "pnmbgg", "pnmbgb", NULL }; indx = Lookup(name, paramNames); if (indx < 0) { TxError("\"%s\" isn't a valid plot parameter.\n", name); PlotPrintParams(); return; } i = atoi(value); switch (indx) { case SHOWCELLNAMES: i = Lookup(value, tfNames); if (i < 0) { TxError("ShowCellNames can only be \"true\" or \"false\".\n"); return; } PlotShowCellNames = i; break; case PSCELLIDFONT: StrDup(&PlotPSIdFont, value); break; case PSNAMEFONT: StrDup(&PlotPSNameFont, value); break; case PSLABELFONT: StrDup(&PlotPSLabelFont, value); break; case PSIDSIZE: if (!StrIsInt(value) || (i <= 0)) { TxError("PS_cellIdSize must be an integer greater than zero.\n"); return; } else PlotPSIdSize = i; break; case PSNAMESIZE: if (!StrIsInt(value) || (i <= 0)) { TxError("PS_cellNameSize must be an integer greater than zero.\n"); return; } else PlotPSNameSize = i; break; case PSLABELSIZE: if (!StrIsInt(value) || (i <= 0)) { TxError("PS_labelSize must be an integer greater than zero.\n"); return; } else PlotPSLabelSize = i; break; case PSBOUNDARY: i = Lookup(value, tfNames); if (i < 0) { TxError("PS_boundary can only be \"true\" or \"false\".\n"); return; } PlotPSBoundary = i; break; case PSWIDTH: if (!StrIsInt(value) || (i <= 0)) { TxError("PS_Width must be an integer greater than zero.\n"); return; } else PlotPSWidth = i; break; case PSHEIGHT: if (!StrIsInt(value) || (i <= 0)) { TxError("PS_Height must be an integer greater than zero.\n"); return; } else PlotPSHeight = i; break; case PSMARGIN: if (!StrIsInt(value) || (i < 0)) { TxError("PS_Margin must be an integer greater than or equal to zero.\n"); return; } else PlotPSMargin = i; break; case CELLIDFONT: StrDup(&PlotVersIdFont, value); break; case CELLNAMEFONT: StrDup(&PlotVersNameFont, value); break; case LABELFONT: StrDup(&PlotVersLabelFont, value); break; case DIRECTORY: StrDup(&PlotTempDirectory, value); break; case DOTSPERINCH: if (!StrIsInt(value) || (i <= 0)) { TxError("DotsPerInch must be an integer greater than zero.]n"); return; } else PlotVersDotsPerInch = i; break; case PRINTER: StrDup(&PlotVersPrinter, value); break; case COLOR: i = Lookup(value, tfNames); if (i < 0) { TxError("Color can only be \"true\" or \"false\".\n"); return; } PlotVersColor = i; /* color plotting means our scanlines can only be 6848 (856 bytes) long */ PlotVersWidth = i?6848:7040; break; case SPOOLCOMMAND: StrDup(&PlotVersCommand, value); break; case SWATHHEIGHT: if (!StrIsInt(value) || (i <= 0)) { TxError("SwathHeight must be an integer greater than zero.\n"); return; } else PlotVersSwathHeight= i; break; case WIDTH: if (!StrIsInt(value) || (i <= 0)) { TxError("Width must be an integer greater than zero.\n"); return; } else PlotVersWidth = i; break; case PIXWIDTH: if (!StrIsInt(value) || (i <= 0)) { TxError("PixWidth must be an integer greater than zero.\n"); return; } else PlotPixWidth = i; break; case PIXHEIGHT: if (!StrIsInt(value) || (i <= 0)) { TxError("PixHeight must be an integer greater than zero.\n"); return; } else PlotPixHeight = i; break; case PNMMAXMEM: if (!StrIsInt(value) || (i <= 0)) { TxError("pnmmaxmem must be an integer greater than zero.\n"); return; } else PlotPNMmaxmem = i; break; case PNMBGRED: if (!StrIsInt(value) || (i < 0) || (i > 255)) { TxError("pnmbgr must be an integer in [0,255]\n"); return; } else PlotPNMBGr = i; PlotPNMSetBG (); break; case PNMBGGREEN: if (!StrIsInt(value) || (i < 0) || (i > 255)) { TxError("pnmbgg must be an integer in [0,255]\n"); return; } else PlotPNMBGg = i; PlotPNMSetBG (); break; case PNMBGBLUE: if (!StrIsInt(value) || (i < 0) || (i > 255)) { TxError("pnmbgb must be an integer in [0,255]\n"); return; } else PlotPNMBGb = i; PlotPNMSetBG (); break; } }