|
|
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.