Merge branch 'master' into magic-8.2

This commit is contained in:
Tim Edwards 2020-03-21 03:00:06 -04:00
commit d03d814c48
10 changed files with 427 additions and 61 deletions

View File

@ -1 +1 @@
8.2.198
8.2.199

View File

@ -3714,14 +3714,6 @@ cmdDumpParseArgs(cmdName, w, cmd, dummy, scx)
if ((clen > 4) && !strcmp(cellnameptr + clen - 4, ".mag"))
*(cellnameptr + clen - 4) = '\0';
/* However, if this is a full path, then the full path name must have .mag */
if (fullpathname != NULL)
{
clen = strlen(fullpathname);
if ((clen <= 4) || strcmp(fullpathname + clen - 4, ".mag"))
strcat(cellnameptr, ".mag");
}
/* Check for illegal characters in the cellname */
if (CmdIllegalChars(cellnameptr, "", "Cell name"))
{

View File

@ -480,8 +480,8 @@ keepGoing(use, clientdata)
* Implement the "move" command.
*
* Usage:
* move [direction [amount]]
* move to x y
* move [origin] [direction [amount]]
* move [origin] to x y
*
* Results:
* None.
@ -502,12 +502,13 @@ CmdMove(w, cmd)
Point rootPoint, editPoint;
CellDef *rootDef;
int argpos;
bool doOrigin = FALSE;
if (cmd->tx_argc > 4)
{
badUsage:
TxError("Usage: %s [direction [amount]]\n", cmd->tx_argv[0]);
TxError(" or: %s to x y\n", cmd->tx_argv[0]);
TxError("Usage: %s [origin] [direction [amount]]\n", cmd->tx_argv[0]);
TxError(" or: %s [origin] to x y\n", cmd->tx_argv[0]);
return;
}
@ -518,18 +519,26 @@ CmdMove(w, cmd)
if (!ToolGetEditBox((Rect *)NULL)) return;
if (strcmp(cmd->tx_argv[1], "to") == 0)
argpos = 1;
if (strcmp(cmd->tx_argv[1], "origin") == 0)
{
doOrigin = TRUE;
argpos++;
}
if (strcmp(cmd->tx_argv[argpos], "to") == 0)
{
if (cmd->tx_argc != 4)
goto badUsage;
editPoint.p_x = cmdParseCoord(w, cmd->tx_argv[2], FALSE, TRUE);
editPoint.p_y = cmdParseCoord(w, cmd->tx_argv[3], FALSE, FALSE);
editPoint.p_x = cmdParseCoord(w, cmd->tx_argv[argpos + 1], FALSE, TRUE);
editPoint.p_y = cmdParseCoord(w, cmd->tx_argv[argpos + 2], FALSE, FALSE);
GeoTransPoint(&EditToRootTransform, &editPoint, &rootPoint);
goto moveToPoint;
}
indx = GeoNameToPos(cmd->tx_argv[1], FALSE, FALSE);
argpos = (indx < 0) ? 1 : 2;
indx = GeoNameToPos(cmd->tx_argv[argpos], FALSE, FALSE);
if (indx >= 0) argpos++;
if (cmd->tx_argc >= 3)
{
@ -605,8 +614,9 @@ CmdMove(w, cmd)
* but is retained for backward compatibility.
*/
if (ToolGetBox(&rootDef, &rootBox) && ((rootDef == SelectRootDef)
|| (SelectRootDef == NULL)))
if (ToolGetBox(&rootDef, &rootBox) &&
((rootDef == SelectRootDef) || (SelectRootDef == NULL))
&& (doOrigin == FALSE))
{
GeoTransRect(&t, &rootBox, &newBox);
DBWSetBox(rootDef, &newBox);
@ -640,11 +650,41 @@ moveToPoint:
}
GeoTransTranslate(rootPoint.p_x - rootBox.r_xbot,
rootPoint.p_y - rootBox.r_ybot, &GeoIdentityTransform, &t);
GeoTransRect(&t, &rootBox, &newBox);
DBWSetBox(rootDef, &newBox);
if (doOrigin == FALSE)
{
GeoTransRect(&t, &rootBox, &newBox);
DBWSetBox(rootDef, &newBox);
}
}
SelectTransform(&t);
if (doOrigin)
{
DBMoveCell(rootDef, t.t_c, t.t_f);
/* Adjust box to maintain relative position */
if (ToolGetBox(&rootDef, &rootBox) &&
((rootDef == SelectRootDef) || (SelectRootDef == NULL)))
{
t.t_c = -t.t_c;
t.t_f = -t.t_f;
GeoTransRect(&t, &rootBox, &newBox);
DBWSetBox(rootDef, &newBox);
t.t_c = -t.t_c;
t.t_f = -t.t_f;
}
/* Adjust all window viewing positions and redraw */
WindTranslate(t.t_c, t.t_f);
/* This is harsh. Might work to change all distance measures */
/* in the undo record, but this is simple and direct. */
UndoFlush();
}
else
SelectTransform(&t);
}
/*

View File

@ -1386,6 +1386,42 @@ typedef struct LCU1 /* A linked celluse record */
struct LCU1 *cu_next; /* Pointer to another linked celluse record */
} LinkedCellUse;
/*
* ----------------------------------------------------------------------------
*
* DBMovePoint ---
*
* Move a point by a position (origx, origy). Ignore positions which
* are marked as (M)INFINITY.
*
* Results:
* TRUE if the point was moved (point position was not infinite)
*
* Side effects:
* Point structure pointed to by the first argument is repositioned.
*
* ----------------------------------------------------------------------------
*/
bool
DBMovePoint(p, origx, origy)
Point *p;
int origx, origy;
{
int result = FALSE;
if ((p->p_x < (INFINITY - 2)) && (p->p_x > (MINFINITY + 2)))
{
p->p_x -= origx;
result = TRUE;
}
if ((p->p_y < (INFINITY + 2)) && (p->p_y > (MINFINITY + 2)))
{
p->p_y -= origy;
result = TRUE;
}
return result;
}
/*
* ----------------------------------------------------------------------------
*
@ -1538,6 +1574,14 @@ struct scaleArg {
bool modified;
};
struct moveArg {
int origx;
int origy;
int pnum;
Plane *ptarget;
bool modified;
};
/*
* ----------------------------------------------------------------------------
*
@ -1619,6 +1663,74 @@ dbTileScaleFunc(tile, scvals)
return 0;
}
/*
* ----------------------------------------------------------------------------
*
* dbMovePlane --
*
* Relocation procedure called on a single plane. Copies paint into the
* new plane at a delta position (-origx, -origy)
*
* ----------------------------------------------------------------------------
*/
bool
dbMovePlane(oldplane, newplane, pnum, origx, origy)
Plane *oldplane, *newplane;
int pnum;
int origx, origy;
{
int dbTileMoveFunc(); /* forward declaration */
struct moveArg arg;
arg.origx = origx;
arg.origy = origy;
arg.ptarget = newplane;
arg.pnum = pnum;
arg.modified = FALSE;
(void) DBSrPaintArea((Tile *) NULL, oldplane, &TiPlaneRect,
&DBAllButSpaceBits, dbTileMoveFunc, (ClientData) &arg);
return arg.modified;
}
/*
* ----------------------------------------------------------------------------
*
* dbTileMoveFunc --
*
* Repositioning procedure called on each tile being copied from one plane
* to another. Delta position (-origx, -origy) is stored inside the struct
* moveArg before calling.
*
* ----------------------------------------------------------------------------
*/
int
dbTileMoveFunc(tile, mvvals)
Tile *tile;
struct moveArg *mvvals;
{
TileType type;
Rect targetRect;
TileType exact;
TiToRect(tile, &targetRect);
mvvals->modified = TRUE;
DBMovePoint(&targetRect.r_ll, mvvals->origx, mvvals->origy);
DBMovePoint(&targetRect.r_ur, mvvals->origx, mvvals->origy);
type = TiGetTypeExact(tile);
exact = type;
if (IsSplit(tile))
type = (SplitSide(tile)) ? SplitRightType(tile) : SplitLeftType(tile);
DBNMPaintPlane(mvvals->ptarget, exact, &targetRect,
DBStdPaintTbl(type, mvvals->pnum),
(PaintUndoInfo *)NULL);
return 0;
}
/*
* ----------------------------------------------------------------------------
*
@ -1804,9 +1916,6 @@ dbScaleCell(cellDef, scalen, scaled)
cellDef->cd_planes[pNum] = newplane;
}
/* Check consistency of several global pointers */
/* WARNING: This list may not be complete! */
/* Also scale the position of all labels. */
/* If labels are the rendered-font type, scale the size as well */
@ -1949,3 +2058,176 @@ dbCellUseEnumFunc(cellUse, arg)
return 0;
}
/*
* ----------------------------------------------------------------------------
*
* DBMoveCell --
*
* Reposition a cell to a different origin. This routine is equivalent to
* unexpanding all contents of a cell, selecting everything, and issuing a
* move command. However, for very large layouts this becomes memory- and
* compute- intensive. The process of reorienting an entire layout to a
* new position can be done much more efficiently. This routine is
* essentially a copy of dbScaleCell() but changes only position and not
* scale.
*
* ----------------------------------------------------------------------------
*/
int
DBMoveCell(cellDef, origx, origy)
CellDef *cellDef; /* Pointer to CellDef to be saved. This def might
* be an internal buffer; if so, we ignore it.
*/
int origx, origy; /* Internal unit coordinates which will become the new origin */
{
int dbCellTileEnumFunc(), dbCellUseEnumFunc();
Label *lab;
int pNum;
LinkedTile *lhead, *lt;
LinkedCellUse *luhead, *lu;
Plane *newplane;
/* Unlike dbScaleCell(), this routine is only run on valid edit defs */
cellDef->cd_flags |= CDBOXESCHANGED;
/* Enumerate all unique cell uses, and move their position in the */
/* bounding box and transform. */
luhead = NULL;
(void) DBCellEnum(cellDef, dbCellUseEnumFunc, (ClientData) &luhead);
lu = luhead;
while (lu != NULL)
{
CellUse *use;
Rect *bbox;
use = lu->cellUse;
bbox = &use->cu_bbox;
/* TxPrintf("CellUse: BBox is ll (%d, %d), transform [%d %d %d %d %d %d]\n",
bbox->r_xbot, bbox->r_ybot,
use->cu_transform.t_a, use->cu_transform.t_b, use->cu_transform.t_c,
use->cu_transform.t_d, use->cu_transform.t_e, use->cu_transform.t_f); */
DBMovePoint(&bbox->r_ll, origx, origy);
DBMovePoint(&bbox->r_ur, origx, origy);
bbox = &use->cu_extended;
DBMovePoint(&bbox->r_ll, origx, origy);
DBMovePoint(&bbox->r_ur, origx, origy);
use->cu_transform.t_c -= origx;
use->cu_transform.t_f -= origy;
lu = lu->cu_next;
}
/* Free this linked cellUse structure */
lu = luhead;
while (lu != NULL)
{
freeMagic((char *)lu);
lu = lu->cu_next;
}
/* Move the position of all subcell uses. Count all of the tiles in the */
/* subcell plane, and move those without reference to the actual cells (so */
/* we don't count the cells multiple times). */
lhead = NULL;
(void) TiSrArea((Tile *)NULL, cellDef->cd_planes[PL_CELL], &TiPlaneRect,
dbCellTileEnumFunc, (ClientData) &lhead);
/* Move each of the tiles in the linked list by (-x, -y) */
/* Don't move (M)INFINITY on boundary tiles! */
lt = lhead;
while (lt != NULL)
{
DBMovePoint(&lt->tile->ti_ll, origx, origy);
lt = lt->t_next;
}
/* Free this linked tile structure */
lt = lhead;
while (lt != NULL)
{
freeMagic((char *)lt);
lt = lt->t_next;
}
/* Move all of the paint tiles in this cell by creating a new plane */
/* and copying all tiles into the new plane at the new position. */
for (pNum = PL_PAINTBASE; pNum < DBNumPlanes; pNum++)
{
if (cellDef->cd_planes[pNum] == NULL) continue;
newplane = DBNewPlane((ClientData) TT_SPACE);
DBClearPaintPlane(newplane);
if (dbMovePlane(cellDef->cd_planes[pNum], newplane, pNum,
origx, origy, FALSE))
cellDef->cd_flags |= (CDMODIFIED | CDGETNEWSTAMP);
DBFreePaintPlane(cellDef->cd_planes[pNum]);
TiFreePlane(cellDef->cd_planes[pNum]);
cellDef->cd_planes[pNum] = newplane;
}
/* Also move the position of all labels. */
if (cellDef->cd_labels)
{
for (lab = cellDef->cd_labels; lab; lab = lab->lab_next)
{
DBMovePoint(&lab->lab_rect.r_ll, origx, origy);
DBMovePoint(&lab->lab_rect.r_ur, origx, origy);
if (lab->lab_font >= 0)
{
DBMovePoint(&lab->lab_bbox.r_ll, origx, origy);
DBMovePoint(&lab->lab_bbox.r_ur, origx, origy);
}
}
}
donecell:
/* The cellDef bounding box gets moved to match the new position. */
DBMovePoint(&cellDef->cd_bbox.r_ll, origx, origy);
DBMovePoint(&cellDef->cd_bbox.r_ur, origx, origy);
DBMovePoint(&cellDef->cd_extended.r_ll, origx, origy);
DBMovePoint(&cellDef->cd_extended.r_ur, origx, origy);
/* If the cell is an abstract view with a fixed bounding box, then */
/* adjust the bounding box property to match the new scale. */
if ((cellDef->cd_flags & CDFIXEDBBOX) != 0)
{
Rect r;
bool found;
char *propval;
propval = (char *)DBPropGet(cellDef, "FIXED_BBOX", &found);
if (found)
{
if (sscanf(propval, "%d %d %d %d", &r.r_xbot, &r.r_ybot,
&r.r_xtop, &r.r_ytop) == 4)
{
DBMovePoint(&r.r_ll, origx, origy);
DBMovePoint(&r.r_ur, origx, origy);
propval = (char *)mallocMagic(40);
sprintf(propval, "%d %d %d %d", r.r_xbot, r.r_ybot,
r.r_xtop, r.r_ytop);
DBPropPut(cellDef, "FIXED_BBOX", propval);
}
}
}
return 0;
}

