265 lines
7.8 KiB
C
265 lines
7.8 KiB
C
/*
|
||
* ExtYank.c --
|
||
*
|
||
* Circuit extraction.
|
||
* Hierarchical yanking of paint and labels.
|
||
*
|
||
* *********************************************************************
|
||
* * 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/extract/ExtYank.c,v 1.2 2008/06/01 18:37:42 tim Exp $";
|
||
#endif /* not lint */
|
||
|
||
#include <stdio.h>
|
||
#include <string.h>
|
||
#include <math.h>
|
||
|
||
#include "utils/magic.h"
|
||
#include "utils/geometry.h"
|
||
#include "utils/geofast.h"
|
||
#include "tiles/tile.h"
|
||
#include "utils/hash.h"
|
||
#include "database/database.h"
|
||
#include "utils/malloc.h"
|
||
#include "textio/textio.h"
|
||
#include "debug/debug.h"
|
||
#include "utils/styles.h"
|
||
#include "extract/extract.h"
|
||
#include "extract/extractInt.h"
|
||
|
||
Rect extSubcellArea; /* Area of currently processed subcell, clipped
|
||
* to area of interaction, in parent coords.
|
||
*/
|
||
|
||
/* Forward declarations of filter functions */
|
||
int extHierYankFunc();
|
||
int extHierLabelFunc();
|
||
|
||
/*
|
||
* ----------------------------------------------------------------------------
|
||
*
|
||
* extHierCopyLabels --
|
||
*
|
||
* Copy the label list from sourceDef to targetDef, prepending
|
||
* it to any labels already in targetDef. Does not change
|
||
* sourceDef's label list.
|
||
*
|
||
* Labels are copied in order, so the first label on sourceDef's
|
||
* list becomes the first label on targetDef's list. THIS IS
|
||
* CRITICAL TO INSURE THAT HIERARCHICAL ADJUSTMENTS CAN BE MADE
|
||
* PROPERLY; SEE extSubtreeAdjustInit() FOR AN EXPLANATION.
|
||
*
|
||
* Results:
|
||
* None.
|
||
*
|
||
* Side effects:
|
||
* See above.
|
||
*
|
||
* ----------------------------------------------------------------------------
|
||
*/
|
||
|
||
void
|
||
extHierCopyLabels(sourceDef, targetDef)
|
||
CellDef *sourceDef, *targetDef;
|
||
{
|
||
Label *lab, *newlab, *firstLab, *lastLab;
|
||
unsigned n;
|
||
|
||
firstLab = lastLab = (Label *) NULL;
|
||
for (lab = sourceDef->cd_labels; lab; lab = lab->lab_next)
|
||
{
|
||
n = sizeof (Label) + strlen(lab->lab_text) - sizeof lab->lab_text + 1;
|
||
newlab = (Label *) mallocMagic((unsigned) n);
|
||
bcopy((char *) lab, (char *) newlab, (int) n);
|
||
|
||
if (lastLab == NULL) lastLab = firstLab = newlab;
|
||
else lastLab->lab_next = newlab, lastLab = newlab;
|
||
}
|
||
|
||
if (lastLab)
|
||
{
|
||
lastLab->lab_next = targetDef->cd_labels;
|
||
targetDef->cd_labels = firstLab;
|
||
}
|
||
}
|
||
|
||
/*
|
||
* ----------------------------------------------------------------------------
|
||
*
|
||
* extHierFreeLabels --
|
||
*
|
||
* Free all the labels from 'def'.
|
||
* Leaves the label lis of 'def' pointing to NULL.
|
||
*
|
||
* This procedure exists mainly so we can trace the freeing
|
||
* of labels for debugging.
|
||
*
|
||
* Results:
|
||
* None.
|
||
*
|
||
* Side effects:
|
||
* See above.
|
||
*
|
||
* ----------------------------------------------------------------------------
|
||
*/
|
||
|
||
void
|
||
extHierFreeLabels(def)
|
||
CellDef *def;
|
||
{
|
||
Label *lab;
|
||
|
||
for (lab = def->cd_labels; lab; lab = lab->lab_next)
|
||
freeMagic((char *) lab);
|
||
def->cd_labels = (Label *) NULL;
|
||
}
|
||
|
||
/*
|
||
* ----------------------------------------------------------------------------
|
||
*
|
||
* extHierYankFunc --
|
||
*
|
||
* Filter function normally called by DBArraySr to yank hierarchically the
|
||
* paint and labels from 'use'. Called for each array element. Also called
|
||
* during array extraction.
|
||
*
|
||
* Expects hy->hy_area to be the area, in use->cu_parent coordinates,
|
||
* to be yanked. What we yank will be transformed to parent coordinates
|
||
* and placed in the cell hy->hy_target. If hy->hy_prefix is TRUE, we
|
||
* will prepend all the labels we yank with the use id of this array
|
||
* element; otherwise, the labels have no prefix.
|
||
*
|
||
* WARNING:
|
||
* Only node-name labels are yanked; attributes are not.
|
||
* The hierarchical extraction code depends on this fact.
|
||
*
|
||
* Results:
|
||
* Returns 0 to cause DBArraySr to keep going.
|
||
*
|
||
* Side effects:
|
||
* Adds paint and new labels to 'hy->hy_target'.
|
||
*
|
||
* ----------------------------------------------------------------------------
|
||
*/
|
||
|
||
int
|
||
extHierYankFunc(use, trans, x, y, hy)
|
||
CellUse *use; /* Use that is the root of the subtree being yanked */
|
||
Transform *trans; /* Transform from coordinates of use->cu_def to those
|
||
* in use->cu_parent, for the array element (x, y).
|
||
*/
|
||
int x, y; /* Indices of this array element */
|
||
HierYank *hy; /* See comments in procedure header */
|
||
{
|
||
char labelBuf[4096];
|
||
TerminalPath tpath;
|
||
SearchContext scx;
|
||
Transform tinv;
|
||
|
||
/*
|
||
* Want scx.scx_area to be the area in coordinates of use->cu_def
|
||
* but hy->hy_area is in coordinates of use->cu_parent.
|
||
*/
|
||
GEOINVERTTRANS(trans, &tinv);
|
||
GEOTRANSRECT(&tinv, hy->hy_area, &scx.scx_area);
|
||
GEOCLIP(&scx.scx_area, &use->cu_def->cd_bbox);
|
||
|
||
scx.scx_use = use;
|
||
scx.scx_trans = *trans;
|
||
scx.scx_x = x;
|
||
scx.scx_y = y;
|
||
|
||
/* Yank the paint */
|
||
// if (!DBIsSubcircuit(use->cu_def))
|
||
DBCellCopyAllPaint(&scx, &DBAllButSpaceBits, 0, hy->hy_target);
|
||
|
||
/* Yank the labels */
|
||
tpath.tp_next = tpath.tp_first = labelBuf;
|
||
tpath.tp_last = &labelBuf[sizeof labelBuf - 2];
|
||
if (hy->hy_prefix)
|
||
{
|
||
tpath.tp_next = DBPrintUseId(&scx, labelBuf, sizeof labelBuf - 3, FALSE);
|
||
*tpath.tp_next++ = '/';
|
||
}
|
||
*tpath.tp_next = '\0';
|
||
(void) DBTreeSrLabels(&scx, &DBAllButSpaceBits, 0, &tpath, TF_LABEL_ATTACH,
|
||
extHierLabelFunc, (ClientData) hy->hy_target->cu_def);
|
||
|
||
return (0);
|
||
}
|
||
|
||
int
|
||
extHierLabelFunc(scx, label, tpath, targetDef)
|
||
SearchContext *scx;
|
||
Label *label;
|
||
TerminalPath *tpath;
|
||
CellDef *targetDef;
|
||
{
|
||
char *srcp, *dstp;
|
||
Label *newlab;
|
||
int len;
|
||
|
||
/* Reject if the label falls over space */
|
||
if (label->lab_type == TT_SPACE)
|
||
return (0);
|
||
|
||
/* Reject if not a node label */
|
||
if (!extLabType(label->lab_text, LABTYPE_NAME))
|
||
return (0);
|
||
|
||
/* Determine size of new label with hierarchical name */
|
||
for (srcp = label->lab_text; *srcp++; )
|
||
/* Nothing */;
|
||
len = srcp - label->lab_text;
|
||
for (srcp = tpath->tp_first; *srcp++; )
|
||
/* Nothing */;
|
||
len += srcp - tpath->tp_first + 1;
|
||
|
||
/* Allocate new label at correct location */
|
||
newlab = (Label *) mallocMagic((unsigned) (sizeof (Label) + len - 4));
|
||
GeoTransRect(&scx->scx_trans, &label->lab_rect, &newlab->lab_rect);
|
||
newlab->lab_just = GeoTransPos(&scx->scx_trans, label->lab_just);
|
||
newlab->lab_type = label->lab_type;
|
||
newlab->lab_flags = label->lab_flags;
|
||
dstp = newlab->lab_text;
|
||
for (srcp = tpath->tp_first; *dstp++ = *srcp++; )
|
||
/* Nothing */;
|
||
for (--dstp, srcp = label->lab_text; *dstp++ = *srcp++; )
|
||
/* Nothing */;
|
||
|
||
newlab->lab_next = targetDef->cd_labels;
|
||
targetDef->cd_labels = newlab;
|
||
|
||
/* Add paint inside label if this is a subcircuit */
|
||
/* Caveat: If label has zero area, it will be extended by 1 unit */
|
||
|
||
// if (label->lab_flags & PORT_DIR_MASK)
|
||
// {
|
||
// int pNum;
|
||
//
|
||
// /* Is extending the label area valid in all cases? */
|
||
// if (newlab->lab_rect.r_xbot == newlab->lab_rect.r_xtop)
|
||
// newlab->lab_rect.r_xtop++;
|
||
// if (newlab->lab_rect.r_ybot == newlab->lab_rect.r_ytop)
|
||
// newlab->lab_rect.r_ytop++;
|
||
//
|
||
// pNum = DBPlane(newlab->lab_type);
|
||
// DBPaintPlane(targetDef->cd_planes[pNum], &newlab->lab_rect,
|
||
// DBStdPaintTbl(newlab->lab_type, pNum),
|
||
// (PaintUndoInfo *) NULL);
|
||
// }
|
||
|
||
return (0);
|
||
}
|