xref: /plan9/sys/src/cmd/pic/textgen.c (revision 219b2ee8daee37f4aad58d63f21287faa8e4ffdc)
1 #include	<stdio.h>
2 #include	"pic.h"
3 #include	"y.tab.h"
4 
5 obj *textgen(void)
6 {
7 	int i, sub, nstr, at, with, hset;
8 	double xwith, ywith, h, w, x0, y0, x1, y1;
9 	obj *p, *ppos;
10 	static double prevh = 0;
11 	static double prevw = 0;
12 	Attr *ap;
13 
14 	at = with = nstr = hset = 0;
15 	h = getfval("textht");
16 	w = getfval("textwid");
17 	for (i = 0; i < nattr; i++) {
18 		ap = &attr[i];
19 		switch (ap->a_type) {
20 		case HEIGHT:
21 			h = ap->a_val.f;
22 			hset++;
23 			break;
24 		case WIDTH:
25 			w = ap->a_val.f;
26 			break;
27 		case WITH:
28 			with = ap->a_val.i;
29 			break;
30 		case AT:
31 			ppos = ap->a_val.o;
32 			curx = ppos->o_x;
33 			cury = ppos->o_y;
34 			at++;
35 			break;
36 		case TEXTATTR:
37 			sub = ap->a_sub;
38 			if (ap->a_val.p == NULL)	/* an isolated modifier */
39 				text[ntext-1].t_type = sub;
40 			else {
41 				savetext(sub, ap->a_val.p);
42 				nstr++;
43 			}
44 			break;
45 		}
46 	}
47 	if (hset == 0)		/* no explicit ht cmd */
48 		h *= nstr;
49 	if (with) {
50 		xwith = ywith = 0.0;
51 		switch (with) {
52 		case NORTH:	ywith = -h / 2; break;
53 		case SOUTH:	ywith = h / 2; break;
54 		case EAST:	xwith = -w / 2; break;
55 		case WEST:	xwith = w / 2; break;
56 		case NE:	xwith = -w / 2; ywith = -h / 2; break;
57 		case SE:	xwith = -w / 2; ywith = h / 2; break;
58 		case NW:	xwith = w / 2; ywith = -h / 2; break;
59 		case SW:	xwith = w / 2; ywith = h / 2; break;
60 		}
61 		curx += xwith;
62 		cury += ywith;
63 	}
64 	if (!at) {
65 		if (isright(hvmode))
66 			curx += w / 2;
67 		else if (isleft(hvmode))
68 			curx -= w / 2;
69 		else if (isup(hvmode))
70 			cury += h / 2;
71 		else
72 			cury -= h / 2;
73 	}
74 	x0 = curx - w / 2;
75 	y0 = cury - h / 2;
76 	x1 = curx + w / 2;
77 	y1 = cury + h / 2;
78 	extreme(x0, y0);
79 	extreme(x1, y1);
80 	dprintf("Text h %g w %g at %g,%g\n", h, w, curx, cury);
81 	p = makenode(TEXT, 2);
82 	p->o_val[0] = w;
83 	p->o_val[1] = h;
84 	if (isright(hvmode))
85 		curx = x1;
86 	else if (isleft(hvmode))
87 		curx = x0;
88 	else if (isup(hvmode))
89 		cury = y1;
90 	else
91 		cury = y0;
92 	prevh = h;
93 	prevw = w;
94 	return(p);
95 }
96 
97 obj *troffgen(char *s)	/* save away a string of troff commands */
98 {
99 	savetext(CENTER, s);	/* use the existing text mechanism */
100 	return makenode(TROFF, 0);
101 }
102 
103 void savetext(int t, char *s)	/* record text elements for current object */
104 {
105 	if (ntext >= ntextlist)
106 		text = (Text *) grow((char *) text, "text", ntextlist += 200, sizeof(Text));
107 	text[ntext].t_type = t;
108 	text[ntext].t_val = s;
109 	dprintf("saving %d text %s at %d\n", t, s, ntext);
110 	ntext++;
111 }
112