View File

@ -1133,7 +1133,14 @@ dbReadOpen(cellDef, name, setFileName, errptr)
cellDef->cd_flags &= ~CDNOTFOUND;
#endif
if (setFileName)
{
/* Remove any ".mag" file extension */
char *pptr = strrchr(filename, '.');
if (pptr != NULL)
if (!strcmp(pptr, DBSuffix)) *pptr = '\0';
(void) StrDup(&cellDef->cd_file, filename);
}
cellDef->cd_flags |= CDAVAILABLE;
return (f);
}

View File

@ -1619,7 +1619,7 @@ esMakePorts(hc, cdata)
nn = (EFNodeName *) HashGetValue(he);
}
if (!(nn->efnn_node->efnode_flags & EF_PORT))
if (nn->efnn_node && !(nn->efnn_node->efnode_flags & EF_PORT))
{
nn->efnn_node->efnode_flags |= EF_PORT;
nn->efnn_port = -1; // Will be sorted later

View File

@ -1668,7 +1668,7 @@ topVisit(def, doStub)
sname = (EFNodeName *) HashGetValue(he);
if (sname == NULL) continue;
snode = sname->efnn_node;
if (!(snode->efnode_flags & EF_PORT)) continue;
if ((!snode) || (!(snode->efnode_flags & EF_PORT))) continue;
for (nodeName = sname; nodeName != NULL; nodeName = nodeName->efnn_next)
{
portorder = nodeName->efnn_port;
@ -1729,7 +1729,7 @@ topVisit(def, doStub)
if (sname == NULL) continue; /* Should not happen */
snode = sname->efnn_node;
if (!(snode->efnode_flags & EF_PORT)) continue;
if ((!snode) || (!(snode->efnode_flags & EF_PORT))) continue;
for (nodeName = sname; nodeName != NULL; nodeName = nodeName->efnn_next)
{
@ -1787,7 +1787,7 @@ topVisit(def, doStub)
if (sname == NULL) continue;
snode = sname->efnn_node;
if (snode->efnode_flags & EF_SUBS_PORT)
if (snode && (snode->efnode_flags & EF_SUBS_PORT))
{
if (snode->efnode_name->efnn_port < 0)
{

View File

@ -466,6 +466,8 @@ efBuildEquiv(def, nodeName1, nodeName2)
if (efWarn)
efReadError("Merged nodes %s and %s\n", nodeName1, nodeName2);
efNodeMerge(&nn1->efnn_node, &nn2->efnn_node);
if (nn1->efnn_port > 0) nn2->efnn_port = nn1->efnn_port;
else if (nn2->efnn_port > 0) nn1->efnn_port = nn2->efnn_port;
}
return;
}

View File

@ -618,6 +618,14 @@ MakeLegalLEFSyntax(text)
return rstr;
}
/* Linked list structure for holding PIN PORT geometry areas */
typedef struct _labelLinkedList {
Label *lll_label;
Rect lll_area;
struct _labelLinkedList *lll_next;
} labelLinkedList;
/*
* ----------------------------------------------------------------------------
*
@ -657,6 +665,7 @@ lefWriteMacro(def, f, scale, hide)
char *LEFtext;
HashSearch hs;
HashEntry *he;
labelLinkedList *lll = NULL;
extern CellDef *SelectDef;
@ -959,7 +968,11 @@ lefWriteMacro(def, f, scale, hide)
if (hide)
{
SelectChunk(&scx, lab->lab_type, 0, NULL, FALSE);
Rect carea;
labelLinkedList *newlll;
SelectChunk(&scx, lab->lab_type, 0, &carea, FALSE);
if (GEO_RECTNULL(&carea)) carea = lab->lab_rect;
/* Note that a sticky label could be placed over multiple */
/* tile types, which would cause SelectChunk to fail. So */
@ -967,8 +980,15 @@ lefWriteMacro(def, f, scale, hide)
/* SelectDef. */
pNum = DBPlane(lab->lab_type);
DBPaintPlane(SelectDef->cd_planes[pNum], &lab->lab_rect,
DBPaintPlane(SelectDef->cd_planes[pNum], &carea,
DBStdPaintTbl(lab->lab_type, pNum), (PaintUndoInfo *) NULL);
/* Remember this area since it's going to get erased */
newlll = (labelLinkedList *)mallocMagic(sizeof(labelLinkedList));
newlll->lll_label = lab;
newlll->lll_area = carea;
newlll->lll_next = lll;
lll = newlll;
}
else
SelectNet(&scx, lab->lab_type, 0, NULL, FALSE);
@ -1064,6 +1084,7 @@ lefWriteMacro(def, f, scale, hide)
/* cell. Otherwise, this routine can block internal pins. */
Rect layerBound;
labelLinkedList *thislll;
for (ttype = TT_TECHDEPBASE; ttype < DBNumTypes; ttype++)
if (TTMaskHasType(&lmask, ttype))
@ -1080,39 +1101,20 @@ lefWriteMacro(def, f, scale, hide)
DBPaint(lc.lefYank, &layerBound, ttype);
}
scx.scx_use = &lefSourceUse;
for (lab = def->cd_labels; lab != NULL; lab = lab->lab_next)
for (thislll = lll; thislll; thislll = thislll->lll_next)
{
Rect carea;
int lspace;
labr = lab->lab_rect;
lab = thislll->lll_label;
/* Force label area to be non-degenerate */
if (labr.r_xbot >= labr.r_xtop)
{
labr.r_xbot--;
labr.r_xtop++;
}
if (labr.r_ybot >= labr.r_ytop)
{
labr.r_ybot--;
labr.r_ytop++;
}
if (lab->lab_flags & PORT_DIR_MASK)
{
scx.scx_area = labr;
SelectClear();
SelectChunk(&scx, lab->lab_type, 0, &carea, FALSE);
if (GEO_RECTNULL(&carea)) carea = lab->lab_rect;
lspace = DRCGetDefaultLayerSpacing(lab->lab_type, lab->lab_type);
carea.r_xbot -= lspace;
carea.r_ybot -= lspace;
carea.r_xtop += lspace;
carea.r_ytop += lspace;
DBErase(lc.lefYank, &carea, lab->lab_type);
}
lspace = DRCGetDefaultLayerSpacing(lab->lab_type, lab->lab_type);
thislll->lll_area.r_xbot -= lspace;
thislll->lll_area.r_ybot -= lspace;
thislll->lll_area.r_xtop += lspace;
thislll->lll_area.r_ytop += lspace;
DBErase(lc.lefYank, &thislll->lll_area, lab->lab_type);
freeMagic(thislll);
}
}
else

