mirror of
https://github.com/RTimothyEdwards/magic.git
synced 2026-08-29 09:30:46 +02:00
Initial commit at Tue Apr 25 08:41:48 EDT 2017 by tim on stravinsky
This commit is contained in:
+649
@@ -0,0 +1,649 @@
|
||||
/*
|
||||
* 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 char *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 char *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 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",
|
||||
#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");
|
||||
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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user