2017-04-25 14:41:48 +02:00
|
|
|
|
/*
|
|
|
|
|
|
* DBpaint2.c --
|
|
|
|
|
|
*
|
|
|
|
|
|
* More paint and erase primitives
|
|
|
|
|
|
*
|
|
|
|
|
|
* *********************************************************************
|
|
|
|
|
|
* * 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/DBpaint2.c,v 1.6 2010/06/24 12:37:15 tim Exp $";
|
|
|
|
|
|
#endif /* not lint */
|
|
|
|
|
|
|
|
|
|
|
|
#include <sys/types.h>
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
|
|
|
|
|
|
|
#include "utils/magic.h"
|
|
|
|
|
|
#include "utils/geometry.h"
|
|
|
|
|
|
#include "tiles/tile.h"
|
|
|
|
|
|
#include "utils/hash.h"
|
|
|
|
|
|
#include "database/database.h"
|
|
|
|
|
|
#include "database/databaseInt.h"
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
* ----------------------------------------------------------------------------
|
|
|
|
|
|
* DBPaint --
|
|
|
|
|
|
*
|
|
|
|
|
|
* Paint a rectangular area with a specific tile type.
|
|
|
|
|
|
* All paint tile planes in cellDef are painted.
|
|
|
|
|
|
*
|
|
|
|
|
|
* Results:
|
|
|
|
|
|
* None.
|
|
|
|
|
|
*
|
|
|
|
|
|
* Side effects:
|
|
|
|
|
|
* Modifies potentially all paint tile planes in cellDef.
|
|
|
|
|
|
* ----------------------------------------------------------------------------
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
|
DBPaint (cellDef, rect, type)
|
|
|
|
|
|
CellDef * cellDef; /* CellDef to modify */
|
|
|
|
|
|
Rect * rect; /* Area to paint */
|
|
|
|
|
|
TileType type; /* Type of tile to be painted */
|
|
|
|
|
|
{
|
|
|
|
|
|
int pNum;
|
|
|
|
|
|
PaintUndoInfo ui;
|
|
|
|
|
|
TileType loctype = type; /* Local value of tile type */
|
|
|
|
|
|
|
|
|
|
|
|
Rect brect;
|
|
|
|
|
|
GEO_EXPAND(rect, 1, &brect);
|
|
|
|
|
|
|
|
|
|
|
|
if (type & TT_DIAGONAL)
|
|
|
|
|
|
loctype = (type & TT_SIDE) ?
|
|
|
|
|
|
(type & TT_RIGHTMASK) >> 14 : (type & TT_LEFTMASK);
|
|
|
|
|
|
|
|
|
|
|
|
cellDef->cd_flags |= CDMODIFIED|CDGETNEWSTAMP;
|
|
|
|
|
|
ui.pu_def = cellDef;
|
|
|
|
|
|
for (pNum = PL_PAINTBASE; pNum < DBNumPlanes; pNum++)
|
|
|
|
|
|
if (DBPaintOnPlane(loctype, pNum))
|
|
|
|
|
|
{
|
|
|
|
|
|
ui.pu_pNum = pNum;
|
|
|
|
|
|
DBNMPaintPlane(cellDef->cd_planes[pNum], type, rect,
|
|
|
|
|
|
DBStdPaintTbl(loctype, pNum), &ui);
|
|
|
|
|
|
DBMergeNMTiles(cellDef->cd_planes[pNum], &brect, &ui);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Resolve images over all their planes. This allows the */
|
|
|
|
|
|
/* definition of composite types generated from types on */
|
|
|
|
|
|
/* different planes, as well as relaxing the constraints on */
|
|
|
|
|
|
/* the "compose" section of the technology file. */
|
|
|
|
|
|
|
|
|
|
|
|
if (loctype < DBNumUserLayers)
|
|
|
|
|
|
{
|
|
|
|
|
|
TileTypeBitMask *rMask, tMask;
|
|
|
|
|
|
TileType itype;
|
|
|
|
|
|
int dbResolveImages();
|
|
|
|
|
|
|
|
|
|
|
|
for (itype = TT_SELECTBASE; itype < DBNumUserLayers; itype++)
|
|
|
|
|
|
{
|
|
|
|
|
|
/* Ignore self, or infinite looping will result */
|
|
|
|
|
|
if (itype == loctype) continue;
|
|
|
|
|
|
|
|
|
|
|
|
rMask = DBResidueMask(itype);
|
|
|
|
|
|
if (TTMaskHasType(rMask, loctype))
|
|
|
|
|
|
{
|
|
|
|
|
|
TTMaskZero(&tMask);
|
|
|
|
|
|
TTMaskSetType(&tMask, itype);
|
|
|
|
|
|
for (pNum = PL_PAINTBASE; pNum < DBNumPlanes; pNum++)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (DBPaintOnPlane(itype, pNum))
|
|
|
|
|
|
{
|
|
|
|
|
|
DBSrPaintNMArea((Tile *)NULL, cellDef->cd_planes[pNum],
|
|
|
|
|
|
type, rect, &tMask, dbResolveImages,
|
|
|
|
|
|
(ClientData)cellDef);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
* dbResolveImages ---
|
|
|
|
|
|
*
|
|
|
|
|
|
* This callback function is called from DBSrPaintArea and
|
|
|
|
|
|
* makes a recursive call to DBPaint() for tiles that have
|
|
|
|
|
|
* images on multiple planes but which may not have been
|
|
|
|
|
|
* painted on all of those planes due to restrictions of
|
|
|
|
|
|
* the paint table.
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
|
dbResolveImages(tile, cellDef)
|
|
|
|
|
|
Tile *tile;
|
|
|
|
|
|
CellDef *cellDef;
|
|
|
|
|
|
{
|
|
|
|
|
|
Rect rect;
|
|
|
|
|
|
|
|
|
|
|
|
TiToRect(tile, &rect);
|
|
|
|
|
|
|
|
|
|
|
|
/* Recursive call back to DBPaint---this will ensure that */
|
|
|
|
|
|
/* all of the planes of the image type are painted. */
|
|
|
|
|
|
|
|
|
|
|
|
DBPaint(cellDef, &rect, TiGetTypeExact(tile));
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
* ----------------------------------------------------------------------------
|
|
|
|
|
|
* DBErase --
|
|
|
|
|
|
*
|
|
|
|
|
|
* Erase a specific tile type from a rectangular area.
|
|
|
|
|
|
* The plane in which tiles of the given type reside is modified
|
|
|
|
|
|
* in cellDef.
|
|
|
|
|
|
*
|
|
|
|
|
|
* Results:
|
|
|
|
|
|
* None.
|
|
|
|
|
|
*
|
|
|
|
|
|
* Side effects:
|
|
|
|
|
|
* Modifies potentially all paint tile planes in cellDef.
|
|
|
|
|
|
* ----------------------------------------------------------------------------
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
|
DBErase (cellDef, rect, type)
|
|
|
|
|
|
CellDef * cellDef; /* Cell to modify */
|
|
|
|
|
|
Rect * rect; /* Area to paint */
|
|
|
|
|
|
TileType type; /* Type of tile to be painted */
|
|
|
|
|
|
{
|
|
|
|
|
|
int pNum;
|
|
|
|
|
|
PaintUndoInfo ui;
|
|
|
|
|
|
TileType loctype = type; /* Local value of tile type */
|
|
|
|
|
|
|
|
|
|
|
|
Rect brect;
|
|
|
|
|
|
bool allPlane = FALSE;
|
|
|
|
|
|
|
|
|
|
|
|
if (GEO_SAMERECT(*rect, TiPlaneRect))
|
|
|
|
|
|
allPlane = TRUE;
|
|
|
|
|
|
else
|
|
|
|
|
|
GEO_EXPAND(rect, 1, &brect);
|
|
|
|
|
|
|
|
|
|
|
|
if (type & TT_DIAGONAL)
|
|
|
|
|
|
loctype = (type & TT_SIDE) ?
|
|
|
|
|
|
(type & TT_RIGHTMASK) >> 14 : (type & TT_LEFTMASK);
|
|
|
|
|
|
|
|
|
|
|
|
cellDef->cd_flags |= CDMODIFIED|CDGETNEWSTAMP;
|
|
|
|
|
|
ui.pu_def = cellDef;
|
|
|
|
|
|
if (loctype == TT_SPACE)
|
|
|
|
|
|
{
|
|
|
|
|
|
/*
|
|
|
|
|
|
* Erasing space is the same as erasing everything under
|
|
|
|
|
|
* the rectangle.
|
|
|
|
|
|
*/
|
|
|
|
|
|
for (pNum = PL_PAINTBASE; pNum < DBNumPlanes; pNum++)
|
|
|
|
|
|
{
|
|
|
|
|
|
ui.pu_pNum = pNum;
|
|
|
|
|
|
DBNMPaintPlane(cellDef->cd_planes[pNum], type, rect,
|
|
|
|
|
|
DBStdPaintTbl(loctype, pNum), &ui);
|
|
|
|
|
|
if (!allPlane)
|
|
|
|
|
|
DBMergeNMTiles(cellDef->cd_planes[pNum], &brect, &ui);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
/*
|
|
|
|
|
|
* Ordinary type is being erased.
|
|
|
|
|
|
* Generate the erase on all planes in cellDef.
|
|
|
|
|
|
*/
|
|
|
|
|
|
for (pNum = PL_PAINTBASE; pNum < DBNumPlanes; pNum++)
|
|
|
|
|
|
if (DBEraseOnPlane(loctype, pNum))
|
|
|
|
|
|
{
|
|
|
|
|
|
ui.pu_pNum = pNum;
|
|
|
|
|
|
DBNMPaintPlane(cellDef->cd_planes[pNum], type, rect,
|
|
|
|
|
|
DBStdEraseTbl(loctype, pNum), &ui);
|
|
|
|
|
|
if (!allPlane)
|
|
|
|
|
|
DBMergeNMTiles(cellDef->cd_planes[pNum], &brect, &ui);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
* ----------------------------------------------------------------------------
|
|
|
|
|
|
* DBPaintMask --
|
|
|
|
|
|
*
|
|
|
|
|
|
* Paint a rectangular area with all tile types specified in the
|
|
|
|
|
|
* mask supplied.
|
|
|
|
|
|
*
|
|
|
|
|
|
* Results:
|
|
|
|
|
|
* None.
|
|
|
|
|
|
*
|
|
|
|
|
|
* Side effects:
|
|
|
|
|
|
* Modifies potentially all paint tile planes in cellDef.
|
|
|
|
|
|
* ----------------------------------------------------------------------------
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
|
DBPaintMask(cellDef, rect, mask)
|
|
|
|
|
|
CellDef *cellDef; /* CellDef to modify */
|
|
|
|
|
|
Rect *rect; /* Area to paint */
|
|
|
|
|
|
TileTypeBitMask *mask; /* Mask of types to be erased */
|
|
|
|
|
|
{
|
|
|
|
|
|
TileType t;
|
|
|
|
|
|
|
|
|
|
|
|
for (t = TT_SPACE + 1; t < DBNumTypes; t++)
|
|
|
|
|
|
if (TTMaskHasType(mask, t))
|
|
|
|
|
|
DBPaint(cellDef, rect, t);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
* ----------------------------------------------------------------------------
|
|
|
|
|
|
* DBPaintValid --
|
|
|
|
|
|
*
|
|
|
|
|
|
* Paint a rectangular area with all tile types specified in the
|
|
|
|
|
|
* mask supplied, ANDed with valid layers.
|
|
|
|
|
|
*
|
|
|
|
|
|
* Results:
|
|
|
|
|
|
* None.
|
|
|
|
|
|
*
|
|
|
|
|
|
* Side effects:
|
|
|
|
|
|
* Modifies potentially all paint tile planes in cellDef.
|
|
|
|
|
|
* ----------------------------------------------------------------------------
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
|
DBPaintValid(cellDef, rect, mask, dinfo)
|
|
|
|
|
|
CellDef *cellDef; /* CellDef to modify */
|
|
|
|
|
|
Rect *rect; /* Area to paint */
|
|
|
|
|
|
TileTypeBitMask *mask; /* Mask of types to be erased */
|
|
|
|
|
|
TileType dinfo; /* If non-zero, then rect is a triangle and
|
|
|
|
|
|
* dinfo contains side and direction information
|
|
|
|
|
|
*/
|
|
|
|
|
|
{
|
|
|
|
|
|
TileType t, tt, tloc, dloc;
|
|
|
|
|
|
TileTypeBitMask rmask, mmask, *tMask;
|
|
|
|
|
|
|
|
|
|
|
|
dloc = dinfo & (TT_DIAGONAL | TT_SIDE | TT_DIRECTION);
|
|
|
|
|
|
|
|
|
|
|
|
TTMaskZero(&mmask);
|
|
|
|
|
|
TTMaskSetMask(&mmask, mask);
|
|
|
|
|
|
|
|
|
|
|
|
/* Decompose stacked contacts */
|
|
|
|
|
|
|
|
|
|
|
|
for (t = DBNumUserLayers; t < DBNumTypes; t++)
|
|
|
|
|
|
if (TTMaskHasType(mask, t))
|
|
|
|
|
|
TTMaskSetMask(&mmask, DBResidueMask(t));
|
|
|
|
|
|
|
|
|
|
|
|
/* Remove any inactive layers */
|
|
|
|
|
|
|
|
|
|
|
|
TTMaskAndMask(&mmask, &DBActiveLayerBits);
|
|
|
|
|
|
|
|
|
|
|
|
/* If any residue of a contact is not in the active layers */
|
|
|
|
|
|
/* list, then paint only the valid residue layers. */
|
|
|
|
|
|
|
|
|
|
|
|
for (t = TT_SELECTBASE; t < DBNumUserLayers; t++)
|
|
|
|
|
|
if (TTMaskHasType(&mmask, t))
|
|
|
|
|
|
if (DBIsContact(t))
|
|
|
|
|
|
{
|
|
|
|
|
|
tMask = DBResidueMask(t);
|
|
|
|
|
|
TTMaskAndMask3(&rmask, tMask, &DBActiveLayerBits);
|
|
|
|
|
|
if (TTMaskEqual(&rmask, tMask))
|
|
|
|
|
|
{
|
|
|
|
|
|
tloc = dloc | ((dinfo & TT_DIAGONAL) ? ((dinfo & TT_SIDE) ?
|
|
|
|
|
|
(t << 14) : t) : t);
|
|
|
|
|
|
DBPaint(cellDef, rect, tloc);
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (!TTMaskIsZero(&rmask))
|
|
|
|
|
|
{
|
|
|
|
|
|
for (tt = TT_SPACE + 1; tt < DBNumTypes; tt++)
|
|
|
|
|
|
if (TTMaskHasType(&rmask, tt))
|
|
|
|
|
|
{
|
|
|
|
|
|
tloc = dloc | ((dinfo & TT_DIAGONAL) ?
|
|
|
|
|
|
((dinfo & TT_SIDE) ? (tt << 14) : tt) : tt);
|
|
|
|
|
|
DBPaint(cellDef, rect, tloc);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
tloc = dloc | ((dinfo & TT_DIAGONAL) ? ((dinfo & TT_SIDE) ?
|
|
|
|
|
|
(t << 14) : t) : t);
|
|
|
|
|
|
DBPaint(cellDef, rect, tloc);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
* ----------------------------------------------------------------------------
|
|
|
|
|
|
* DBEraseMask --
|
|
|
|
|
|
*
|
|
|
|
|
|
* Erase a rectangular area with all tile types specified in the
|
|
|
|
|
|
* mask supplied.
|
|
|
|
|
|
*
|
|
|
|
|
|
* Results:
|
|
|
|
|
|
* None.
|
|
|
|
|
|
*
|
|
|
|
|
|
* Side effects:
|
|
|
|
|
|
* Modifies potentially all paint tile planes in cellDef.
|
|
|
|
|
|
* ----------------------------------------------------------------------------
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
|
DBEraseMask(cellDef, rect, mask)
|
|
|
|
|
|
CellDef *cellDef; /* CellDef to modify */
|
|
|
|
|
|
Rect *rect; /* Area to erase */
|
|
|
|
|
|
TileTypeBitMask *mask; /* Mask of types to be erased */
|
|
|
|
|
|
{
|
|
|
|
|
|
TileType t;
|
|
|
|
|
|
|
2018-08-21 04:43:34 +02:00
|
|
|
|
/* Corrected to restore erasing of error layers, which is */
|
|
|
|
|
|
/* functionality lost since magic version 7.1. Modified by */
|
|
|
|
|
|
/* BIM 8/18/2018 */
|
|
|
|
|
|
|
|
|
|
|
|
for (t = DBNumTypes - 1; t >= TT_PAINTBASE; t--)
|
2017-04-25 14:41:48 +02:00
|
|
|
|
if (TTMaskHasType(mask, t))
|
|
|
|
|
|
DBErase(cellDef, rect, t);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
* ----------------------------------------------------------------------------
|
|
|
|
|
|
* DBEraseValid --
|
|
|
|
|
|
*
|
|
|
|
|
|
* Erase a rectangular area with all tile types specified in the
|
|
|
|
|
|
* mask supplied, ANDed with valid layers.
|
|
|
|
|
|
*
|
|
|
|
|
|
* Results:
|
|
|
|
|
|
* None.
|
|
|
|
|
|
*
|
|
|
|
|
|
* Side effects:
|
|
|
|
|
|
* Modifies potentially all paint tile planes in cellDef.
|
|
|
|
|
|
* ----------------------------------------------------------------------------
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
|
DBEraseValid(cellDef, rect, mask, dinfo)
|
|
|
|
|
|
CellDef *cellDef; /* CellDef to modify */
|
|
|
|
|
|
Rect *rect; /* Area to erase */
|
|
|
|
|
|
TileTypeBitMask *mask; /* Mask of types to be erased */
|
|
|
|
|
|
TileType dinfo; /* w/Non-Manhattan geometry, "rect" is a
|
|
|
|
|
|
* triangle and dinfo holds side & direction
|
|
|
|
|
|
*/
|
|
|
|
|
|
{
|
|
|
|
|
|
TileType t, tt, tloc, dloc;
|
|
|
|
|
|
TileTypeBitMask rmask, mmask, *tMask;
|
|
|
|
|
|
|
|
|
|
|
|
dloc = dinfo & (TT_DIAGONAL | TT_SIDE | TT_DIRECTION);
|
|
|
|
|
|
|
|
|
|
|
|
/* Remove any inactive layers */
|
|
|
|
|
|
|
|
|
|
|
|
TTMaskAndMask3(&mmask, mask, &DBActiveLayerBits);
|
|
|
|
|
|
|
|
|
|
|
|
/* If any residue of a contact is not in the active layers */
|
|
|
|
|
|
/* list, then erase the contact in multiple passes. */
|
|
|
|
|
|
|
|
|
|
|
|
for (t = TT_SELECTBASE; t < DBNumUserLayers; t++)
|
|
|
|
|
|
if (TTMaskHasType(&mmask, t))
|
|
|
|
|
|
if (DBIsContact(t))
|
|
|
|
|
|
{
|
|
|
|
|
|
tMask = DBResidueMask(t);
|
|
|
|
|
|
TTMaskAndMask3(&rmask, tMask, &DBActiveLayerBits);
|
|
|
|
|
|
if (TTMaskEqual(&rmask, tMask))
|
|
|
|
|
|
{
|
|
|
|
|
|
tloc = dloc | ((dinfo & TT_DIAGONAL) ? ((dinfo & TT_SIDE) ?
|
|
|
|
|
|
(t << 14) : t) : t);
|
|
|
|
|
|
DBErase(cellDef, rect, tloc);
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (!TTMaskIsZero(&rmask))
|
|
|
|
|
|
{
|
|
|
|
|
|
for (tt = TT_SELECTBASE; tt < DBNumUserLayers; tt++)
|
|
|
|
|
|
if (TTMaskHasType(&rmask, tt))
|
|
|
|
|
|
{
|
|
|
|
|
|
tloc = dloc | ((dinfo & TT_DIAGONAL) ?
|
|
|
|
|
|
((dinfo & TT_SIDE) ? (tt << 14) : tt) : tt);
|
|
|
|
|
|
DBErase(cellDef, rect, tloc);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
tloc = dloc | ((dinfo & TT_DIAGONAL) ? ((dinfo & TT_SIDE) ?
|
|
|
|
|
|
(t << 14) : t) : t);
|
|
|
|
|
|
DBErase(cellDef, rect, tloc);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|