View File

@ -289,6 +289,47 @@ WindScale(scalen, scaled)
}
}
/*
* ----------------------------------------------------------------------------
*
* WindTranslate --
*
* Move the viewing windows by the given delta position. Because
* this is done in conjunction with repositioning the geometry
* ("move origin" command), we don't preserve the center position
* like WindZoom() does. The net effect is that the image in the
* window doesn't appear to change.
*
* Results:
* None.
*
* Side effects:
* All windows will be now view a different portion of the client's area.
*
* ----------------------------------------------------------------------------
*/
void
WindTranslate(origx, origy)
int origx, origy;
{
extern void DBMovePoint();
MagWindow *w2;
Rect newArea;
for (w2 = windTopWindow; w2 != NULL; w2 = w2->w_nextWindow)
{
newArea.r_xbot = w2->w_surfaceArea.r_xbot;
newArea.r_xtop = w2->w_surfaceArea.r_xtop;
newArea.r_ybot = w2->w_surfaceArea.r_ybot;
newArea.r_ytop = w2->w_surfaceArea.r_ytop;
DBMovePoint(&newArea.r_ll, origx, origy);
DBMovePoint(&newArea.r_ur, origx, origy);
WindMove(w2, &newArea);
}
}
/*
* ----------------------------------------------------------------------------