|
|
1.1 ! root 1: /******************************************************************* ! 2: * * ! 3: * File: CIFPLOT/edges.c * ! 4: * Written by Dan Fitzpatrick * ! 5: * copyright 1980 -- Regents of the University of California * ! 6: * * ! 7: ********************************************************************/ ! 8: ! 9: #include <stdio.h> ! 10: #include "defs.h" ! 11: #include "globals.h" ! 12: #include "parser_defs.h" ! 13: #include "structs.h" ! 14: #include "out_structs.h" ! 15: #include <math.h> ! 16: #include "alloc.h" ! 17: ! 18: IMPORT point *MakePoint(); ! 19: IMPORT point *TransPt(); ! 20: IMPORT Command *MakeFlash(); ! 21: IMPORT Command *MakeBox(); ! 22: IMPORT transform *MatrixMult(); ! 23: IMPORT transform *Translate(); ! 24: IMPORT real ICompare(); ! 25: IMPORT real TCompare(); ! 26: IMPORT StartEdgePath(); ! 27: IMPORT iedge *NextEdgePath(); ! 28: IMPORT iedge *EndEdgePath(); ! 29: ! 30: FORWARD iedge *MakeEdge(); ! 31: FORWARD PolyDesc *MakeDesc(); ! 32: FORWARD instance *MakeItem(); ! 33: ! 34: Instanciate(c,trans,n) ! 35: Command *c; ! 36: transform *trans; ! 37: int n; ! 38: { ! 39: instance *i; ! 40: Command *p; ! 41: real x,y,xmin,ymin; ! 42: ! 43: if(c->type != SYMBOL) ! 44: Error("Tried to Instanciate a Non-Symbol",INTERNAL); ! 45: if(depth == 0 || n <= depth) { ! 46: for(p=c->Ctype.Symbl.CStart; p!=NIL; p=p->CLink) { ! 47: i = MakeItem(p,trans,n+1); ! 48: Selector(i); ! 49: } ! 50: if(symbox) DrawBBox(&(c->CBBox),trans); ! 51: if(*(c->Ctype.Symbl.SName) == '\0') return; ! 52: xmin = c->CBBox.xmin; ymin = c->CBBox.ymin; ! 53: Trans(&xmin,&ymin,trans); ! 54: ! 55: x = c->CBBox.xmax; y = c->CBBox.ymin; ! 56: Trans(&x,&y,trans); ! 57: if(x+y < xmin+ymin) { ymin = y; xmin = x; } ! 58: ! 59: x = c->CBBox.xmax; y = c->CBBox.ymax; ! 60: Trans(&x,&y,trans); ! 61: if(x+y < xmin+ymin) { ymin = y; xmin = x; } ! 62: ! 63: x = c->CBBox.xmin; y = c->CBBox.ymax; ! 64: Trans(&x,&y,trans); ! 65: if(x+y < xmin+ymin) { ymin = y; xmin = x; } ! 66: ! 67: ClipText(c->Ctype.Symbl.SName,xmin,ymin,'S'); ! 68: } ! 69: else { /* Don't instanciate this symbol; just draw box and name*/ ! 70: DrawBBox(&(c->CBBox),trans); ! 71: if(*(c->Ctype.Symbl.SName) == '\0') return; ! 72: xmin = c->CBBox.xmin; ymin = c->CBBox.ymin; ! 73: Trans(&xmin,&ymin,trans); ! 74: x = c->CBBox.xmax; y = c->CBBox.ymax; ! 75: Trans(&x,&y,trans); ! 76: x = (xmin+x)/2; y = (ymin+y)/2; ! 77: ClipText(c->Ctype.Symbl.SName,x,y,'C'); ! 78: } ! 79: } ! 80: ! 81: Activate(i) ! 82: instance *i; ! 83: { ! 84: switch(i->type) { ! 85: case CALL: ! 86: { transform *t; ! 87: t = MatrixMult(i->item->Ctype.Call.trans,i->trans); ! 88: Instanciate(i->item->Ctype.Call.CSymb,t,i->depth); ! 89: } ! 90: FreeItem(i); ! 91: break; ! 92: case ARRAY: ! 93: { int j,k; ! 94: point pt; ! 95: transform *trans,*t; ! 96: instance *inst; ! 97: ! 98: pt.x = 0.0; ! 99: for(j=0; j<i->item->Ctype.Array.Am; j++) { ! 100: pt.y = 0.0; ! 101: for(k=0; k<i->item->Ctype.Array.An; k++) { ! 102: trans = Translate(&pt,ident); ! 103: t = MatrixMult(trans,i->trans); ! 104: FreeTransform(trans); ! 105: inst = MakeItem(i->item->Ctype.Array.ACom,t,i->depth); ! 106: Selector(inst); ! 107: pt.y += i->item->Ctype.Array.Ady; ! 108: } ! 109: pt.x += i->item->Ctype.Array.Adx; ! 110: } ! 111: } ! 112: break; ! 113: case POLYGON: ! 114: { PolyDesc *poly; ! 115: PointList *path; ! 116: iedge *e; ! 117: point *pt; ! 118: ! 119: poly = MakeDesc(i->item); ! 120: path = i->item->Ctype.Path; ! 121: pt = &(path->pt); ! 122: StartEdgePath(pt->x,pt->y,i->trans,poly); ! 123: /* Assertion: there are at least two points ! 124: * in every polygon */ ! 125: for(path = path->PLink; path != NIL; path = path->PLink){ ! 126: pt = &(path->pt); ! 127: e = NextEdgePath(pt->x,pt->y); ! 128: Selector(e); ! 129: } ! 130: e = EndEdgePath(); ! 131: Selector(e); ! 132: } ! 133: FreeItem(i); ! 134: break; ! 135: case BOX: ! 136: { PolyDesc *poly; ! 137: point *d; ! 138: real ly,lx,wx,wy,cx,cy,c; ! 139: iedge *e; ! 140: ! 141: poly = MakeDesc(i->item); ! 142: d = &(i->item->Ctype.Box.bdirect); ! 143: c = sqrt(d->x*d->x + d->y*d->y); ! 144: cx = i->item->Ctype.Box.bcenter.x; ! 145: cy = i->item->Ctype.Box.bcenter.y; ! 146: lx = (d->x*i->item->Ctype.Box.blength)/(c*2.0); ! 147: ly = (d->y*i->item->Ctype.Box.blength)/(c*2.0); ! 148: wx = -(d->y*i->item->Ctype.Box.bwidth)/(c*2.0); ! 149: wy = (d->x*i->item->Ctype.Box.bwidth)/(c*2.0); ! 150: StartEdgePath(cx-lx-wx,cy-ly-wy,i->trans,poly); ! 151: e = NextEdgePath(cx-lx+wx,cy-ly+wy); ! 152: Selector(e); ! 153: e = NextEdgePath(cx+lx+wx,cy+ly+wy); ! 154: Selector(e); ! 155: e = NextEdgePath(cx+lx-wx,cy+ly-wy); ! 156: Selector(e); ! 157: e = EndEdgePath(); ! 158: Selector(e); ! 159: /* ! 160: e = MakeEdge(cx-lx-wx,cy-ly-wy,cx-lx+wx,cy-ly+wy,i->trans,poly); ! 161: Selector(e); ! 162: e = MakeEdge(cx-lx+wx,cy-ly+wy,cx+lx+wx,cy+ly+wy,i->trans,poly); ! 163: Selector(e); ! 164: e = MakeEdge(cx+lx+wx,cy+ly+wy,cx+lx-wx,cy+ly-wy,i->trans,poly); ! 165: Selector(e); ! 166: e = MakeEdge(cx+lx-wx,cy+ly-wy,cx-lx-wx,cy-ly-wy,i->trans,poly); ! 167: Selector(e); ! 168: */ ! 169: FreeItem(i); ! 170: } ! 171: break; ! 172: case FLASH: ! 173: { PolyDesc *poly; ! 174: ! 175: poly = MakeDesc(i->item); ! 176: MakeNgon(circle,&(i->item->Ctype.Flash.fcenter),i->item->Ctype.Flash.fdia/2.0,i->trans,poly); ! 177: } ! 178: FreeItem(i); ! 179: break; ! 180: case WIRE: ! 181: { real width; ! 182: PointList *p1,*p2; ! 183: Command *com; ! 184: instance *inst; ! 185: point *dir,*cen; ! 186: real x,y; ! 187: int level; ! 188: ! 189: if(i->item->Ctype.Wire.WIns == NIL) { ! 190: width = i->item->Ctype.Wire.WWidth; ! 191: level = i->item->level; ! 192: p1 = i->item->Ctype.Wire.WPath; ! 193: com = MakeFlash(width,&(p1->pt)); ! 194: com->level = level; ! 195: com->CLink = NIL; ! 196: i->item->Ctype.Wire.WIns = com; ! 197: inst = MakeItem(com,i->trans,i->depth); ! 198: Selector(inst); ! 199: for((p2=p1,p1=p1->PLink);p1 != NIL;(p2=p1,p1=p1->PLink)) { ! 200: x = p1->pt.x - p2->pt.x; y = p1->pt.y - p2->pt.y; ! 201: com = MakeFlash(width,&(p1->pt)); ! 202: com->level = level; ! 203: com->CLink = i->item->Ctype.Wire.WIns; ! 204: i->item->Ctype.Wire.WIns = com; ! 205: inst = MakeItem(com,i->trans,i->depth); ! 206: Selector(inst); ! 207: ! 208: dir = MakePoint(x,y); ! 209: cen = MakePoint((p1->pt.x + p2->pt.x)/2.0,(p1->pt.y + p2->pt.y)/2.0); ! 210: com = MakeBox(sqrt(x*x+y*y),width,cen,dir); ! 211: com->level = level; ! 212: com->CLink = i->item->Ctype.Wire.WIns; ! 213: i->item->Ctype.Wire.WIns = com; ! 214: inst = MakeItem(com,i->trans,i->depth); ! 215: Selector(inst); ! 216: Free(cen); Free(dir); ! 217: } ! 218: } ! 219: else { ! 220: for(com=i->item->Ctype.Wire.WIns;com!=NIL;com=com->CLink) { ! 221: inst = MakeItem(com,i->trans,i->depth); ! 222: Selector(inst); ! 223: } ! 224: } ! 225: } ! 226: FreeItem(i); ! 227: break; ! 228: case EDGE: ! 229: Clip(i); ! 230: if(--(((iedge *) i)->poly->refs) == 0) ! 231: FreeDesc(((iedge *) i)->poly); ! 232: FreeIEdge(i); ! 233: break; ! 234: case POINTNAME: ! 235: { real x,y; ! 236: x = i->item->Ctype.PointName.loc.x; ! 237: y = i->item->Ctype.PointName.loc.y; ! 238: Trans(&x,&y,i->trans); ! 239: if(!extractor) ! 240: ClipText(i->item->Ctype.PointName.Name,x,y,'T'); ! 241: else ! 242: OutputExtPoint(x,y,i->item->Ctype.PointName.Name, ! 243: i->item->level); ! 244: } ! 245: break; ! 246: case STEXT: ! 247: { real x,y; ! 248: Command *icom; ! 249: icom = (Command *) i; ! 250: ! 251: x = icom->Ctype.PointName.loc.x; ! 252: y = icom->Ctype.PointName.loc.y; ! 253: ClipText(icom->Ctype.PointName.Name,x,y,'T'); ! 254: FreeStif(icom); ! 255: } ! 256: break; ! 257: case VECTOR: ! 258: { Command *icom; ! 259: PointList *p1,*p2; ! 260: icom = (Command *) i; ! 261: ! 262: p1 = icom->Ctype.Path; ! 263: if(p1 == NIL) Error("Vector has null path in edge",INTERNAL); ! 264: for((p2=p1,p1=p1->PLink); p1 != NIL;(p2=p1,p1=p1->PLink)) { ! 265: MakeLine(p1->pt.x,p1->pt.y,p2->pt.x,p2->pt.y,ident); ! 266: } ! 267: FreeStif(icom); ! 268: } ! 269: break; ! 270: case SPOLYGON: ! 271: { PolyDesc *poly; ! 272: PointList *path; ! 273: iedge *e; ! 274: point *pt; ! 275: Command *icom; ! 276: icom = (Command *) i; ! 277: i = (instance *) 0xffffffff; /* debugging */ ! 278: ! 279: poly = MakeDesc(icom); ! 280: path = icom->Ctype.Path; ! 281: pt = &(path->pt); ! 282: StartEdgePath(pt->x,pt->y,ident,poly); ! 283: /* Assertion: there are at least two points ! 284: * in every polygon */ ! 285: for(path = path->PLink; path != NIL; path = path->PLink){ ! 286: pt = &(path->pt); ! 287: e = NextEdgePath(pt->x,pt->y); ! 288: Selector(e); ! 289: } ! 290: e = EndEdgePath(); ! 291: Selector(e); ! 292: FreeStif(icom); ! 293: } ! 294: break; ! 295: case SFLASH: ! 296: { PolyDesc *poly; ! 297: Command *icom; ! 298: icom = (Command *) i; ! 299: i = (instance *) 0xffffffff; /* debugging */ ! 300: ! 301: poly = MakeDesc(icom); ! 302: MakeNgon(circle,&(icom->Ctype.Flash.fcenter),icom->Ctype.Flash.fdia/2.0,ident,poly); ! 303: FreeStif(icom); ! 304: } ! 305: break; ! 306: case SWIRE: ! 307: { real width; ! 308: PointList *p1,*p2; ! 309: Command *ncom; ! 310: instance *inst; ! 311: point *dir,*cen; ! 312: real x,y; ! 313: int level; ! 314: Command *icom; ! 315: icom = (Command *) i; ! 316: i = (instance *) 0xffffffff; /* debugging */ ! 317: ! 318: width = icom->Ctype.Wire.WWidth; ! 319: level = icom->level; ! 320: p1 = icom->Ctype.Wire.WPath; ! 321: ncom = MakeFlash(width,&(p1->pt)); ! 322: ncom->level = level; ! 323: ncom->CLink = NIL; ! 324: inst = MakeItem(ncom,ident,0); ! 325: Selector(inst); ! 326: for((p2=p1,p1=p1->PLink);p1 != NIL;(p2=p1,p1=p1->PLink)) { ! 327: x = p1->pt.x - p2->pt.x; y = p1->pt.y - p2->pt.y; ! 328: ncom = MakeFlash(width,&(p1->pt)); ! 329: ncom->level = level; ! 330: inst = MakeItem(ncom,ident,0); ! 331: Selector(inst); ! 332: ! 333: dir = MakePoint(x,y); ! 334: cen = MakePoint((p1->pt.x + p2->pt.x)/2.0,(p1->pt.y + p2->pt.y)/2.0); ! 335: ncom = MakeBox(sqrt(x*x+y*y),width,cen,dir); ! 336: ncom->level = level; ! 337: inst = MakeItem(ncom,ident,0); ! 338: Selector(inst); ! 339: Free(cen); Free(dir); ! 340: } ! 341: FreeStif(icom); ! 342: } ! 343: break; ! 344: case SCALL: ! 345: StifCall(i); ! 346: FreeStif(i); ! 347: break; ! 348: default: ! 349: Error("Tried to Activate Unknown type",INTERNAL); ! 350: } ! 351: } ! 352: ! 353: instance * ! 354: MakeItem(c,trans,n) ! 355: Command *c; ! 356: transform *trans; ! 357: int n; ! 358: { ! 359: instance *i; ! 360: ! 361: i = GetItem(); ! 362: i->type = c->type; ! 363: i->Link = NIL; ! 364: i->trans = trans; ! 365: trans->refs++; ! 366: i->item = c; ! 367: i->depth = n; ! 368: return(i); ! 369: } ! 370: ! 371: iedge * ! 372: MakeEdge(rx1,ry1,rx2,ry2,trans,poly) ! 373: real rx1,rx2,ry1,ry2; ! 374: transform *trans; ! 375: PolyDesc *poly; ! 376: { ! 377: iedge *e; ! 378: real t; ! 379: ! 380: e = GetIEdge(); ! 381: e->type = EDGE; ! 382: e->poly = poly; ! 383: (poly->refs)++; ! 384: Trans(&rx1,&ry1,trans); ! 385: Trans(&rx2,&ry2,trans); ! 386: if(rx1 <= rx2) e->dir = 1; ! 387: else { e->dir = -1; ! 388: SWAP(rx1,rx2,t); ! 389: SWAP(ry1,ry2,t); ! 390: } ! 391: /* Now rx1 <= rx2 and the direction is set */ ! 392: /* Now convert from CIF units to plotter units */ ! 393: e->x1 = CONVERT(rx1); e->y1 = CONVERT(ry1); ! 394: e->x2 = CONVERT(rx2); e->y2 = CONVERT(ry2); ! 395: e->min = CONVERT(rx1); ! 396: return(e); ! 397: } ! 398: ! 399: PolyDesc * ! 400: MakeDesc(c) ! 401: Command *c; ! 402: { ! 403: PolyDesc *p; ! 404: ! 405: p = GetDesc(); ! 406: if(c != NIL) ! 407: p->level = c->level; ! 408: else ! 409: p->level = 0; ! 410: p->count = 0; ! 411: p->refs = 0; ! 412: return(p); ! 413: } ! 414: ! 415: /* ! 416: FreeInstance(i) ! 417: instance *i; ! 418: { ! 419: if(--(i->trans->refs) == 0) FreeTransform(i->trans); ! 420: FreeItem(i); ! 421: } ! 422: */ ! 423:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.