home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
gdead.berkeley.edu
/
gdead.berkeley.edu.tar
/
gdead.berkeley.edu
/
pub
/
cad-tools
/
ciftomann.tar
/
flatten.c
< prev
next >
Wrap
C/C++ Source or Header
|
1988-01-28
|
6KB
|
324 lines
#include "ciftomann.h"
#include "fd.h"
#include <signal.h>
#undef INFINITY
#include "cd.h"
#define HORIZONTAL 0
#define VERTICAL 1
#define IDENTICAL 2
#define NON_MANHATTEN 3
char *dirname = "fltXXXXXX";
char cmd[60];
char *cif_file_name;
/*
* flatten uses Ken Keller's CD package to recursively
* expand each call of a cell into the actual geometry.
* The result is written onto standard output for edger
* to break up into edges
*/
main(argc,argv)
int argc;
char **argv;
{
char *tempname = "fltXXXXXX";
int layer, status;
struct s *SymbolDesc;
cif_file_name = argv[1];
catch_signals();
TInit();
CDInit();
mktemp(tempname);
/* convert the cif into CD's file format */
if (CDParseCIF(tempname, cif_file_name, 'n') != True) {
fprintf(stderr,"flatten : Error in cif file : %s : %s\n",
cif_file_name, CDStatusString);
terminate();
}
CDOpen(tempname,&SymbolDesc,'r');
if (CDStatusInt == CDNEWSYMBOL) {
fprintf(stderr,
"flatten : Parse of the cif failed: CD got confused\n");
terminate();
}
if (CDStatusInt == CDPARSEFAILED) {
fprintf(stderr,"flatten : Error in cif file (%d) : %s\n",
CDStatusInt, CDStatusString);
terminate();
}
for (layer = 1; layer <= CDNUMLAYERS; layer++) {
if (CDLayer[layer].lTechnology != ' ') {
int i;
printf("L %c",CDLayer[layer].lTechnology);
for(i=0;CDLayer[layer].lMask[i] != ' ' && i < 3;i++) {
putchar(CDLayer[layer].lMask[i]);
}
printf(";\n");
Flatten(tempname,layer);
}
}
printf("E\n");
exit(0);
}
/*
* this is the main routine, called recursively on each cell
* call
*/
Flatten(SymbolName,layer)
char * SymbolName;
int layer;
{
struct s *SymbolDesc;
char *Master;
char Type;
int junk;
int X,Y;
struct g *GenDesc;
struct o *Pointer;
struct t *TGen;
CDOpen(SymbolName,&SymbolDesc,'w');
if (CDStatusInt == CDPARSEFAILED)
fprintf(stderr,"flatten : Error in cell \"%s\" : %s\n",
SymbolName, CDStatusString);
CDInitGen(SymbolDesc,0,-INFINITY,-INFINITY,INFINITY,INFINITY
,&GenDesc);
/* handle all of the cell calls */
for(;;) {
CDGen(SymbolDesc,GenDesc,&Pointer);
if (Pointer == NULL)
break;
TPush();
TIdentity();
CDCall(Pointer,&Master,&junk,&junk,&junk,&junk);
CDInitTGen(Pointer,&TGen);
for(;;) {
CDTGen(&TGen,&Type,&X,&Y);
if (TGen == NULL)
break;
switch (Type) {
case 't' :
TTranslate(X,Y);
break;
case 'r' :
TRotate(X,Y);
break;
case 'x' :
TMX();
break;
case 'y' :
TMY();
break;
}/*switch*/
}
TPremultiply();
Flatten(Master,layer);
TPop();
} /* instances */
/* handle all the geometry in the cell */
ProcessLayer(SymbolDesc,layer);
}
#define Scale(value) (*(value) = (CDDesc.dDSA*(*(value)))/CDDesc.dDSB)
ProcessLayer(SymbolDesc,layer)
struct s *SymbolDesc;
int layer;
{
struct p *Path;
struct o *Pointer;
struct g *GenDesc;
int junk;
int Width;
int X,Y,Xdir,Ydir,H,W;
int ZeroX,ZeroY;
char Type;
if (CDInitGen(SymbolDesc,layer,(int)-INFINITY,(int)-INFINITY,
(int)INFINITY,(int)INFINITY,&GenDesc) == False) {
fprintf(stderr, "CDInitGen, malloc failed\n");
}
for(;;) {
CDGen(SymbolDesc,GenDesc,&Pointer);
if (Pointer == NULL)
break;
CDType(Pointer,&Type);
switch (Type) {
case CDBOX :
CDBox(Pointer,&junk,&W,&H,&X,&Y);
TPoint(&X,&Y);
ZeroX = ZeroY = 0;
TPoint(&ZeroX,&ZeroY);
Xdir = 1; Ydir = 0;
TPoint(&Xdir,&Ydir);
Xdir -= ZeroX;
Ydir -= ZeroY;
Scale(&X); Scale(&Y); Scale(&W); Scale(&H);
MakeBox(X,Y,W,H,Xdir,Ydir);
break;
case CDWIRE :
CDWire(Pointer,&junk,&Width,&Path);
Scale(&Width);
MakeWire(Width,Path);
break;
case CDROUNDFLASH :
CDRoundFlash(Pointer,&junk,&Width, &X,&Y);
TPoint(&X,&Y);
Scale(&X); Scale(&Y); Scale(&Width);
MakeCircle(Width,X,Y);
break;
case CDLABEL :
break;
case CDPOLYGON :
CDPolygon(Pointer,&junk,&Path);
MakePolygon(Path);
break;
default :
fprintf(stderr,"Flattener : Unknown type %c\n",
Type);
}
} /* geoms */
}
/*
* all of the following routines convert the data returned by
* CD into the various (ASCII) CIF constructs
*/
MakeBox(X,Y,W,H,Xdir,Ydir)
int X,Y,W,H,Xdir,Ydir;
{
/* throw away zero width boxes */
if (W == 0 || H == 0) {
return;
}
printf("B %d %d %d %d %d %d;\n",W,H,X,Y,Xdir,Ydir);
}
MakePolygon(pathlist)
struct p *pathlist;
{
struct p path;
path = *pathlist;
TPoint(&(path.pX),&(path.pY));
Scale(&(path.pX)); Scale(&(path.pY));
printf("P %d %d",path.pX,path.pY);
while (path.pSucc != 0) {
path = *path.pSucc;
TPoint(&(path.pX),&(path.pY));
Scale(&(path.pX)); Scale(&(path.pY));
printf(" %d %d",path.pX,path.pY);
}
printf(";\n");
}
MakeWire(Width,pathlist)
int Width;
struct p *pathlist;
{
struct p path;
if (Width == 0) {
return;
}
path = *pathlist;
TPoint(&(path.pX),&(path.pY));
Scale(&(path.pX)); Scale(&(path.pY));
if (path.pSucc == 0) {
MakeCircle(Width,path.pX,path.pY);
return;
}
printf("W %d %d %d",Width,path.pX,path.pY);
while (path.pSucc != 0) {
path = *path.pSucc;
TPoint(&(path.pX),&(path.pY));
Scale(&(path.pX)); Scale(&(path.pY));
printf(" %d %d",path.pX,path.pY);
}
printf(";\n");
}
MakeCircle(Diameter,X,Y)
int Diameter,X,Y;
{
printf("R %d %d %d;\n",Diameter,X,Y);
}
terminate()
{
exit(1);
}
catch_signals()
{
if (signal(SIGHUP, SIG_IGN) != SIG_IGN) {
signal(SIGHUP, terminate);
}
if (signal(SIGINT, SIG_IGN) != SIG_IGN) {
signal(SIGINT, terminate);
}
signal(SIGPIPE, terminate);
signal(SIGTERM, terminate);
}