Blob


1 #include <u.h>
2 #include <libc.h>
3 #include <bio.h>
4 #include "../common/common.h"
5 #include "tr2post.h"
7 int hpos = 0, vpos = 0;
8 int fontsize, fontpos;
10 #define MAXSTR 128
11 int trindex; /* index into trofftab of current troff font */
12 static int expecthmot = 0;
14 void
15 initialize(void) {
16 }
18 void
19 hgoto(int x) {
20 hpos = x;
21 if (pageon()) {
22 endstring();
23 /* Bprint(Bstdout, "%d %d m\n", hpos, vpos); */
24 }
25 }
27 void
28 vgoto(int y) {
29 vpos = y;
30 if (pageon()) {
31 endstring();
32 /* Bprint(Bstdout, "%d %d m\n", hpos, vpos); */
33 }
34 }
36 void
37 hmot(int x) {
38 int delta;
40 if ((x<expecthmot-1) || (x>expecthmot+1)) {
41 delta = x - expecthmot;
42 if (curtrofffontid <0 || curtrofffontid >= troffontcnt) {
43 Bprint(Bstderr, "troffontcnt=%d curtrofffontid=%d\n", troffontcnt, curtrofffontid);
44 Bflush(Bstderr);
45 exits("");
46 }
47 if (delta == troffontab[curtrofffontid].spacewidth*fontsize/10 && isinstring()) {
48 if (pageon()) runeout(' ');
49 } else {
50 if (pageon()) {
51 endstring();
52 /* Bprint(Bstdout, " %d 0 rmoveto ", delta); */
53 /* Bprint(Bstdout, " %d %d m ", hpos+x, vpos); */
54 if (debug) Bprint(Bstderr, "x=%d expecthmot=%d\n", x, expecthmot);
55 }
56 }
57 }
58 hpos += x;
59 expecthmot = 0;
60 }
62 void
63 vmot(int y) {
64 endstring();
65 /* Bprint(Bstdout, " 0 %d rmoveto ", -y); */
66 vpos += y;
67 }
69 struct charent **
70 findglyph(int trfid, Rune rune, char *stoken) {
71 struct charent **cp;
73 for (cp = &(troffontab[trfid].charent[RUNEGETGROUP(rune)][RUNEGETCHAR(rune)]); *cp != 0; cp = &((*cp)->next)) {
74 if ((*cp)->name) {
75 if (debug) Bprint(Bstderr, "looking for <%s>, have <%s> in font %s\n", stoken, (*cp)->name, troffontab[trfid].trfontid);
76 if (strcmp((*cp)->name, stoken) == 0)
77 break;
78 }
79 }
80 return(cp);
81 }
83 /* output glyph. Use first rune to look up character (hash)
84 * then use stoken UTF string to find correct glyph in linked
85 * list of glyphs in bucket.
86 */
87 void
88 glyphout(Rune rune, char *stoken, BOOLEAN specialflag) {
89 struct charent **cp;
90 struct troffont *tfp;
91 struct psfent *psfp = (struct psfent*)0;
92 int i, t;
93 int fontid; /* this is the troff font table index, not the mounted font table index */
94 int mi, wid;
95 Rune r;
97 mi = 0;
98 settrfont();
100 /* check current font for the character, special or not */
101 fontid = curtrofffontid;
102 if (debug) fprint(2, " looking through current font: trying %s\n", troffontab[fontid].trfontid);
103 cp = findglyph(fontid, rune, stoken);
104 if (*cp != 0) goto foundit;
106 if (specialflag) {
107 if (expecthmot) hmot(0);
109 /* check special fonts for the special character */
110 /* cycle through the (troff) mounted fonts starting at the next font */
111 for (mi=0; mi<fontmnt; mi++) {
112 if (troffontab[fontid].trfontid==0) error(WARNING, "glyphout:troffontab[%d].trfontid=0x%x, botch!\n",
113 fontid, troffontab[fontid].trfontid);
114 if (fontmtab[mi]==0) {
115 if (debug) fprint(2, "fontmtab[%d]=0x%x, fontmnt=%d\n", mi, fontmtab[mi], fontmnt);
116 continue;
118 if (strcmp(troffontab[fontid].trfontid, fontmtab[mi])==0) break;
120 if (mi==fontmnt) error(FATAL, "current troff font is not mounted, botch!\n");
121 for (i=(mi+1)%fontmnt; i!=mi; i=(i+1)%fontmnt) {
122 if (fontmtab[i]==0) {
123 if (debug) fprint(2, "fontmtab[%d]=0x%x, fontmnt=%d\n", i, fontmtab[i], fontmnt);
124 continue;
126 fontid = findtfn(fontmtab[i], TRUE);
127 if (debug) fprint(2, " looking through special fonts: trying %s\n", troffontab[fontid].trfontid);
128 if (troffontab[fontid].special) {
129 cp = findglyph(fontid, rune, stoken);
130 if (*cp != 0) goto foundit;
134 /* check font 1 (if current font is not font 1) for the special character */
135 if (mi != 1) {
136 fontid = findtfn(fontmtab[1], TRUE);;
137 if (debug) fprint(2, " looking through font at position 1: trying %s\n", troffontab[fontid].trfontid);
138 cp = findglyph(fontid, rune, stoken);
139 if (*cp != 0) goto foundit;
143 if (*cp == 0) {
144 error(WARNING, "cannot find glyph, rune=0x%x stoken=<%s> troff font %s\n", rune, stoken,
145 troffontab[curtrofffontid].trfontid);
146 expecthmot = 0;
149 /* use the peter face in lieu of the character that we couldn't find */
150 rune = 'p'; stoken = "pw";
151 for (i=(mi+1)%fontmnt; i!=mi; i=(i+1)%fontmnt) {
152 if (fontmtab[i]==0) {
153 if (debug) fprint(2, "fontmtab[%d]=0x%x\n", i, fontmtab[i]);
154 continue;
156 fontid = findtfn(fontmtab[i], TRUE);
157 if (debug) fprint(2, " looking through special fonts: trying %s\n", troffontab[fontid].trfontid);
158 if (troffontab[fontid].special) {
159 cp = findglyph(fontid, rune, stoken);
160 if (*cp != 0) goto foundit;
164 if (*cp == 0) {
165 error(WARNING, "cannot find glyph, rune=0x%x stoken=<%s> troff font %s\n", rune, stoken,
166 troffontab[curtrofffontid].trfontid);
167 expecthmot = 0;
168 return;
171 foundit:
172 t = (((*cp)->postfontid&0xff)<<8) | ((*cp)->postcharid&0xff);
173 if (debug) {
174 Bprint(Bstderr, "runeout(0x%x)<%C> postfontid=0x%x postcharid=0x%x troffcharwidth=%d\n",
175 rune, rune, (*cp)->postfontid, (*cp)->postcharid, (*cp)->troffcharwidth);
178 tfp = &(troffontab[fontid]);
179 for (i=0; i<tfp->psfmapsize; i++) {
180 psfp = &(tfp->psfmap[i]);
181 if(t>=psfp->start && t<=psfp->end) break;
183 if (i >= tfp->psfmapsize)
184 error(FATAL, "character <0x%x> does not have a Postscript font defined.\n", rune);
186 setpsfont(psfp->psftid, fontsize);
188 if (t == 0x0001) { /* character is in charlib */
189 endstring();
190 if (pageon()) {
191 Bprint(Bstdout, "%d %d m ", hpos, vpos);
192 /* if char is unicode character rather than name, clean up for postscript */
193 wid = chartorune(&r, (*cp)->name);
194 if(' '<r && r<0x7F)
195 Bprint(Bstdout, "%d build_%s\n", (*cp)->troffcharwidth, (*cp)->name);
196 else{
197 if((*cp)->name[wid] != 0)
198 error(FATAL, "character <%s> badly named\n", (*cp)->name);
199 Bprint(Bstdout, "%d build_X%.4x\n", (*cp)->troffcharwidth, r);
202 /* stash charent pointer in a list so that we can print these character definitions
203 * in the prologue.
204 */
205 for (i=0; i<build_char_cnt; i++)
206 if (*cp == build_char_list[i]) break;
207 if (i == build_char_cnt) {
208 build_char_list = galloc(build_char_list, sizeof(struct charent *) * ++build_char_cnt,
209 "build_char_list");
210 build_char_list[build_char_cnt-1] = *cp;
213 expecthmot = (*cp)->troffcharwidth * fontsize / unitwidth;
214 } else if (isinstring() || rune != ' ') {
215 startstring();
216 if (pageon()) {
217 if (rune == ' ')
218 Bprint(Bstdout, " ");
219 else
220 Bprint(Bstdout, "%s", charcode[RUNEGETCHAR(t)].str);
222 expecthmot = (*cp)->troffcharwidth * fontsize / unitwidth;
226 /* runeout puts a symbol into a string (queue) to be output.
227 * It also has to keep track of the current and last symbol
228 * output to check that the spacing is correct by default
229 * or needs to be adjusted with a spacing operation.
230 */
232 void
233 runeout(Rune rune) {
234 char stoken[UTFmax+1];
235 int i;
237 i = runetochar(stoken, &rune);
238 stoken[i] = '\0';
239 glyphout(rune, stoken, TRUE);
242 void
243 specialout(char *stoken) {
244 Rune rune;
245 int i;
247 i = chartorune(&rune, stoken);
248 glyphout(rune, stoken, TRUE);
251 void
252 graphfunc(Biobuf *bp) {
255 long
256 nametorune(char *name) {
257 return(0);
260 void
261 notavail(char *msg) {
262 Bprint(Bstderr, "%s is not available at this time.\n", msg);