|
|
1.1 root 1: /*
2: %Z% %M% version %I% %Q%of %H% %T%
3: Last Delta: %G% %U% to %P%
4: */
5:
6: #include "cip.h"
7:
8: extern struct macro *macroList;
9: extern int nextMacroName;
10: extern Cursor hourglass;
11: extern char envfont[80];
12: extern void removeMacro ();
13:
14: struct thing *
15: newCircle(p)
16: Point p;
17: {
18: register struct thing *b;
19:
20: if ((b = (struct thing *) getSpace(sizeof(struct thing))) != TNULL) {
21: b->type = CIRCLE;
22: b->origin = p;
23: b->otherValues.radius = RADdefault;
24: BoundingBox(b);
25: b->arrow = 0;
26: }
27: return(b);
28: }
29:
30: struct thing *
31: newBox(r)
32: Rectangle r;
33: {
34: register struct thing *b;
35:
36: if ((b = (struct thing *) getSpace(sizeof(struct thing))) != TNULL) {
37: b->type = BOX;
38: b->origin = r.origin;
39: b->otherValues.corner = r.corner;
40: BoundingBox(b);
41: b->boorder = SOLID;
42: b->arrow = 0;
43: }
44: return(b);
45: }
46:
47: struct thing *
48: newEllipse(p)
49: Point p;
50: {
51: register struct thing *b;
52:
53: if ((b = (struct thing *) getSpace(sizeof(struct thing))) != TNULL) {
54: b->type = ELLIPSE;
55: b->origin = p;
56: b->otherValues.ellipse.ht = HTdefault;
57: b->otherValues.ellipse.wid = WIDdefault;
58: BoundingBox(b);
59: b->boorder = SOLID;
60: b->arrow = 0;
61: }
62: return(b);
63: }
64:
65: struct thing *
66: newLine(o,c)
67: Point o, c;
68: {
69: register struct thing *b;
70:
71: if ((b = (struct thing *) getSpace(sizeof(struct thing))) != TNULL) {
72: b->type = LINE;
73: b->origin = o;
74: b->otherValues.end = c;
75: BoundingBox(b);
76: b->boorder = SOLID;
77: b->arrow = 0;
78: }
79: return(b);
80: }
81:
82: struct thing *
83: newArc(s,e)
84: Point s, e;
85: {
86: register struct thing *b;
87:
88: if ((b = (struct thing *) getSpace(sizeof(struct thing))) != TNULL) {
89: b->type = ARC;
90: b->otherValues.arc.start = s;
91: b->otherValues.arc.end = e;
92: b->origin = computeArcOrigin(s,e);
93: BoundingBox(b);
94: b->boorder = SOLID;
95: b->arrow = 0;
96: }
97: return(b);
98: }
99:
100: struct thing *
101: newText(p,s)
102: Point p; char *s;
103: {
104: register struct thing *b; fontBlk *f;
105:
106: if ((b = (struct thing *) getSpace(sizeof(struct thing))) != TNULL) {
107: b->type = TEXT;
108: b->origin = p;
109: f = findFont(10,ROMAN);
110: b->otherValues.text.f = f;
111: b->otherValues.text.just = CENTER;
112: b->otherValues.text.s = s;
113: BoundingBox(b);
114: b->boorder = SOLID;
115: b->arrow = 0;
116: }
117: return(b);
118: }
119:
120: struct thing *
121: newSpline(u,s,p)
122: int u, s;
123: Point *p;
124: {
125: register struct thing *b;
126:
127: if ((b=(struct thing *) getSpace(sizeof(struct thing))) != TNULL) {
128: b->type = SPLINE;
129: b->origin = p[1];
130: b->otherValues.spline.used = u;
131: b->otherValues.spline.size = s;
132: b->otherValues.spline.plist = p;
133: BoundingBox(b);
134: b->boorder = SOLID;
135: b->arrow = 0;
136: }
137: return(b);
138: }
139:
140: struct thing *
141: newMacro(p,l)
142: Point p;
143: struct macro *l;
144: {
145: register struct thing *b;
146:
147: if ((b = (struct thing *) getSpace(sizeof(struct thing))) != TNULL) {
148: b->type = MACRO;
149: b->origin = p;
150: b->otherValues.list = l;
151: l->useCount++;
152: BoundingBox(b);
153: b->boorder = SOLID;
154: b->arrow = 0;
155: }
156: return(b);
157: }
158:
159:
160: struct thing *
161: insert(t,list)
162: register struct thing *t, *list;
163: {
164: if (t != TNULL) {
165: if (list!=TNULL) {
166: t->next = list;
167: t->last = list->last;
168: list->last->next = t;
169: list->last = t;
170: }
171: else {
172: t->last = t;
173: t->next = t;
174: }
175: return (t);
176: }
177: return(list);
178: }
179:
180: void
181: insertFont(t)
182: register fontBlk *t;
183: {
184: if (t != (fontBlk *) NULL) {
185: t->next = fonts;
186: t->last = fonts->last;
187: fonts->last->next = t;
188: fonts->last=t;
189: }
190: }
191:
192: struct thing *
193: remove(t)
194: register struct thing *t;
195: {
196: if (t != TNULL) {
197: t->last->next = t->next;
198: t->next->last = t->last;
199: }
200: return(( (t==TNULL) || (t==t->next)) ? TNULL : t->next);
201: }
202:
203: freeThingList (list)
204: struct thing *list;
205: {
206: register struct thing *t, *h;
207:
208: if ((h = list) != TNULL) {
209: do {
210: t = h;
211: h = h->next;
212: if (t->type == TEXT) {
213: free (t->otherValues.text.s);
214: }
215: free((char *) t);
216: } while (h != list);
217: }
218: }
219:
220: struct thing *
221: deleteThing(t,p)
222: register struct thing *t;
223: Point p;
224: {
225: register struct thing *t1;
226:
227: if (t!=TNULL) {
228: draw(t,p);
229: t1 = remove(t);
230: if (t->type==MACRO) {
231: if (--t->otherValues.list->useCount == 0) {
232: freeThingList (t->otherValues.list->parts);
233: removeMacro (t->otherValues.list);
234: }
235: }
236: else {
237: if (t->type==TEXT) {
238: t->otherValues.text.f->useCount--;
239: free (t->otherValues.text.s);
240: }
241: }
242: free((char *) t);
243: }
244: else {
245: t1 = t;
246: }
247: return(t1);
248: }
249:
250: struct thing *
251: deleteAllThings(list)
252: struct thing *list;
253: {
254: register struct macro *m;
255:
256: /* I don't use deleteThing() 'cuz I don't want to undraw them all */
257: freeThingList (list);
258: while (macroList != (struct macro *) NULL) {
259: m = macroList;
260: macroList = m->next;
261: freeThingList (m->parts);
262: free (m->name);
263: free(m);
264: }
265: nextMacroName = 0;
266: return(TNULL);
267: }
268:
269: struct thing *
270: selectThing(m,list)
271: Point m;
272: register struct thing *list;
273: {
274: register struct thing *t, *h = TNULL;
275: register int d, hd=0;
276:
277: if ((t = list) != TNULL) {
278: do {
279: d = distance(t->bb.origin,t->bb.corner);
280: if ( ptinrect(m,t->bb) && ((hd==0) || (d<hd)) ) {
281: h = t;
282: hd = d;
283: }
284: t=t->next;
285: } while (t != list);
286: }
287: return(h);
288: }
289:
290: int
291: distance(p,q)
292: Point p, q;
293: {
294: return ( norm(q.x-p.x,q.y-p.y,0) );
295: }
296:
297: BoundingBox(t)
298: register struct thing *t;
299: {
300: Point p, q, r;
301: register int i, h;
302: Font *f;
303:
304: if (t != TNULL) {
305: switch(t->type) {
306: case CIRCLE: {
307: p.x = t->otherValues.radius;
308: p.y = p.x;
309: t->bb.origin = sub(t->origin,p);
310: t->bb.corner = add(t->origin,p);
311: break;
312: }
313: case BOX: {
314: t->bb.origin = t->origin;
315: t->bb.corner = t->otherValues.corner;
316: break;
317: }
318: case ELLIPSE: {
319: p.x = (t->otherValues.ellipse.wid)>>1;
320: p.y = (t->otherValues.ellipse.ht)>>1;
321: t->bb.origin = sub(t->origin,p);
322: t->bb.corner = add(t->origin,p);
323: break;
324: }
325: case LINE: {
326: p = t->origin;
327: q = t->otherValues.end;
328: if (abs(p.x-q.x)<10) {
329: p.x -= nearlyStraight; q.x += nearlyStraight;
330: }
331: else {
332: if (abs(p.y-q.y)<10) {
333: p.y -= nearlyStraight; q.y += nearlyStraight;
334: }
335: }
336: t->bb = canon (p, q);
337: break;
338: }
339: case ARC: {
340: p = t->origin;
341: i = distance(p,t->otherValues.arc.start);
342: t->bb.origin = sub(p,Pt(i,i));
343: t->bb.corner = add(p,Pt(i,i));
344: break;
345: }
346: case TEXT: {
347: p = t->origin;
348: f = t->otherValues.text.f->f;
349: h = fontheight(f);
350: i = strwidth(f,t->otherValues.text.s);
351: switch(t->otherValues.text.just) {
352: case CENTER: {
353: t->bb.origin = sub(p,Pt(i>>1,0));
354: t->bb.corner = add(p,Pt(i>>1,h));
355: break;
356: }
357: case LEFTJUST: {
358: t->bb.origin = p;
359: t->bb.corner = add(p,Pt(i,h));
360: break;
361: }
362: case RIGHTJUST: {
363: t->bb.origin = sub(p,Pt(i,0));
364: t->bb.corner = add(p,Pt(0,h));
365: break;
366: }
367: }
368: break;
369: }
370: case SPLINE: {
371: p.x = Xmin; p.y=YPIC; q.x=Xmax; q.y=YBOT;
372: for (i=1; i<t->otherValues.spline.used; i++) {
373: r = t->otherValues.spline.plist[i];
374: p.x = max(p.x,r.x); p.y = max(p.y,r.y);
375: q.x = min(q.x,r.x); q.y = min(q.y,r.y);
376: }
377: t->bb.origin = q;
378: t->bb.corner = p;
379: break;
380: }
381: case MACRO: {
382: t->bb.origin = add(t->origin,t->otherValues.list->bb.origin);
383: t->bb.corner = add(t->origin,t->otherValues.list->bb.corner);
384: break;
385: }
386: }
387: }
388: }
389:
390: Point
391: computeArcOrigin(s,e)
392: Point s,e;
393: {
394: Point t;
395:
396: if (e.x<s.x) { /*swap s and e */
397: t=s; s=e; e=t;
398: }
399: return( div(add(add(e,Pt(s.y-e.y,e.x-s.x)),s),2) );
400: }
401:
402: /* This routine searches the list pointed to by the global 'fonts' */
403: /* for a font with point size s and type n. If it can't find that */
404: /* font then defont is used. */
405: /* Special case: If the user runs out of space, then the first */
406: /* entry, which is always defont, is used. This will allow the */
407: /* user to write out the file with the font description intact. */
408:
409: fontBlk *
410: findFont(s,n)
411: register short s; /* Point size of desired font */
412: register short n; /* Type of font - ROMAN, BOLD, ITALICS */
413: {
414: register fontBlk *f;
415: register int i;
416: register char c, fn[50];
417:
418: f = fonts->next; /* Skip over defont entry */
419: while (f != fonts) {
420: if (f->ps == s && f->num == n) {
421: break;
422: }
423: f = f->next;
424: }
425: if (f==fonts) { /* This is always defont */
426: if ((f=(fontBlk *)getSpace(sizeof(fontBlk))) == (fontBlk *)NULL) {
427: f = fonts; /* Use defont if there is no room */
428: }
429: else {
430: free (f);
431: f = fonts;
432: /*
433: cursswitch(&hourglass);
434: c = (n==ROMAN) ? 'R' : ((n==ITALIC) ? 'I' : 'B');
435: i = s+1;
436: do {
437: sprintf(fn,"%c.%d",c,--i);
438: } while ((i>0) && (access(fn,4)!=0));
439: if ((f->f = (i==0) ? &defont : getfont(fn)) == (Font *) NULL) {
440: free (f);
441: f = fonts;
442: outOfSpace ();
443: }
444: else {
445: insertFont(f);
446: f->ps = s;
447: f->num = n;
448: f->useCount = 0;
449: }
450: cursSwitch();
451: */
452: }
453: }
454: f->useCount++;
455: return(f);
456: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.