magic/database/DBcellsubr.c

346 lines
9.4 KiB
C
Raw Normal View History

/*
* DBcellsubr.c --
*
* Low-level support for cell operations.
*
* *********************************************************************
* * 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/database/DBcellsubr.c,v 1.2 2010/09/15 20:26:08 tim Exp $";
#endif /* not lint */
#include <stdio.h>
#include "utils/magic.h"
#include "utils/malloc.h"
#include "utils/hash.h"
#include "utils/utils.h"
#include "utils/geometry.h"
#include "tiles/tile.h"
#include "database/database.h"
#include "database/databaseInt.h"
#include "dbwind/dbwind.h"
#include "utils/signals.h"
/* Forward declarations */
extern void dbSetPlaneTile();
/*
* ----------------------------------------------------------------------------
* DBDescendSubcell --
*
* Determine from the supplied mask if a tree search should descend into
* a cell. Note that the mask must be one of the following: 1) a single
* bit representing a window dbw_bitmask, 2) CU_DESCEND_ALL (== 0), or
* 3) a number that is not a power of two that is defined in database.h
* as a valid type for xMask (e.g., CU_DESCEND_SPECIAL).
*
* Results:
* TRUE if we should descend, FALSE if not.
*
* Side effects:
* None.
*
* Notes:
* This routine can be expanded as necessary, adding flags for various
* modes of determining whether or not to descend into a subcell.
*
* ----------------------------------------------------------------------------
*/
bool
DBDescendSubcell(use, xMask)
CellUse *use;
unsigned int xMask;
{
bool propfound;
/* Check single bit (window ID) or zero */
if (((xMask - 1) & xMask) == 0)
return ((use->cu_expandMask & xMask) == xMask);
else switch (xMask) {
case CU_DESCEND_SPECIAL:
return (use->cu_expandMask == CU_DESCEND_SPECIAL);
case CU_DESCEND_NO_SUBCKT:
if ((use->cu_def->cd_flags & CDAVAILABLE) == 0)
if (!DBCellRead(use->cu_def, TRUE, TRUE, NULL))
return FALSE;
return (DBIsSubcircuit(use->cu_def)) ? FALSE : TRUE;
case CU_DESCEND_NO_LOCK:
if (use->cu_flags & CU_LOCKED)
return FALSE;
else
return (use->cu_expandMask == CU_DESCEND_SPECIAL);
case CU_DESCEND_NO_VENDOR:
return (use->cu_def->cd_flags & CDVENDORGDS) ? FALSE : TRUE;
case CU_DESCEND_PROP_FLAT:
if (use->cu_expandMask == CU_DESCEND_SPECIAL)
return TRUE;
else
{
/* Descend only into cells marked with property "flatten" */
DBPropGet(use->cu_def, "flatten", &propfound);
return (propfound) ? TRUE : FALSE;
}
case CU_DESCEND_NONE:
return FALSE;
}
return TRUE; /* in case CU_DESCEND_ALL is not defined as 0 */
}
/*
* ----------------------------------------------------------------------------
*
* DBCellCopyDefBody --
*
* Copies the contents of the CellDef pointed to by sourceDef into the
* CellDef pointed to by destDef. Only the planes, labels, flags,
* cell plane, use-id hash table, and bounding box are copied.
*
* Results:
* None.
*
* Side effects:
* Switches the contents of the bodies of the two CellDefs.
*
* ----------------------------------------------------------------------------
*/
void
DBCellCopyDefBody(sourceDef, destDef)
CellDef *sourceDef; /* Pointer to CellDef copied from */
CellDef *destDef; /* Pointer to CellDef copied to */
{
int i;
int dbCopyDefFunc();
destDef->cd_flags = sourceDef->cd_flags;
destDef->cd_bbox = sourceDef->cd_bbox;
destDef->cd_labels = sourceDef->cd_labels;
destDef->cd_lastLabel = sourceDef->cd_lastLabel;
destDef->cd_idHash = sourceDef->cd_idHash;
for (i = 0; i < MAXPLANES; i++)
destDef->cd_planes[i] = sourceDef->cd_planes[i];
destDef->cd_cellPlane = sourceDef->cd_cellPlane;
/* Be careful to update parent pointers in the children of dest.
* Don't allow interrupts to wreck this.
*/
SigDisableInterrupts();
(void) DBSrCellPlaneArea(destDef->cd_cellPlane,
&TiPlaneRect, dbCopyDefFunc, (ClientData) destDef);
SigEnableInterrupts();
}
int
dbCopyDefFunc(use, def)
CellUse *use; /* Subcell use. */
CellDef *def; /* Set parent pointer in each use to this. */
{
use->cu_parent = def;
return 0;
}
/*
* ----------------------------------------------------------------------------
*
* DBCellClearDef --
*
* Empties out all tile planes of the indicated CellDef, making it
* as though the def had been newly allocated. This also removes all
* labels and all properties from the cell.
*
* Results:
* None.
*
* Side effects:
* The paint and subcells stored in the CellDef are all deleted.
* Sets the bounding box to the degenerate (0,0)::(1,1) box.
*
* ----------------------------------------------------------------------------
*/
void
DBCellClearDef(cellDef)
CellDef *cellDef; /* Pointer to CellDef to be deleted */
{
int pNum;
Plane *plane;
Label *lab;
Tile *tile;
/*
* We want the following searching to be non-interruptible
* to guarantee that everything gets cleared.
*/
SigDisableInterrupts();
/* Remove all instances from the cell plane */
DBClearCellPlane(cellDef);
/* Reduce clutter by reinitializing the id hash table */
HashKill(&cellDef->cd_idHash);
HashInit(&cellDef->cd_idHash, 16, HT_STRINGKEYS);
for (pNum = PL_PAINTBASE; pNum < DBNumPlanes; pNum++)
{
plane = cellDef->cd_planes[pNum];
tile = TR(plane->pl_left);
if (TiGetBody(tile) != TT_SPACE
|| LB(tile) != plane->pl_bottom
|| TR(tile) != plane->pl_right
|| RT(tile) != plane->pl_top)
DBClearPaintPlane(plane);
}
cellDef->cd_bbox.r_xbot = cellDef->cd_bbox.r_ybot = 0;
cellDef->cd_bbox.r_xtop = cellDef->cd_bbox.r_ytop = 1;
cellDef->cd_extended.r_xbot = cellDef->cd_extended.r_ybot = 0;
cellDef->cd_extended.r_xtop = cellDef->cd_extended.r_ytop = 1;
for (lab = cellDef->cd_labels; lab; lab = lab->lab_next)
freeMagic((char *) lab);
cellDef->cd_labels = (Label *) NULL;
cellDef->cd_lastLabel = (Label *) NULL;
/* Remove all defined properties */
DBPropClearAll(cellDef);
/* Remove any elements associated with the cell */
DBWElementClearDef(cellDef);
SigEnableInterrupts();
}
/*
* ----------------------------------------------------------------------------
*
* DBClearPaintPlane --
*
* Similar in effect to painting space over an entire tile plane, but
* much faster. The resultant tile plane is guaranteed to contain a
* single central space tile, exactly as though it had been newly allocated.
*
* Results:
* None.
*
* Side effects:
* Modifies the database plane given.
*
* ----------------------------------------------------------------------------
*/
void
DBClearPaintPlane(plane)
Plane *plane;
{
Tile *newCenterTile;
/* Eliminate all the tiles from this plane */
DBFreePaintPlane(plane);
/* Allocate a new central space tile */
newCenterTile = TiAlloc();
plane->pl_hint = newCenterTile;
TiSetBody(newCenterTile, TT_SPACE);
dbSetPlaneTile(plane, newCenterTile);
}
/*
* ----------------------------------------------------------------------------
*
* dbSetPlaneTile --
*
* Set the single central tile of a plane to be that specified.
*
* Results:
* None.
*
* Side effects:
* Modifies the plane given.
*
* ----------------------------------------------------------------------------
*/
void
dbSetPlaneTile(plane, newCenterTile)
Plane *plane;
Tile *newCenterTile;
{
/*
* Set the stitches of the newly created center tile
* to point to the four boundaries of the plane.
*/
RT(newCenterTile) = plane->pl_top;
TR(newCenterTile) = plane->pl_right;
LB(newCenterTile) = plane->pl_bottom;
BL(newCenterTile) = plane->pl_left;
/*
* Set the stitches for the four boundaries of the plane
* all to point to the newly created center tile.
*/
RT(plane->pl_bottom) = newCenterTile;
LB(plane->pl_top) = newCenterTile;
TR(plane->pl_left) = newCenterTile;
BL(plane->pl_right) = newCenterTile;
LEFT(newCenterTile) = TiPlaneRect.r_xbot;
BOTTOM(newCenterTile) = TiPlaneRect.r_ybot;
}
/*
* ----------------------------------------------------------------------------
*
* DBNewPlane --
*
* Allocates and initializes a new tile plane for a cell.
* The new plane contains a single tile whose body is specified by
* the caller. The tile extends from minus infinity to plus infinity.
*
* Results:
* Returns a pointer to a new tile plane.
*
* Side effects:
* None.
*
* ----------------------------------------------------------------------------
*/
Plane *
DBNewPlane(body)
ClientData body; /* Body of initial, central tile */
{
Tile *newtile;
newtile = TiAlloc();
TiSetBody(newtile, body);
LEFT(newtile) = TiPlaneRect.r_xbot;
BOTTOM(newtile) = TiPlaneRect.r_ybot;
return (TiNewPlane(newtile));
}