651 lines
16 KiB
C
651 lines
16 KiB
C
/*
|
|
* 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[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/plot/plotMain.c,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $";
|
|
#endif /* not lint */
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#include "utils/magic.h"
|
|
#include "utils/geometry.h"
|
|
#include "tiles/tile.h"
|
|
#include "utils/hash.h"
|
|
#include "database/database.h"
|
|
#include "utils/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.
|
|
*/
|
|
|
|
/* Note (10/8/04): All of the plot styles except PostScript and PNM */
|
|
/* have been removed in the default compilation. However, they should */
|
|
/* remain in the following lists so that magic doesn't complain when */
|
|
/* encountering these styles in the technology file. */
|
|
|
|
static const char * const plotStyles[] = /* Names of tech subsections. */
|
|
{
|
|
"postscript",
|
|
"pnm",
|
|
"gremlin",
|
|
"versatec",
|
|
"colorversatec",
|
|
"pixels",
|
|
NULL
|
|
};
|
|
|
|
/* These names need to match the plot types enumerated in plotInt.h */
|
|
static const char * const plotTypeNames[] =
|
|
{
|
|
"versatec_color",
|
|
"versatec_bw",
|
|
"hprtl",
|
|
"hpgl2",
|
|
NULL
|
|
};
|
|
|
|
|
|
static void (*plotInitProcs[])() = /* Initialization procedures for
|
|
* each style.
|
|
*/
|
|
{
|
|
PlotPSTechInit,
|
|
PlotPNMTechInit,
|
|
PlotGremlinTechInit,
|
|
PlotVersTechInit,
|
|
PlotColorVersTechInit,
|
|
PlotPixTechInit,
|
|
NULL
|
|
};
|
|
|
|
static bool (*plotLineProcs[])() = /* Proc to call for each line in
|
|
* relevant subsection of tech file.
|
|
*/
|
|
{
|
|
PlotPSTechLine,
|
|
PlotPNMTechLine,
|
|
PlotGremlinTechLine,
|
|
PlotVersTechLine,
|
|
PlotColorVersTechLine,
|
|
PlotPixTechLine,
|
|
NULL
|
|
};
|
|
|
|
static void (*plotFinalProcs[])() = /* Proc to call at end of reading
|
|
* tech files.
|
|
*/
|
|
{
|
|
NULL,
|
|
PlotPNMTechFinal,
|
|
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("");
|
|
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("");
|
|
TxPrintf("PNM plotting parameters are:\n");
|
|
TxPrintf(" pnmmaxmem: %d KB\n", PlotPNMmaxmem);
|
|
TxPrintf(" pnmdownsample: %d\n", PlotPNMdownsample);
|
|
TxPrintf(" pnmbackground: %d\n", PlotPNMBG);
|
|
|
|
#ifdef VERSATEC
|
|
TxPrintf(" pnmplotRTL: %s\n", PlotPNMRTL ? "true" : "false");
|
|
TxPrintf("");
|
|
TxPrintf("HP/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(" plotType: %s\n", plotTypeNames[PlotVersPlotType]);
|
|
#endif
|
|
#ifdef LLNL
|
|
TxPrintf("");
|
|
TxPrintf("Pixel plotting parameters are:\n");
|
|
TxPrintf(" pixheight: %d\n", PlotPixHeight);
|
|
TxPrintf(" pixwidth: %d\n", PlotPixWidth);
|
|
#endif /* LLNL */
|
|
}
|
|
|
|
/*
|
|
* ----------------------------------------------------------------------------
|
|
*
|
|
* 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.
|
|
*
|
|
* ----------------------------------------------------------------------------
|
|
*/
|
|
|
|
typedef enum {
|
|
SHOWCELLNAMES=0,
|
|
PSCELLIDFONT,
|
|
PSNAMEFONT,
|
|
PSLABELFONT,
|
|
PSIDSIZE,
|
|
PSNAMESIZE,
|
|
PSLABELSIZE,
|
|
PSBOUNDARY,
|
|
PSWIDTH,
|
|
PSHEIGHT,
|
|
PSMARGIN,
|
|
#ifdef VERSATEC
|
|
CELLIDFONT,
|
|
CELLNAMEFONT,
|
|
LABELFONT,
|
|
DIRECTORY,
|
|
DOTSPERINCH,
|
|
PRINTER,
|
|
SPOOLCOMMAND,
|
|
SWATHHEIGHT,
|
|
WIDTH,
|
|
PLOTTYPE,
|
|
PNMRTL,
|
|
#endif
|
|
#ifdef LLNL
|
|
PIXWIDTH,
|
|
PIXHEIGHT,
|
|
#endif
|
|
PNMMAXMEM,
|
|
PNMDOWNSAMPLE,
|
|
PNMBACKGROUND
|
|
} PlotParameterOptions;
|
|
|
|
void
|
|
PlotSetParam(name, value)
|
|
char *name; /* Name of a parameter. */
|
|
char *value; /* New value for the parameter. */
|
|
{
|
|
int indx, i;
|
|
static const char * const tfNames[] = { "false", "true", 0 };
|
|
static const char * const paramNames[] =
|
|
{
|
|
"showcellnames",
|
|
"ps_cellidfont",
|
|
"ps_namefont",
|
|
"ps_labelfont",
|
|
"ps_cellidsize",
|
|
"ps_namesize",
|
|
"ps_labelsize",
|
|
"ps_boundary",
|
|
"ps_width",
|
|
"ps_height",
|
|
"ps_margin",
|
|
#ifdef VERSATEC
|
|
"cellidfont",
|
|
"cellnamefont",
|
|
"labelfont",
|
|
"directory",
|
|
"dotsperinch",
|
|
"printer",
|
|
"spoolcommand",
|
|
"swathheight",
|
|
"width",
|
|
"plottype",
|
|
"pnmplotRTL", /* PNM output piped through an HP plotter */
|
|
#endif
|
|
#ifdef LLNL
|
|
"pixwidth",
|
|
"pixheight",
|
|
#endif
|
|
"pnmmaxmem",
|
|
"pnmdownsample",
|
|
"pnmbackground",
|
|
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;
|
|
|
|
#ifdef VERSATEC
|
|
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 PLOTTYPE:
|
|
i = Lookup(value, plotTypeNames);
|
|
if (i < 0)
|
|
{
|
|
int j;
|
|
|
|
TxError("%s is not a supported plot type. Plot types are:\n",
|
|
value);
|
|
for (j = 0 ; plotTypeNames[j] != NULL; j++)
|
|
{
|
|
TxError("\t%s\n", plotTypeNames[j]);
|
|
}
|
|
return;
|
|
}
|
|
PlotVersPlotType = i;
|
|
switch(PlotVersPlotType)
|
|
{
|
|
case VERSATEC_COLOR:
|
|
PlotVersDotsPerInch = 215;
|
|
PlotVersWidth = 7904;
|
|
break;
|
|
case VERSATEC_BW:
|
|
PlotVersDotsPerInch = 215;
|
|
PlotVersWidth = 7904;
|
|
break;
|
|
case HPRTL:
|
|
PlotVersDotsPerInch = 316;
|
|
PlotVersWidth = 2400;
|
|
break;
|
|
case HPGL2:
|
|
PlotVersDotsPerInch = 300;
|
|
PlotVersWidth = 10650;
|
|
break;
|
|
}
|
|
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 PNMRTL:
|
|
i = Lookup(value, tfNames);
|
|
if (i < 0)
|
|
{
|
|
TxError("pnmplotRTL can only be \"true\" or \"false\".\n");
|
|
return;
|
|
}
|
|
PlotPNMRTL = i;
|
|
break;
|
|
|
|
#endif /* VERSATEC */
|
|
|
|
#ifdef LLNL
|
|
|
|
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;
|
|
|
|
#endif /* LLNL */
|
|
|
|
case PNMMAXMEM:
|
|
if (!StrIsInt(value) || (i <= 0))
|
|
{
|
|
TxError("pnmmaxmem must be an integer greater than zero.\n");
|
|
return;
|
|
}
|
|
else PlotPNMmaxmem = i;
|
|
break;
|
|
|
|
case PNMDOWNSAMPLE:
|
|
if (!StrIsInt(value) || (i < 0))
|
|
{
|
|
TxError("pnmdownsample must be an integer zero or larger.\n");
|
|
return;
|
|
}
|
|
else PlotPNMdownsample = i;
|
|
break;
|
|
|
|
case PNMBACKGROUND:
|
|
if (!StrIsInt(value) || (i < 0) || (i > 255))
|
|
{
|
|
TxError("pnmbackground must be an integer 0-255.\n");
|
|
return;
|
|
}
|
|
else PlotPNMBG = (unsigned char)i;
|
|
break;
|
|
}
|
|
}
|