1219b2ee8SDavid du Colombier #include <u.h>
2219b2ee8SDavid du Colombier #include <libc.h>
3219b2ee8SDavid du Colombier #include <bio.h>
4219b2ee8SDavid du Colombier #include "../common/common.h"
5219b2ee8SDavid du Colombier #include "tr2post.h"
6219b2ee8SDavid du Colombier
7219b2ee8SDavid du Colombier int hpos = 0, vpos = 0;
8219b2ee8SDavid du Colombier int fontsize, fontpos;
9219b2ee8SDavid du Colombier
10219b2ee8SDavid du Colombier #define MAXSTR 128
11219b2ee8SDavid du Colombier int trindex; /* index into trofftab of current troff font */
12219b2ee8SDavid du Colombier static int expecthmot = 0;
13219b2ee8SDavid du Colombier
14219b2ee8SDavid du Colombier void
initialize(void)15219b2ee8SDavid du Colombier initialize(void) {
16219b2ee8SDavid du Colombier }
17219b2ee8SDavid du Colombier
18219b2ee8SDavid du Colombier void
hgoto(int x)19219b2ee8SDavid du Colombier hgoto(int x) {
20219b2ee8SDavid du Colombier hpos = x;
21219b2ee8SDavid du Colombier if (pageon()) {
22219b2ee8SDavid du Colombier endstring();
23219b2ee8SDavid du Colombier /* Bprint(Bstdout, "%d %d m\n", hpos, vpos); */
24219b2ee8SDavid du Colombier }
25219b2ee8SDavid du Colombier }
26219b2ee8SDavid du Colombier
27219b2ee8SDavid du Colombier void
vgoto(int y)28219b2ee8SDavid du Colombier vgoto(int y) {
29219b2ee8SDavid du Colombier vpos = y;
30219b2ee8SDavid du Colombier if (pageon()) {
31219b2ee8SDavid du Colombier endstring();
32219b2ee8SDavid du Colombier /* Bprint(Bstdout, "%d %d m\n", hpos, vpos); */
33219b2ee8SDavid du Colombier }
34219b2ee8SDavid du Colombier }
35219b2ee8SDavid du Colombier
36219b2ee8SDavid du Colombier void
hmot(int x)37219b2ee8SDavid du Colombier hmot(int x) {
38219b2ee8SDavid du Colombier int delta;
39219b2ee8SDavid du Colombier
40219b2ee8SDavid du Colombier if ((x<expecthmot-1) || (x>expecthmot+1)) {
41219b2ee8SDavid du Colombier delta = x - expecthmot;
42219b2ee8SDavid du Colombier if (curtrofffontid <0 || curtrofffontid >= troffontcnt) {
43*456a8764SDavid du Colombier fprint(2, "troffontcnt=%d curtrofffontid=%d\n",
44*456a8764SDavid du Colombier troffontcnt, curtrofffontid);
45219b2ee8SDavid du Colombier exits("");
46219b2ee8SDavid du Colombier }
47*456a8764SDavid du Colombier if (delta == troffontab[curtrofffontid].spacewidth*fontsize/10 &&
48*456a8764SDavid du Colombier isinstring()) {
49*456a8764SDavid du Colombier if (pageon())
50*456a8764SDavid du Colombier runeout(' ');
51219b2ee8SDavid du Colombier } else {
52219b2ee8SDavid du Colombier if (pageon()) {
53219b2ee8SDavid du Colombier endstring();
54219b2ee8SDavid du Colombier /* Bprint(Bstdout, " %d 0 rmoveto ", delta); */
55219b2ee8SDavid du Colombier /* Bprint(Bstdout, " %d %d m ", hpos+x, vpos); */
56*456a8764SDavid du Colombier if (debug)
57*456a8764SDavid du Colombier fprint(2, "x=%d expecthmot=%d\n",
58*456a8764SDavid du Colombier x, expecthmot);
59219b2ee8SDavid du Colombier }
60219b2ee8SDavid du Colombier }
61219b2ee8SDavid du Colombier }
62219b2ee8SDavid du Colombier hpos += x;
63219b2ee8SDavid du Colombier expecthmot = 0;
64219b2ee8SDavid du Colombier }
65219b2ee8SDavid du Colombier
66219b2ee8SDavid du Colombier void
vmot(int y)67219b2ee8SDavid du Colombier vmot(int y) {
68219b2ee8SDavid du Colombier endstring();
69219b2ee8SDavid du Colombier /* Bprint(Bstdout, " 0 %d rmoveto ", -y); */
70219b2ee8SDavid du Colombier vpos += y;
71219b2ee8SDavid du Colombier }
72219b2ee8SDavid du Colombier
73219b2ee8SDavid du Colombier struct charent **
findglyph(int trfid,Rune rune,char * stoken)74219b2ee8SDavid du Colombier findglyph(int trfid, Rune rune, char *stoken) {
75219b2ee8SDavid du Colombier struct charent **cp;
76219b2ee8SDavid du Colombier
77219b2ee8SDavid du Colombier for (cp = &(troffontab[trfid].charent[RUNEGETGROUP(rune)][RUNEGETCHAR(rune)]); *cp != 0; cp = &((*cp)->next)) {
78219b2ee8SDavid du Colombier if ((*cp)->name) {
79*456a8764SDavid du Colombier if (debug) fprint(2, "looking for <%s>, have <%s> in font %s\n", stoken, (*cp)->name, troffontab[trfid].trfontid);
80219b2ee8SDavid du Colombier if (strcmp((*cp)->name, stoken) == 0)
81219b2ee8SDavid du Colombier break;
82219b2ee8SDavid du Colombier }
83219b2ee8SDavid du Colombier }
84219b2ee8SDavid du Colombier return(cp);
85219b2ee8SDavid du Colombier }
86219b2ee8SDavid du Colombier
87219b2ee8SDavid du Colombier /* output glyph. Use first rune to look up character (hash)
88219b2ee8SDavid du Colombier * then use stoken UTF string to find correct glyph in linked
89219b2ee8SDavid du Colombier * list of glyphs in bucket.
90219b2ee8SDavid du Colombier */
91219b2ee8SDavid du Colombier void
glyphout(Rune rune,char * stoken,BOOLEAN specialflag)92219b2ee8SDavid du Colombier glyphout(Rune rune, char *stoken, BOOLEAN specialflag) {
93219b2ee8SDavid du Colombier struct charent **cp;
94219b2ee8SDavid du Colombier struct troffont *tfp;
95219b2ee8SDavid du Colombier struct psfent *psfp;
96*456a8764SDavid du Colombier int i, t, mi, wid;
97219b2ee8SDavid du Colombier int fontid; /* this is the troff font table index, not the mounted font table index */
98219b2ee8SDavid du Colombier Rune r;
99219b2ee8SDavid du Colombier
100*456a8764SDavid du Colombier mi = 0;
101219b2ee8SDavid du Colombier settrfont();
102219b2ee8SDavid du Colombier
103219b2ee8SDavid du Colombier /* check current font for the character, special or not */
104219b2ee8SDavid du Colombier fontid = curtrofffontid;
105*456a8764SDavid du Colombier if (debug)
106*456a8764SDavid du Colombier fprint(2, "\tlooking through current font: trying %s\n",
107*456a8764SDavid du Colombier troffontab[fontid].trfontid);
108219b2ee8SDavid du Colombier cp = findglyph(fontid, rune, stoken);
109*456a8764SDavid du Colombier if (*cp != 0)
110*456a8764SDavid du Colombier goto foundit;
111219b2ee8SDavid du Colombier
112219b2ee8SDavid du Colombier if (specialflag) {
113*456a8764SDavid du Colombier if (expecthmot)
114*456a8764SDavid du Colombier hmot(0);
115219b2ee8SDavid du Colombier
116219b2ee8SDavid du Colombier /* check special fonts for the special character */
117219b2ee8SDavid du Colombier /* cycle through the (troff) mounted fonts starting at the next font */
118219b2ee8SDavid du Colombier for (mi=0; mi<fontmnt; mi++) {
119*456a8764SDavid du Colombier if (troffontab[fontid].trfontid==0)
120*456a8764SDavid du Colombier error(WARNING, "glyphout:troffontab[%d].trfontid=0x%x, botch!\n",
121219b2ee8SDavid du Colombier fontid, troffontab[fontid].trfontid);
122219b2ee8SDavid du Colombier if (fontmtab[mi]==0) {
123*456a8764SDavid du Colombier if (debug)
124*456a8764SDavid du Colombier fprint(2, "fontmtab[%d]=%#p, fontmnt=%d\n",
125*456a8764SDavid du Colombier mi, fontmtab[mi], fontmnt);
126219b2ee8SDavid du Colombier continue;
127219b2ee8SDavid du Colombier }
128*456a8764SDavid du Colombier if (strcmp(troffontab[fontid].trfontid, fontmtab[mi])==0)
129*456a8764SDavid du Colombier break;
130219b2ee8SDavid du Colombier }
131*456a8764SDavid du Colombier if (mi==fontmnt)
132*456a8764SDavid du Colombier error(FATAL, "current troff font is not mounted, botch!\n");
133219b2ee8SDavid du Colombier for (i=(mi+1)%fontmnt; i!=mi; i=(i+1)%fontmnt) {
134219b2ee8SDavid du Colombier if (fontmtab[i]==0) {
135*456a8764SDavid du Colombier if (debug)
136*456a8764SDavid du Colombier fprint(2, "fontmtab[%d]=%#p, fontmnt=%d\n",
137*456a8764SDavid du Colombier i, fontmtab[i], fontmnt);
138219b2ee8SDavid du Colombier continue;
139219b2ee8SDavid du Colombier }
140219b2ee8SDavid du Colombier fontid = findtfn(fontmtab[i], TRUE);
141219b2ee8SDavid du Colombier if (debug) fprint(2, " looking through special fonts: trying %s\n", troffontab[fontid].trfontid);
142219b2ee8SDavid du Colombier if (troffontab[fontid].special) {
143219b2ee8SDavid du Colombier cp = findglyph(fontid, rune, stoken);
144*456a8764SDavid du Colombier if (*cp != 0)
145*456a8764SDavid du Colombier goto foundit;
146219b2ee8SDavid du Colombier }
147219b2ee8SDavid du Colombier }
148219b2ee8SDavid du Colombier
149219b2ee8SDavid du Colombier /* check font 1 (if current font is not font 1) for the special character */
150219b2ee8SDavid du Colombier if (mi != 1) {
151219b2ee8SDavid du Colombier fontid = findtfn(fontmtab[1], TRUE);;
152219b2ee8SDavid du Colombier if (debug) fprint(2, " looking through font at position 1: trying %s\n", troffontab[fontid].trfontid);
153219b2ee8SDavid du Colombier cp = findglyph(fontid, rune, stoken);
154219b2ee8SDavid du Colombier if (*cp != 0) goto foundit;
155219b2ee8SDavid du Colombier }
156219b2ee8SDavid du Colombier }
157219b2ee8SDavid du Colombier
158219b2ee8SDavid du Colombier if (*cp == 0) {
159219b2ee8SDavid du Colombier error(WARNING, "cannot find glyph, rune=0x%x stoken=<%s> troff font %s\n", rune, stoken,
160219b2ee8SDavid du Colombier troffontab[curtrofffontid].trfontid);
161219b2ee8SDavid du Colombier expecthmot = 0;
162219b2ee8SDavid du Colombier }
163219b2ee8SDavid du Colombier
164219b2ee8SDavid du Colombier /* use the peter face in lieu of the character that we couldn't find */
165219b2ee8SDavid du Colombier rune = 'p'; stoken = "pw";
166219b2ee8SDavid du Colombier for (i=(mi+1)%fontmnt; i!=mi; i=(i+1)%fontmnt) {
167219b2ee8SDavid du Colombier if (fontmtab[i]==0) {
168*456a8764SDavid du Colombier if (debug) fprint(2, "fontmtab[%d]=%#p\n", i, fontmtab[i]);
169219b2ee8SDavid du Colombier continue;
170219b2ee8SDavid du Colombier }
171219b2ee8SDavid du Colombier fontid = findtfn(fontmtab[i], TRUE);
172219b2ee8SDavid du Colombier if (debug) fprint(2, " looking through special fonts: trying %s\n", troffontab[fontid].trfontid);
173219b2ee8SDavid du Colombier if (troffontab[fontid].special) {
174219b2ee8SDavid du Colombier cp = findglyph(fontid, rune, stoken);
175219b2ee8SDavid du Colombier if (*cp != 0) goto foundit;
176219b2ee8SDavid du Colombier }
177219b2ee8SDavid du Colombier }
178219b2ee8SDavid du Colombier
179219b2ee8SDavid du Colombier if (*cp == 0) {
180*456a8764SDavid du Colombier error(WARNING, "cannot find glyph, rune=0x%x stoken=<%s> troff font %s\n",
181*456a8764SDavid du Colombier rune, stoken, troffontab[curtrofffontid].trfontid);
182219b2ee8SDavid du Colombier expecthmot = 0;
183219b2ee8SDavid du Colombier return;
184219b2ee8SDavid du Colombier }
185219b2ee8SDavid du Colombier
186219b2ee8SDavid du Colombier foundit:
187219b2ee8SDavid du Colombier t = (((*cp)->postfontid&0xff)<<8) | ((*cp)->postcharid&0xff);
188*456a8764SDavid du Colombier if (debug)
189*456a8764SDavid du Colombier fprint(2, "runeout(0x%x)<%C> postfontid=0x%x postcharid=0x%x troffcharwidth=%d\n",
190*456a8764SDavid du Colombier rune, rune, (*cp)->postfontid, (*cp)->postcharid,
191*456a8764SDavid du Colombier (*cp)->troffcharwidth);
192219b2ee8SDavid du Colombier
193*456a8764SDavid du Colombier tfp = &troffontab[fontid];
194*456a8764SDavid du Colombier psfp = nil;
195219b2ee8SDavid du Colombier for (i=0; i<tfp->psfmapsize; i++) {
196219b2ee8SDavid du Colombier psfp = &(tfp->psfmap[i]);
197*456a8764SDavid du Colombier if(t>=psfp->start && t<=psfp->end)
198*456a8764SDavid du Colombier break;
199219b2ee8SDavid du Colombier }
200219b2ee8SDavid du Colombier if (i >= tfp->psfmapsize)
201219b2ee8SDavid du Colombier error(FATAL, "character <0x%x> does not have a Postscript font defined.\n", rune);
202219b2ee8SDavid du Colombier
203219b2ee8SDavid du Colombier setpsfont(psfp->psftid, fontsize);
204219b2ee8SDavid du Colombier
205219b2ee8SDavid du Colombier if (t == 0x0001) { /* character is in charlib */
206219b2ee8SDavid du Colombier endstring();
207219b2ee8SDavid du Colombier if (pageon()) {
208219b2ee8SDavid du Colombier Bprint(Bstdout, "%d %d m ", hpos, vpos);
209219b2ee8SDavid du Colombier /* if char is unicode character rather than name, clean up for postscript */
210219b2ee8SDavid du Colombier wid = chartorune(&r, (*cp)->name);
211219b2ee8SDavid du Colombier if(' '<r && r<0x7F)
212*456a8764SDavid du Colombier Bprint(Bstdout, "%d build_%s\n",
213*456a8764SDavid du Colombier (*cp)->troffcharwidth, (*cp)->name);
214219b2ee8SDavid du Colombier else{
215219b2ee8SDavid du Colombier if((*cp)->name[wid] != 0)
216219b2ee8SDavid du Colombier error(FATAL, "character <%s> badly named\n", (*cp)->name);
217*456a8764SDavid du Colombier Bprint(Bstdout, "%d build_X%.4x\n",
218*456a8764SDavid du Colombier (*cp)->troffcharwidth, r);
219219b2ee8SDavid du Colombier }
220219b2ee8SDavid du Colombier
221*456a8764SDavid du Colombier /*
222*456a8764SDavid du Colombier * stash charent pointer in a list so that we can
223*456a8764SDavid du Colombier * print these character definitions in the prologue.
224219b2ee8SDavid du Colombier */
225219b2ee8SDavid du Colombier for (i=0; i<build_char_cnt; i++)
226*456a8764SDavid du Colombier if (*cp == build_char_list[i])
227*456a8764SDavid du Colombier break;
228219b2ee8SDavid du Colombier if (i == build_char_cnt) {
229*456a8764SDavid du Colombier build_char_list = galloc(build_char_list,
230*456a8764SDavid du Colombier sizeof(struct charent *)*++build_char_cnt,
231219b2ee8SDavid du Colombier "build_char_list");
232219b2ee8SDavid du Colombier build_char_list[build_char_cnt-1] = *cp;
233219b2ee8SDavid du Colombier }
234219b2ee8SDavid du Colombier }
235219b2ee8SDavid du Colombier expecthmot = (*cp)->troffcharwidth * fontsize / unitwidth;
236219b2ee8SDavid du Colombier } else if (isinstring() || rune != ' ') {
237219b2ee8SDavid du Colombier startstring();
238*456a8764SDavid du Colombier if (pageon())
239219b2ee8SDavid du Colombier if (rune == ' ')
240219b2ee8SDavid du Colombier Bprint(Bstdout, " ");
241219b2ee8SDavid du Colombier else
242219b2ee8SDavid du Colombier Bprint(Bstdout, "%s", charcode[RUNEGETCHAR(t)].str);
243219b2ee8SDavid du Colombier expecthmot = (*cp)->troffcharwidth * fontsize / unitwidth;
244219b2ee8SDavid du Colombier }
245219b2ee8SDavid du Colombier }
246219b2ee8SDavid du Colombier
247*456a8764SDavid du Colombier /*
248*456a8764SDavid du Colombier * runeout puts a symbol into a string (queue) to be output.
249219b2ee8SDavid du Colombier * It also has to keep track of the current and last symbol
250219b2ee8SDavid du Colombier * output to check that the spacing is correct by default
251219b2ee8SDavid du Colombier * or needs to be adjusted with a spacing operation.
252219b2ee8SDavid du Colombier */
253219b2ee8SDavid du Colombier
254219b2ee8SDavid du Colombier void
runeout(Rune rune)255219b2ee8SDavid du Colombier runeout(Rune rune) {
256219b2ee8SDavid du Colombier char stoken[UTFmax+1];
257219b2ee8SDavid du Colombier int i;
258219b2ee8SDavid du Colombier
259219b2ee8SDavid du Colombier i = runetochar(stoken, &rune);
260219b2ee8SDavid du Colombier stoken[i] = '\0';
261219b2ee8SDavid du Colombier glyphout(rune, stoken, TRUE);
262219b2ee8SDavid du Colombier }
263219b2ee8SDavid du Colombier
264219b2ee8SDavid du Colombier void
specialout(char * stoken)265219b2ee8SDavid du Colombier specialout(char *stoken) {
266219b2ee8SDavid du Colombier Rune rune;
267219b2ee8SDavid du Colombier
268*456a8764SDavid du Colombier chartorune(&rune, stoken);
269219b2ee8SDavid du Colombier glyphout(rune, stoken, TRUE);
270219b2ee8SDavid du Colombier }
271219b2ee8SDavid du Colombier
272219b2ee8SDavid du Colombier void
graphfunc(Biobufhdr * bp)273219b2ee8SDavid du Colombier graphfunc(Biobufhdr *bp) {
274*456a8764SDavid du Colombier USED(bp);
275219b2ee8SDavid du Colombier }
276219b2ee8SDavid du Colombier
277219b2ee8SDavid du Colombier long
nametorune(char * name)278219b2ee8SDavid du Colombier nametorune(char *name) {
279*456a8764SDavid du Colombier USED(name);
280219b2ee8SDavid du Colombier return(0);
281219b2ee8SDavid du Colombier }
282219b2ee8SDavid du Colombier
283219b2ee8SDavid du Colombier void
notavail(char * msg)284219b2ee8SDavid du Colombier notavail(char *msg) {
285*456a8764SDavid du Colombier fprint(2, "%s is not available at this time.\n", msg);
286219b2ee8SDavid du Colombier }
287