utils.c (7116B)
1 #include <u.h> 2 #include <libc.h> 3 #include <bio.h> 4 #include "../common/common.h" 5 #include "tr2post.h" 6 7 int hpos = 0, vpos = 0; 8 int fontsize, fontpos; 9 10 #define MAXSTR 128 11 int trindex; /* index into trofftab of current troff font */ 12 static int expecthmot = 0; 13 14 void 15 initialize(void) { 16 } 17 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 } 26 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 } 35 36 void 37 hmot(int x) { 38 int delta; 39 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 } 61 62 void 63 vmot(int y) { 64 endstring(); 65 /* Bprint(Bstdout, " 0 %d rmoveto ", -y); */ 66 vpos += y; 67 } 68 69 struct charent ** 70 findglyph(int trfid, Rune rune, char *stoken) { 71 struct charent **cp; 72 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 } 82 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; 96 97 mi = 0; 98 settrfont(); 99 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; 105 106 if (specialflag) { 107 if (expecthmot) hmot(0); 108 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; 117 } 118 if (strcmp(troffontab[fontid].trfontid, fontmtab[mi])==0) break; 119 } 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; 125 } 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; 131 } 132 } 133 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; 140 } 141 } 142 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; 147 } 148 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; 155 } 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; 161 } 162 } 163 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; 169 } 170 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); 176 } 177 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; 182 } 183 if (i >= tfp->psfmapsize) 184 error(FATAL, "character <0x%x> does not have a Postscript font defined.\n", rune); 185 186 setpsfont(psfp->psftid, fontsize); 187 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); 200 } 201 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; 211 } 212 } 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); 221 } 222 expecthmot = (*cp)->troffcharwidth * fontsize / unitwidth; 223 } 224 } 225 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 */ 231 232 void 233 runeout(Rune rune) { 234 char stoken[UTFmax+1]; 235 int i; 236 237 i = runetochar(stoken, &rune); 238 stoken[i] = '\0'; 239 glyphout(rune, stoken, TRUE); 240 } 241 242 void 243 specialout(char *stoken) { 244 Rune rune; 245 246 chartorune(&rune, stoken); 247 glyphout(rune, stoken, TRUE); 248 } 249 250 void 251 graphfunc(Biobuf *bp) { 252 } 253 254 long 255 nametorune(char *name) { 256 return(0); 257 } 258 259 void 260 notavail(char *msg) { 261 Bprint(Bstderr, "%s is not available at this time.\n", msg); 262 }