tap - technology access package
Tom Laidig
University of California, Berkeley

Include in source files:
    "oct.h" "tap.h"

Link with:
    libtap.a liboct.a libutility.a liberrtrap.a libmm.a libport.a -lm

NOTES:
    Most of the routines in this package are declared void.  If an error
    occurs, the appropriate error handler will be called through the
    `errtrap' package.  No routine ever returns a null pointer on error.

/*
 *	General definitions
 */

char *tapRootDirectory(dirName)
char *dirName;

	If `dirName' is non-null, sets the root directory of the
	technology tree to `dirName'; else does nothing.  In any case,
	it returns the new root directory name.  The initial root
	directory is a compile-time constant within tap, and is
	available from `tapGetDefaultRoot' below.  It is recommended
	that every program that uses tap provide a means for overriding
	the default (a `-T' command-line option is suggested).  The
	returned string should not be altered or freed by the user.

char *tapGetDefaultRoot()

	Returns the default (initial) root directory, which is
	"CADROOT/lib/technology" at this writing.  The returned string
	should not be altered or freed by the user.

char *tapGetDirectory(objPtr)
octObject *objPtr;

	Returns the name of the directory where technology-related
	information is stored for the technology relevant to the oct
	object pointed to by `objPtr'.  This can be any kind of object,
	provided its facet has the necessary properties to define what
	technology it uses.  The returned string is dynamically
	allocated, and the user is responsible for freeing it when it is
	no longer needed.

int tapIsLayerDefined(objPtr, name)
octObject *objPtr;
char *name;

	Determines if a layer whose name is `name' exists in the
	technology relevant to the oct object pointed to by `objPtr'.
	Returns non-zero if the layer exists; zero if it doesn't.

/*
 *	The following calls relate to ``palettes'', which are cells
 *	instantiated in a technology facet.  These are often used to
 *	hold a library of cells, such as primitive connectors or
 *	transistors, but a tool can have its own palette to hold any
 *	tool-specific information that is desired.  This is the preferred
 *	place to put default parameters, private cell libraries, etc.
 *
 *	By convention, generic palette names are singular nouns, such as
 *	"mosfet" or "gate", while tool-specific palettes have the tool
 *	name as a prefix.  The strings TAP_LAYER_PALETTE_NAME and
 *	TAP_CONNECTOR_PALETTE_NAME defined in tap.h are the correct
 *	names for the layer palette (which normally contains a piece of
 *	geometry on each layer) and connector palette (which is searched
 *	by tapGetConnector), respectively.
 */

int tapOpenPalette(objPtr, name, &facet, mode)
octObject *objPtr;
char *name;
octObject facet;
char *mode;

	Opens the palette named `name' associated with the technology
	relevant to the oct object pointed to by `objPtr'.  The palette
	facet is opened with mode `mode', and returned in `facet'.
	Returns non-zero for success; zero if the palette is opened with
	mode=="r" and the palette is not in the technology.  An error is
	raised if the technology can't be found or some error opening
	the palette is encountered.  Opening with mode=="w" or mode="a"
	will create the palette in the technology area if it did not
	exist (if you have permission to do this).

void tapListPalettes(objPtr, &numPalettes, &nameArray)
octObject *objPtr;
int numPalettes;
char **nameArray;

	Gets a list of the names of palettes in the technology relevant
	to the oct object pointed to by `objPtr'.  `nameArray' is set
	to point to an allocated array of strings, and `numPalettes'
	is set to the number of names.  Note that, although `nameArray'
	is allocated and should be freed by the user, the actual
	strings it points to are internal, and should not be freed.
	The string pointers become invalid upon a call to `tapFlushCache'.

/*
 *	The next set of functions relates to technology properties, which
 *	allow storage of miscellaneous information about the technology
 *	as a whole, or about a layer or a set of layers.
 *
 *	The following is a list of currently standardized properties.
 *	There is an array of statically declared `octProp' structures,
 *	one for each of these known properties.  Each preprocessor
 *	definition evaluates to a pointer to one of these structures, so
 *	the program writer can do something like:
 *
 *		tapGetProp(&someObj, TAP_LAMBDA);
 *		/* use TAP_LAMBDA->value.integer */
 *
 *
 *		Properties not associated with layers
 *	  Property Pointer		  Type	  Meaning
 *	TAP_LAMBDA			int	octCoord units per lambda
 *	TAP_COORD_SIZE			real	Meters/octCoord
 *
 *		Properties associated with 1 layer
 *	  Property Pointer		  Type	  Meaning
 *	TAP_LAYER_CLASS			string	"ROUTING", "CONTACT",
 *						    "ANNOTATION", or "OTHER"
 *	TAP_CURRENT_DENSITY		real	amps/meter
 *	TAP_SHEET_RESISTANCE		real	ohms/square
 *	TAP_AREA_CAP_TO_GROUND		real	farads/meter^2
 *	TAP_PERIM_CAP_TO_GROUND		real	farads/meter
 *
 *		Properties associated with 2 layers
 *	  Property Pointer		  Type	  Meaning
 *	TAP_AREA_CAP_TO_LAYER		real	farads/meter^2
 *	TAP_PERIM_CAP_TO_LAYER		real	farads/meter
 */

int tapGetProp(objPtr, propPtr)
octObject *objPtr;
struct octProp *propPtr;

	This function looks for a technology property from the
	technology relevant to the object pointed to by `objPtr', with
	the same name and property type as that in the structure
	pointed to by `propPtr'.  If the property is found, the value
	is placed in `*propPtr' and the function returns a non-zero
	value; otherwise `*propPtr' is left alone and zero is
	returned.  An error is raised if the technology can't be found
	or if a property with the right name and the wrong type is
	found.  For string- and array-valued properties, the string or
	array storage is internal to tap, and becomes invalid upon a
	call to `tapFlushCache'.  It should be copied if it will be
	saved for any time.

void tapSetProp(objPtr, propPtr)
octObject *objPtr;
struct octProp *propPtr;

	The opposite of `tapGetProp'.  It sets a property in the
	technology facet.  An error is raised if the technology can't
	be found.  All data is copied, by tap, so any storage can be
	freed or reused immediately.

int tapGetLyrProp(nLayers, layerList, propPtr)
int nLayers;
tapLayerListElement layerList[];
struct octProp *propPtr;

	This function is like `tapGetProp' except that it gets a layer-
	specific technology property.  A layer property can be
	associated with any number of layers:  for example, a sheet
	resistance property is only associated with one layer, while a
	capacitance property may be associated with two layers.  If
	more than one layer is involved, the order of layers in
	`layerList' is unimportant.  Only the `layer' field of the
	`tapLayerListElement' structure is used here.  An error is
	raised if the technology can't be found, the given layers
	aren't all of the same technology, or if a property with the
	right name and the wrong type is found.

void tapSetLyrProp(nLayers, layerList, propPtr)
int nLayers;
tapLayerListElement layerList[];
struct octProp *propPtr;

	This function is like `tapSetProp' except that it sets a layer-
	specific technology property.

/*
 *	The following routines return design-rule values in oct
 *  coordinates.  They return TAP_NO_RULE if there is no rule in the
 *  technology facet. Tap takes some pains to cache this information so
 *  that repeated calls to these routines are very cheap.
 */

octCoord tapGetMinWidth(lyrPtr)
octObject *lyrPtr;

	Returns the minimum width for geometry on the layer pointed to
	by `lyrPtr'.

void tapSetMinWidth(lyrPtr, width)
octObject *lyrPtr;
octCoord width;

	Sets the minimum width for the layer pointed to by `lyrPtr'.

octCoord tapGetMaxWidth(lyrPtr)
octObject *lyrPtr;

	Returns the maximum width for geometry on the layer pointed to
	by `lyrPtr'.

octCoord tapGetMinSpacing(lyr1Ptr, lyr2Ptr)
octObject *lyr1Ptr, *lyr2Ptr;

	Returns the minimum spacing between geometry on the layer
	pointed to by `lyr1Ptr' and geometry on the layer pointed to by
	`lyr2Ptr' (which may be the same).

octCoord tapGetMinOverlap(lyr1Ptr, lyr2Ptr)
octObject *lyr1Ptr, *lyr2Ptr;

	Returns the minimum overlap of geometry on the layer pointed to
	by `lyr1Ptr' over geometry on the layer pointed to by `lyr2Ptr'.

/*
 *	The following routines concern the display of geometry on each
 *  of the layers defined in the technology.
 */

void tapSetDisplayType(name, chromaticism)
char *name;
int chromaticism;

	Tells tap the name of the type of display you are using (e.g.
	"GPX-II" or "Versatec").  `Chromaticism' is either TAP_COLOR or
	TAP_BW, and allows tap to fall back to a reasonable default set
	of display attributes if the device named by `name' is not
	defined in the technology.  `name' can be a null pointer if you
	don't know the name of the output device type.

void tapGetDisplayInfo(layerPtr, &dispPrio, &nColors, &fill, &border)
octObject *layerPtr;
int dispPrio, nColors, fill, border;

	Gets general display information for the layer pointed to by
	`layerPtr', and returns it into the variables pointed to by the
	other arguments (a null pointer can be passed for any value the
	user doesn't want).  `dispPrio' provides a relative drawing
	order for the layers, with larger values drawing on top of
	smaller ones.  `nColors' is the number of colors defined for
	the layer, which is 0 for monochrome devices.  `fill' and
	`border' will be set to TAP_EMPTY (for no fill/border),
	TAP_STIPPLED (for stippled fill or broken border), or TAP_SOLID
	(for solid fill/border).

void tapGetDisplayColor(layerPtr, index, &red, &green, &blue)
octObject *layerPtr;
int index;
unsigned short red, green, blue;

	Gets the RGB values of the `index'th color defined for the
	layer pointed to by `layerPtr'.  It is an error for `index' to
	by less than 0 or not less than the `nColors' value obtained
	from tapGetDisplayInfo.  The RGB values are in the range
	[0, TAP_MAX_INTENSITY].  TAP_MAX_INTENSITY is 65535.

void tapGetDisplayPattern(layerPtr, type, &width, &height, &bitPtr)
octObject *layerPtr;
int type;
int width, height;
char *bitPtr;

	Gets the size (`width' and `height') and bit array of a stipple
	pattern for the layer pointed to by `layerPtr'.  `type' is
	TAP_FILL_PATTERN to get the interior fill pattern and
	TAP_BORDER_PATTERN for the border pattern.  Currently, fill
	patterns have the same width and height, and border patterns
	have a height of 1 (the width in this case runs along the
	border).  `bitPtr' is set to point to a NUL-terminated string
	with a length of width*height.  It contains `1' and `0'
	characters to indicate the bit pattern in left-to-right,
	top-to-bottom order.  The user should not modify or free this
	string.

void tapGetDisplayStrokes(layerPtr, &count, &strokePtr)
octbject *layerPtr;
int count;
tapStroke *strokePtr;

/* defined in tap.h */
typedef struct tapStroke {
    octCoord angle;
    int spacing;
} tapStroke;

	Interprets the fill pattern for the layer pointed to by `layerPtr'
	as 0 or more sets of evenly-spaced parallel lines.  It returns
	the number of such sets in `count', and a pointer to an array
	of their descriptions in `strokePtr'.  The `angle' is in tenths
	of degrees counterclockwise from horizontal, and is in the
	range [0, 1800).  No two `angle's will be the same.  `spacing'
	is the line spacing in multiples of line width, where 1 means
	solid fill.  The user should not modify or free this array.

	Beware:  it is possible for a stippled pattern to have no
	roughly straight lines through it, hence it will have 0 strokes.
	This is not flagged as an error the way it was on earlier
	versions of tap.

/*
 *	These routines are not expected to be used by most users of tap.
 */

octId tapGetFacetIdFromObj(objPtr)
octObject *objPtr;

	Returns the objectId of the technology facet relevant to the oct
	object pointed to by `objPtr', which can be any kind of object,
	provided its facet has the necessary properties to define what
	technology it uses.

void tapFlushCache()

	Flushes the internal caches kept by tap.  This is necessary if
	you have reason to believe the technology has changed out from
	under you, or if the TECHNOLOGY or VIEWTYPE property of some
	facet has been changed since tap was asked about that facet.

int tapGetConnector(nLayers, layerList, &instance)
int nLayers;
tapLayerListElement layerList[];
octObject instance;

/* defined in tap.h */
typedef struct tapLayerListElement {
    octObject layer;
    octCoord width;
    int direction;
    octCoord angle;
} tapLayerListElement;

	Searches the connector palette for a connector that can be used
	to interconnect the paths on the layers described in
	`layerList'.  Each entry in `layerList' contains the oct layer
	object, the path width, and the direction(s) from which the
	paths must be able to approach the connector.  `direction' is
	calculated by oring together bits for each desired direction
	that paths must be able to approach from.  The four manhattan
	directions are indicated by TAP_LEFT, TAP_TOP, TAP_RIGHT, and
	TAP_BOTTOM (with TAP_HORIZONTAL and TAP_VERTICAL defined for
	bidirectionally symmetric connectors).  An arbitrary angle can
	be specified by oring in TAP_WEIRD_DIR and setting `angle' to be
	the approach angle in tenths of a degree, as in the angles of
	the oct circle object).  `instance' is filled in as an instance
	of this connector, except that the instance name and
	translation are not affected -- only the master information and
	the transform type are set.  Returns non-zero if it was
	successful; zero if no appropriate connector was found.

	Currently, only manhattan connectors are supported.


void tapSetUserConnectorGenerator(funct)
int (*funct)(int nLayers, tapLayerListElement layerList[], octObject *instance);

	If a function is registered with this tap function, when 
	tapGetConnector fails to find a connector in the connector
	palette, the registered function will be called to generate
	a connector.


/*
 *	These routines are used for modifying technology facets.  As such
 *	they should be of interest to very few people.
 */

void tapOpenTechFacet(techName, viewName, &facet, mode)
char *techName, *viewName;
octObject facet;
char *mode;

	Opens the technology facet that describes cells with a
	TECHNOLOGY property of `techName' and a VIEWTYPE property of
	`viewName', and places the opened facet in `facet'.  The `mode'
	argument is passed on directly to the octOpenFacet call.  Tap
	doesn't read and cache any information from this facet, and it
	is the user's responsibility to close the facet again
	afterwards.  (Note:  if the facet was successfully opened for
	writing, tap initializes its TECHNOLOGY property to
	TAP_TECH_PROP_VAL, which tells tap that this facet contains its
	own technology.)

