|
|
1.1 root 1: /* Copyright (c) 1988 AT&T */
2: /* All Rights Reserved */
3:
4: /* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T */
5: /* The copyright notice above does not evidence any */
6: /* actual or intended publication of such source code. */
7:
8: /* @(#)picasso:attrs.c 1.0 */
9: #include "picasso.h"
10: #include "y.tab.h"
11:
12: setdir(n) /* set direction (hvmode) from LEFT, RIGHT, etc. */
13: int n;
14: {
15: switch (n) {
16: case UP: hvmode = U_DIR; break;
17: case DOWN: hvmode = D_DIR; break;
18: case LEFT: hvmode = L_DIR; break;
19: case RIGHT: hvmode = R_DIR; break;
20: /* case REVERSE: hvmode = (hvmode+2)%4; break; */
21: }
22: return(hvmode);
23: }
24:
25: curdir() /* convert current dir (hvmode) to RIGHT, LEFT, etc. */
26: {
27: switch (hvmode) {
28: case R_DIR: return RIGHT;
29: case L_DIR: return LEFT;
30: case U_DIR: return UP;
31: case D_DIR: return DOWN;
32: }
33: yyerror("can't happen curdir");
34: }
35:
36: double setrgbindex () /* returns integer-valued index to (r,g,b) */
37: {
38: int n;
39:
40: if (nexpr > 3)
41: yyerror("color components are r, g, b only; excess ignored");
42: for (n = 0; n < 3; ++n) {
43: if (n >= nexpr)
44: exprlist[n] = 0;
45: else if (exprlist[n] < 0 || exprlist[n] > 1) {
46: yyerror("color component %g not between 0 and 1",
47: exprlist[n]);
48: nexpr = 0;
49: return 0;
50: }
51: }
52: nexpr = 0;
53: for (n = nrgb; n--;)
54: if (exprlist[0] == rgbtable[n].r && /* backwards in case */
55: exprlist[1] == rgbtable[n].g && /* there's locality. */
56: exprlist[2] == rgbtable[n].b) {
57: return ((double)n);
58: }
59: if (nrgb >= nrgbtable)
60: rgbtable = (rgb *) grow((char *)rgbtable, "rgbtable",
61: nrgbtable += 100, sizeof(rgb));
62: rgbtable[nrgb].r = exprlist[0];
63: rgbtable[nrgb].g = exprlist[1];
64: rgbtable[nrgb].b = exprlist[2];
65: return ((double)nrgb++);
66: }
67:
68: double
69: checkcolor (f) /* gray level OR negative integer rgb index */
70: double f;
71: {
72: /* if (f < 0.0 || (f > 1.0 && f != (double)((int)f)))
73: { yyerror("gray level %g not between 0 and 1", f); f = -1.0; }
74: */ if (f > 1.0 || f < 0.0)
75: f = (double)((int)f);
76: if (f < -1.0)
77: f = -1.0; /* end of change */
78: else if (f >= nrgb)
79: { yyerror("rgb color index %g not defined", f); f = -1.0; }
80: return f;
81: }
82:
83: makefattr(type, sub, f) /* float attr */
84: int type, sub;
85: double f;
86: {
87: YYSTYPE val;
88: val.f = f;
89: makeattr(type, sub, val);
90: }
91:
92: makeoattr(type, o) /* obj* attr */
93: obj *o;
94: {
95: YYSTYPE val;
96: val.o = o;
97: makeattr(type, 0, val);
98: }
99:
100: makeiattr(type, i) /* int attr */
101: int i;
102: {
103: YYSTYPE val;
104: val.i = i;
105: makeattr(type, 0, val);
106: }
107:
108: int def_textattr = CENTER;
109:
110: maketattr(sub, p) /* text attribute: takes two */
111: char *p;
112: {
113: YYSTYPE val;
114: val.p = p;
115: if (sub == 0)
116: sub = def_textattr;
117: else if (sub & (CENTER|LJUST|RJUST))
118: def_textattr = (def_textattr & ~(CENTER|LJUST|RJUST)) | sub;
119: else if (sub & (ABOVE|BELOW))
120: def_textattr = (def_textattr & ~(ABOVE|BELOW)) | sub;
121: makeattr(TEXTATTR, sub, val);
122: }
123:
124: addtattr(sub) /* add text attrib to existing item */
125: {
126: attr[nattr-1].a_sub |= sub;
127: /* def_textattr != sub; looks like a bug and should be */
128: def_textattr |= sub;
129: }
130:
131: makevattr(p) /* varname attribute */
132: char *p;
133: {
134: YYSTYPE val;
135:
136: val.p = p;
137: makeattr(VARNAME, 0, val);
138: }
139:
140: makelattr(p, q) /* "locus" attribute; x and y coordinate lists via varnames */
141: char *p, *q;
142: {
143: YYSTYPE val;
144: val.p = p;
145: makeattr(XLIST, 0, val);
146: val.p = q;
147: makeattr(YLIST, 0, val);
148: }
149:
150: makedattr(name) /* dash pattern (array of dash/space widths) */
151: char *name;
152: {
153: int n;
154: struct symtab *p;
155: YYSTYPE val;
156:
157: if (name) {
158: if ((p = lookup(name)) == NULL) {
159: yyerror("no variable named %s", name);
160: return;
161: }
162: n = p->s_dim+1;
163: }
164: else {
165: n = nexpr;
166: nexpr = 0;
167: }
168: if ((val.a = (float *)malloc(sizeof(float)*(n+1))) == NULL)
169: yyerror("out of room in makedattr");
170: else {
171: val.a[0] = (float)n;
172: while (n--)
173: val.a[n+1] = (name? p->s_val.a[n] : exprlist[n]);
174: }
175: makeattr(DASHPAT, 0, val);
176: }
177:
178: makeattr(type, sub, val) /* add attribute type and val */
179: int type, sub;
180: YYSTYPE val;
181: {
182: if (type == 0 && val.i == 0) { /* clear table for next stat */
183: nattr = 0;
184: def_textattr = CENTER;
185: return;
186: }
187: if (nattr >= nattrlist)
188: attr = (Attr *) grow((char *)attr, "attr", nattrlist += 100,
189: sizeof(Attr));
190: attr[nattr].a_type = type;
191: attr[nattr].a_sub = sub;
192: attr[nattr].a_val = val;
193: nattr++;
194: }
195:
196: double setattr(p, type, val)
197: obj *p;
198: int type;
199: double val;
200: {
201: int cw_switch;
202: double x, y;
203: obj *q;
204:
205: if (p->o_type == BLOCK) {
206: for (q = p->o_next; q != p->o_val[N_VAL].o; q = q->o_next)
207: setattr (q, type, val);
208: }
209: else if (p->o_type <= TEXT) switch (type) {
210:
211: case TCOLOR: if (val >= 0.0 || checkcolor(val) >= 0.0)
212: p->o_text = val;
213: break;
214: case LCOLOR: if (val >= 0.0 || checkcolor(val) >= 0.0)
215: p->o_color = val;
216: break;
217: case PCOLOR: if (val < 0.0 || checkcolor(val) < 0.0)
218: p->o_attr &= ~FILLED;
219: else {
220: p->o_fill = val; /* ignored for TEXT? */
221: p->o_attr |= FILLED;
222: }
223: break;
224: case LAYER: if (val < -128) val = -128; else if (val > 127) val = 127;
225: p->o_layer = (short)val;
226: if (val > getfval("maxlayer"))
227: setfval ("maxlayer", val);
228: break;
229: case LWEIGHT: p->o_weight = val;
230: break;
231: case NOEDGE: if (val != 0.0)
232: p->o_attr &= ~EDGED;
233: else
234: p->o_attr |= EDGED;
235: break;
236:
237: case CCW:
238: case CW: if (p->o_type == ARC) {
239: cw_switch = (p->o_attr & CW_ARC);
240: if (type == CW)
241: cw_switch = !cw_switch;
242: if (cw_switch) {
243: x = p->o_val[N_VAL+2].f;
244: y = p->o_val[N_VAL+3].f;
245: p->o_val[N_VAL+2] = p->o_val[N_VAL+4];
246: p->o_val[N_VAL+3] = p->o_val[N_VAL+5];
247: /* exchange from & to */ p->o_val[N_VAL+4].f = x;
248: p->o_val[N_VAL+5].f = y;
249: p->o_attr ^= (p->o_attr & CW_ARC);
250: }
251: }
252: break;
253: case DIAMETER: val /= 2;
254: case RADIUS: switch (p->o_type) {
255: case ARROW:
256: case LINE:
257: case BOX:
258: case ARC:
259: case SECTOR: p->o_val[N_VAL].f = val;
260: break;
261: case CIRCLE:
262: case ELLIPSE: p->o_wid = val * 2;
263: break;
264: }
265: break;
266: case WIDTH: p->o_wid = val;
267: break;
268: case HEIGHT: p->o_ht = val;
269: break;
270: default: yyerror ("can't happen setattr");
271: }
272: return val;
273: }
274:
275: miscattrs(ap, obat)
276: Attr *ap;
277: struct objattr *obat;
278: {
279: float *fp;
280: int n;
281:
282: switch (ap->a_type) {
283: case FONT:
284: reset_font((double)ap->a_val.f);
285: break;
286: case SIZE:
287: reset_size(ap->a_sub, (double)ap->a_val.f);
288: break;
289: case SPACE:
290: reset_space(ap->a_sub, (double)ap->a_val.f);
291: break;
292: case TEXTATTR:
293: if (ap->a_val.p != NULL)
294: savetext(ap->a_sub, ap->a_val.p);
295: else
296: text[ntext-1].t_type = ap->a_sub;
297: /* ??? can this ever happen */
298: /* except after a previous */
299: /* text in the same object? */
300: break;
301: case NOEDGE:
302: obat->a_flags &= ~EDGED;
303: break;
304: case LAYER:
305: obat->a_layer = ap->a_val.f;
306: break;
307: case LWEIGHT:
308: obat->a_weight = ap->a_val.f;
309: break;
310: case LCOLOR:
311: obat->a_lcolor = ap->a_val.f;
312: break;
313: case PCOLOR:
314: obat->a_flags |= FILLED;
315: if (ap->a_sub != DEFAULT)
316: obat->a_pcolor = ap->a_val.f;
317: break;
318: case TCOLOR:
319: obat->a_tcolor = ap->a_val.f;
320: break;
321: case DOT:
322: case DASH:
323: n = ap->a_type == DOT ? 3 : 2;
324: if ((fp = (float *)malloc(n * sizeof(float))) == NULL) {
325: yyerror("out of space in miscattrs");
326: break;
327: }
328: *fp = --n;
329: fp[n] = (ap->a_sub == DEFAULT ? getfval("dashwid")
330: : ap->a_val.f);
331: if (n == 2)
332: fp[1] = -1; /* fill in later, from weight */
333: ap->a_val.a = fp;
334: /* and fall through to the general case */
335: case DASHPAT:
336: obat->a_flags |= DOTDASH;
337: obat->a_dashpat.a = ap->a_val.a;
338: break;
339: case HEIGHT:
340: obat->a_ht = ap->a_val.f;
341: break;
342: case WIDTH:
343: obat->a_wid = ap->a_val.f;
344: break;
345: case RADIUS:
346: obat->a_rad = ap->a_val.f;
347: break;
348: case DIAMETER:
349: obat->a_rad = ap->a_val.f / 2;
350: break;
351: }
352: }
353:
354: float miters[8] = {0, 0, 0, 0, 0, 0, 0, 0};
355:
356: primattrs(p, obat) /* note: ht, wid, rad and layer are set elsewhere */
357: /* because of nonuniformities in their design */
358: obj *p; /* (this could be further rationalized!) */
359: struct objattr *obat;
360: {
361: int n;
362: float x, bnd[4];
363:
364: p->o_attr |= obat->a_flags;
365: p->o_text = obat->a_tcolor;
366: checktextcolor(p);
367: if (obat->a_flags & FILLED) {
368: if (obat->a_pcolor == -1.)
369: obat->a_pcolor = getfval ("fillcolor");
370: p->o_fill = checkcolor((double)obat->a_pcolor);
371: }
372: if (obat->a_flags & EDGED) {
373: if (obat->a_weight == -1.)
374: obat->a_weight = getfval ("lineweight");
375: if (obat->a_weight >= 0.)
376: p->o_weight = obat->a_weight;
377: if (obat->a_lcolor == -1.)
378: obat->a_lcolor = getfval ("linecolor");
379: p->o_color = checkcolor((double)obat->a_lcolor);
380: if ((n = (int)getfval("linecap")) >= 0)
381: p->o_attr |= (1 + n%3)*LINECAP;
382: if ((n = (int)getfval("linejoin")) >= 0)
383: p->o_attr |= (1 + n%3)*JOIN;
384: if (n == 0) { /* mitre join */
385: x = getfval("miterlimit");
386: if (x >= 1) {
387: for (n = 1; n < 8; n++)
388: if (miters[n] == 0 || miters[n] == x)
389: break;
390: if (n == 8)
391: for (n = 1; n < 7; ++n)
392: miters[n] = miters[n+1];
393: miters[n] = x;
394: p->o_attr |= n * MITER;
395: }
396: }
397: }
398: else
399: p->o_weight = 0;
400: if (obat->a_dashpat.a != NULL && obat->a_dashpat.a[1] == -1) /* dots */
401: if ((obat->a_dashpat.a[1] = p->o_weight) == 0)
402: obat->a_dashpat.a[1] = 1/(pgscale*2);
403: p->o_ddpat = obat->a_dashpat;
404: }
405:
406: checktextcolor (p)
407: obj *p;
408: {
409: if (p->o_nt2 > p->o_nt1) {
410: if (p->o_text == -1)
411: p->o_text = getfval("textcolor");
412: p->o_text = checkcolor((double)p->o_text);
413: }
414: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.