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