void tapSetDisplayInfo(layerPtr, dispPrio, nColors, fill, border)
octObject *layerPtr;
int dispPrio, nColors, fill, border;

	Sets general display information for the layer pointed to by
	`layerPtr' for the display indicated by a previous call to
	tapSetDisplayType.  `dispPrio', `nColors', `fill', and `border'
	are as described under tapGetDisplayInfo.  tapSetDisplayColor
	must subsequently be called for each of the `nColors', and
	tapSetDisplayPattern must be called to describe the pattern(s)
	unless `fill' or `border' is TAP_EMPTY or TAP_SOLID.

void tapSetDisplayColor(layerPtr, index, red, green, blue)
octObject *layerPtr;
int index;
unsigned short red, green, blue;

        Sets the RGB values of the `index'th color defined for the
        layer pointed to by `layerPtr'.  `red', `green', and `blue' are
	as in tapGetDisplayColor.

void tapSetDisplayPattern(layerPtr, type, width, height, bitPtr)
octObject *layerPtr;
int type;
int width, height;
char *bitPtr;

	Sets the size (`width' and `height') and bit array of a stipple
        pattern for the layer pointed to by `layerPtr'.  `type', `width',
	and `height' are as in tapGetDisplayPattern.  The string pointed
	to by `bitPtr' can be reused immediately by the user.

void tapLayoutPalette(genPtr, pad, widthOverHeight)
octGenerator *genPtr;
octCoord pad;
double widthOverHeight;

	Takes the objects generated by `*genPtr' (often a user defined
	generator) and arranges them in rows, separated vertically and
	horizontally by at least `pad', attempting to achieve an aspect
	ratio of approximately `widthOverHeight'.  The current row can
	be ended prematurely by having the generator return an object
	without a valid bounding box (this could be a non-geometric
	object or even a non-existent object, if a user defined
	generator is used). When the generator is exhausted, the
	objects are moved and the function returns.  The array of
	objects is always placed with its upper-left corner at the
	containing facet's origin.

	Although this routine is intended to assist programs that
	create tap palettes, it has no direct relation to technology
	information, and can be used for other applications where its
	idea of a neat arrangement is desired.
