1*219b2ee8SDavid du Colombier /* Unicode | PostScript 2*219b2ee8SDavid du Colombier * start end | offset font name 3*219b2ee8SDavid du Colombier * 0x0000 0x00ff 0x00 LucidaSansUnicode00 4*219b2ee8SDavid du Colombier */ 5*219b2ee8SDavid du Colombier #include <u.h> 6*219b2ee8SDavid du Colombier #include <libc.h> 7*219b2ee8SDavid du Colombier #include <bio.h> 8*219b2ee8SDavid du Colombier #include "common.h" 9*219b2ee8SDavid du Colombier #include "tr2post.h" 10*219b2ee8SDavid du Colombier #include "comments.h" 11*219b2ee8SDavid du Colombier #include "path.h" 12*219b2ee8SDavid du Colombier 13*219b2ee8SDavid du Colombier /* Postscript font names, e.g., `LucidaSansUnicode00' 14*219b2ee8SDavid du Colombier * names may only be added because reference to the 15*219b2ee8SDavid du Colombier * names is made by indexing into this table. 16*219b2ee8SDavid du Colombier */ 17*219b2ee8SDavid du Colombier static struct pfnament *pfnafontmtab = 0; 18*219b2ee8SDavid du Colombier static int pfnamcnt = 0; 19*219b2ee8SDavid du Colombier int curpostfontid = -1; 20*219b2ee8SDavid du Colombier int curfontsize = -1; 21*219b2ee8SDavid du Colombier int curtrofffontid = -1; 22*219b2ee8SDavid du Colombier static int curfontpos = -1; 23*219b2ee8SDavid du Colombier 24*219b2ee8SDavid du Colombier /* This is troffs mounted font table. It is an anachronism resulting 25*219b2ee8SDavid du Colombier * from the design of the APS typesetter. fontmnt is the 26*219b2ee8SDavid du Colombier * number of positions available. fontmnt is really 11, but 27*219b2ee8SDavid du Colombier * should not be limited. 28*219b2ee8SDavid du Colombier */ 29*219b2ee8SDavid du Colombier int fontmnt = 0; 30*219b2ee8SDavid du Colombier char **fontmtab; 31*219b2ee8SDavid du Colombier 32*219b2ee8SDavid du Colombier struct troffont *troffontab = 0; 33*219b2ee8SDavid du Colombier 34*219b2ee8SDavid du Colombier int troffontcnt = 0; 35*219b2ee8SDavid du Colombier 36*219b2ee8SDavid du Colombier void 37*219b2ee8SDavid du Colombier mountfont(int pos, char *fontname) { 38*219b2ee8SDavid du Colombier int i; 39*219b2ee8SDavid du Colombier 40*219b2ee8SDavid du Colombier if (debug) Bprint(Bstderr, "mountfont(%d, %s)\n", pos, fontname); 41*219b2ee8SDavid du Colombier if (pos < 0 || pos >= fontmnt) 42*219b2ee8SDavid du Colombier error(FATAL, "cannot mount a font at position %d,\n can only mount into postions 0-%d\n", 43*219b2ee8SDavid du Colombier pos, fontmnt-1); 44*219b2ee8SDavid du Colombier 45*219b2ee8SDavid du Colombier i = strlen(fontname); 46*219b2ee8SDavid du Colombier fontmtab[pos] = galloc(fontmtab[pos], i+1, "mountfont():fontmtab"); 47*219b2ee8SDavid du Colombier strcpy(fontmtab[pos], fontname); 48*219b2ee8SDavid du Colombier if (curfontpos == pos) curfontpos = -1; 49*219b2ee8SDavid du Colombier } 50*219b2ee8SDavid du Colombier 51*219b2ee8SDavid du Colombier void 52*219b2ee8SDavid du Colombier settrfont(void) { 53*219b2ee8SDavid du Colombier if (curfontpos == fontpos) return; 54*219b2ee8SDavid du Colombier 55*219b2ee8SDavid du Colombier if (fontmtab[fontpos] == 0) 56*219b2ee8SDavid du Colombier error(FATAL, "Font at position %d was not initialized, botch!\n", fontpos); 57*219b2ee8SDavid du Colombier 58*219b2ee8SDavid du Colombier curtrofffontid = findtfn(fontmtab[fontpos], 1); 59*219b2ee8SDavid du Colombier if (debug) Bprint(Bstderr, "settrfont()-> curtrofffontid=%d\n", curtrofffontid); 60*219b2ee8SDavid du Colombier curfontpos = fontpos; 61*219b2ee8SDavid du Colombier if (curtrofffontid < 0) { 62*219b2ee8SDavid du Colombier int i; 63*219b2ee8SDavid du Colombier 64*219b2ee8SDavid du Colombier error(WARNING, "fontpos=%d\n", fontpos); 65*219b2ee8SDavid du Colombier for (i=0; i<fontmnt; i++) 66*219b2ee8SDavid du Colombier if (fontmtab[i] == 0) 67*219b2ee8SDavid du Colombier error(WARNING, "fontmtab[%d]=0x0\n", i); 68*219b2ee8SDavid du Colombier else 69*219b2ee8SDavid du Colombier error(WARNING, "fontmtab[%d]=%s\n", i, fontmtab[i]); 70*219b2ee8SDavid du Colombier exits("settrfont()"); 71*219b2ee8SDavid du Colombier } 72*219b2ee8SDavid du Colombier } 73*219b2ee8SDavid du Colombier 74*219b2ee8SDavid du Colombier void 75*219b2ee8SDavid du Colombier setpsfont(int psftid, int fontsize) { 76*219b2ee8SDavid du Colombier if (psftid == curpostfontid && fontsize == curfontsize) return; 77*219b2ee8SDavid du Colombier if (psftid >= pfnamcnt) 78*219b2ee8SDavid du Colombier error(FATAL, "Postscript font index=%d used but not defined, there are only %d fonts\n", 79*219b2ee8SDavid du Colombier psftid, pfnamcnt); 80*219b2ee8SDavid du Colombier 81*219b2ee8SDavid du Colombier endstring(); 82*219b2ee8SDavid du Colombier if (pageon()) { 83*219b2ee8SDavid du Colombier Bprint(Bstdout, "%d /%s f\n", fontsize, pfnafontmtab[psftid].str); 84*219b2ee8SDavid du Colombier pfnafontmtab[psftid].used = 1; 85*219b2ee8SDavid du Colombier curpostfontid = psftid; 86*219b2ee8SDavid du Colombier curfontsize = fontsize; 87*219b2ee8SDavid du Colombier } 88*219b2ee8SDavid du Colombier } 89*219b2ee8SDavid du Colombier 90*219b2ee8SDavid du Colombier /* find index of PostScript font name in table 91*219b2ee8SDavid du Colombier * returns -1 if name is not in table 92*219b2ee8SDavid du Colombier * If insflg is not zero 93*219b2ee8SDavid du Colombier * and the name is not found in the table, insert it. 94*219b2ee8SDavid du Colombier */ 95*219b2ee8SDavid du Colombier int 96*219b2ee8SDavid du Colombier findpfn(char *fontname, int insflg) { 97*219b2ee8SDavid du Colombier char *tp; 98*219b2ee8SDavid du Colombier int i; 99*219b2ee8SDavid du Colombier 100*219b2ee8SDavid du Colombier for (i=0; i<pfnamcnt; i++) { 101*219b2ee8SDavid du Colombier if (strcmp(pfnafontmtab[i].str, fontname) == 0) 102*219b2ee8SDavid du Colombier return(i); 103*219b2ee8SDavid du Colombier } 104*219b2ee8SDavid du Colombier if (insflg) { 105*219b2ee8SDavid du Colombier tp = galloc(pfnafontmtab, sizeof(struct pfnament)*(pfnamcnt+1), "findpfn():pfnafontmtab"); 106*219b2ee8SDavid du Colombier if (tp == 0) 107*219b2ee8SDavid du Colombier return(-2); 108*219b2ee8SDavid du Colombier pfnafontmtab = (struct pfnament *)tp; 109*219b2ee8SDavid du Colombier i = strlen(fontname); 110*219b2ee8SDavid du Colombier pfnafontmtab[pfnamcnt].str = galloc(0, i+1, "findpfn():pfnafontmtab[].str"); 111*219b2ee8SDavid du Colombier strncpy(pfnafontmtab[pfnamcnt].str, fontname, i); 112*219b2ee8SDavid du Colombier pfnafontmtab[pfnamcnt].str[i] = '\0'; 113*219b2ee8SDavid du Colombier return(pfnamcnt++); 114*219b2ee8SDavid du Colombier } 115*219b2ee8SDavid du Colombier return(-1); 116*219b2ee8SDavid du Colombier } 117*219b2ee8SDavid du Colombier 118*219b2ee8SDavid du Colombier char postroffdirname[] = "/sys/lib/postscript/troff"; /* "/sys/lib/postscript/troff/"; */ 119*219b2ee8SDavid du Colombier char troffmetricdirname[] = "/sys/lib/troff/font"; /* "/sys/lib/troff/font/devutf/"; */ 120*219b2ee8SDavid du Colombier 121*219b2ee8SDavid du Colombier int 122*219b2ee8SDavid du Colombier readpsfontdesc(char *fontname, int trindex) { 123*219b2ee8SDavid du Colombier static char *filename = 0; 124*219b2ee8SDavid du Colombier Biobuf *bfd; 125*219b2ee8SDavid du Colombier Biobufhdr *Bfd; 126*219b2ee8SDavid du Colombier int warn = 0, errorflg = 0, line =1, rv; 127*219b2ee8SDavid du Colombier int start, end, offset; 128*219b2ee8SDavid du Colombier int startfont, endfont, startchar, endchar, i, pfid; 129*219b2ee8SDavid du Colombier char psfontnam[128]; 130*219b2ee8SDavid du Colombier struct troffont *tp; 131*219b2ee8SDavid du Colombier struct charent *cp[]; 132*219b2ee8SDavid du Colombier 133*219b2ee8SDavid du Colombier if (debug) Bprint(Bstderr, "readpsfontdesc(%s,%d)\n", fontname, trindex); 134*219b2ee8SDavid du Colombier filename=galloc(filename, strlen(postroffdirname)+1+strlen(fontname)+1, "readpsfontdesc: cannot allocate memory\n"); 135*219b2ee8SDavid du Colombier sprint(filename, "%s/%s", postroffdirname, fontname); 136*219b2ee8SDavid du Colombier 137*219b2ee8SDavid du Colombier bfd = Bopen(filename, OREAD); 138*219b2ee8SDavid du Colombier if (bfd == 0) { 139*219b2ee8SDavid du Colombier error(WARNING, "cannot open file %s\n", filename); 140*219b2ee8SDavid du Colombier return(0); 141*219b2ee8SDavid du Colombier } 142*219b2ee8SDavid du Colombier Bfd = &(bfd->Biobufhdr); 143*219b2ee8SDavid du Colombier 144*219b2ee8SDavid du Colombier do { 145*219b2ee8SDavid du Colombier offset = 0; 146*219b2ee8SDavid du Colombier if ((rv=Bgetfield(Bfd, 'd', &start, 0)) == 0) { 147*219b2ee8SDavid du Colombier errorflg = 1; 148*219b2ee8SDavid du Colombier error(WARNING, "file %s:%d illegal start value\n", filename, line); 149*219b2ee8SDavid du Colombier } else if (rv < 0) break; 150*219b2ee8SDavid du Colombier if ((rv=Bgetfield(Bfd, 'd', &end, 0)) == 0) { 151*219b2ee8SDavid du Colombier errorflg = 1; 152*219b2ee8SDavid du Colombier error(WARNING, "file %s:%d illegal end value\n", filename, line); 153*219b2ee8SDavid du Colombier } else if (rv < 0) break; 154*219b2ee8SDavid du Colombier if ((rv=Bgetfield(Bfd, 'd', &offset, 0)) < 0) { 155*219b2ee8SDavid du Colombier errorflg = 1; 156*219b2ee8SDavid du Colombier error(WARNING, "file %s:%d illegal offset value\n", filename, line); 157*219b2ee8SDavid du Colombier } 158*219b2ee8SDavid du Colombier if ((rv=Bgetfield(Bfd, 's', psfontnam, 128)) == 0) { 159*219b2ee8SDavid du Colombier errorflg = 1; 160*219b2ee8SDavid du Colombier error(WARNING, "file %s:%d illegal fontname value\n", filename, line); 161*219b2ee8SDavid du Colombier } else if (rv < 0) break; 162*219b2ee8SDavid du Colombier Brdline(Bfd, '\n'); 163*219b2ee8SDavid du Colombier if (!errorflg) { 164*219b2ee8SDavid du Colombier struct psfent *psfentp; 165*219b2ee8SDavid du Colombier startfont = RUNEGETGROUP(start); 166*219b2ee8SDavid du Colombier startchar = RUNEGETCHAR(start); 167*219b2ee8SDavid du Colombier endfont = RUNEGETGROUP(end); 168*219b2ee8SDavid du Colombier endchar = RUNEGETCHAR(end); 169*219b2ee8SDavid du Colombier pfid = findpfn(psfontnam, 1); 170*219b2ee8SDavid du Colombier if (startfont != endfont) { 171*219b2ee8SDavid du Colombier error(WARNING, "font descriptions must not cross 256 glyph block boundary\n"); 172*219b2ee8SDavid du Colombier errorflg = 1; 173*219b2ee8SDavid du Colombier break; 174*219b2ee8SDavid du Colombier } 175*219b2ee8SDavid du Colombier tp = &(troffontab[trindex]); 176*219b2ee8SDavid du Colombier tp->psfmap = galloc(tp->psfmap, ++(tp->psfmapsize)*sizeof(struct psfent), "readpsfontdesc():psfmap"); 177*219b2ee8SDavid du Colombier if (debug) Bprint(Bstderr, "\tpsfentp=0x%x\n", psfentp); 178*219b2ee8SDavid du Colombier psfentp = &(tp->psfmap[tp->psfmapsize-1]); 179*219b2ee8SDavid du Colombier psfentp->start = start; 180*219b2ee8SDavid du Colombier psfentp->end = end; 181*219b2ee8SDavid du Colombier psfentp->offset = offset; 182*219b2ee8SDavid du Colombier psfentp->psftid = pfid; 183*219b2ee8SDavid du Colombier /* 184*219b2ee8SDavid du Colombier for (i=startchar; i<=endchar; i++) { 185*219b2ee8SDavid du Colombier tp->charent[startfont][i].postfontid = pfid; 186*219b2ee8SDavid du Colombier tp->charent[startfont][i].postcharid = i + offset - startchar; 187*219b2ee8SDavid du Colombier } 188*219b2ee8SDavid du Colombier */ 189*219b2ee8SDavid du Colombier if (debug) { 190*219b2ee8SDavid du Colombier Bprint(Bstderr, "%x %x ", start, end); 191*219b2ee8SDavid du Colombier if (offset) Bprint(Bstderr, "%x ", offset); 192*219b2ee8SDavid du Colombier Bprint(Bstderr, "%s\n", psfontnam); 193*219b2ee8SDavid du Colombier } 194*219b2ee8SDavid du Colombier line++; 195*219b2ee8SDavid du Colombier } 196*219b2ee8SDavid du Colombier } while(errorflg != 1); 197*219b2ee8SDavid du Colombier Bterm(Bfd); 198*219b2ee8SDavid du Colombier return(1); 199*219b2ee8SDavid du Colombier } 200*219b2ee8SDavid du Colombier 201*219b2ee8SDavid du Colombier int 202*219b2ee8SDavid du Colombier readtroffmetric(char *fontname, int trindex) { 203*219b2ee8SDavid du Colombier static char *filename = 0; 204*219b2ee8SDavid du Colombier Biobuf *bfd; 205*219b2ee8SDavid du Colombier Biobufhdr *Bfd; 206*219b2ee8SDavid du Colombier int warn = 0, errorflg = 0, line =1, rv; 207*219b2ee8SDavid du Colombier struct troffont *tp; 208*219b2ee8SDavid du Colombier struct charent **cp; 209*219b2ee8SDavid du Colombier char stoken[128], *str; 210*219b2ee8SDavid du Colombier int ntoken; 211*219b2ee8SDavid du Colombier Rune troffchar, quote; 212*219b2ee8SDavid du Colombier int width, flag, charnum, thisfont, thischar; 213*219b2ee8SDavid du Colombier BOOLEAN specharflag; 214*219b2ee8SDavid du Colombier 215*219b2ee8SDavid du Colombier if (debug) Bprint(Bstderr, "readtroffmetric(%s,%d)\n", fontname, trindex); 216*219b2ee8SDavid du Colombier filename=galloc(filename, strlen(troffmetricdirname)+4+strlen(devname)+1+strlen(fontname)+1, "readtroffmetric():filename"); 217*219b2ee8SDavid du Colombier sprint(filename, "%s/dev%s/%s", troffmetricdirname, devname, fontname); 218*219b2ee8SDavid du Colombier 219*219b2ee8SDavid du Colombier bfd = Bopen(filename, OREAD); 220*219b2ee8SDavid du Colombier if (bfd == 0) { 221*219b2ee8SDavid du Colombier error(WARNING, "cannot open file %s\n", filename); 222*219b2ee8SDavid du Colombier return(0); 223*219b2ee8SDavid du Colombier } 224*219b2ee8SDavid du Colombier Bfd = &(bfd->Biobufhdr); 225*219b2ee8SDavid du Colombier do { 226*219b2ee8SDavid du Colombier /* deal with the few lines at the beginning of the 227*219b2ee8SDavid du Colombier * troff font metric files. 228*219b2ee8SDavid du Colombier */ 229*219b2ee8SDavid du Colombier if ((rv=Bgetfield(Bfd, 's', stoken, 128)) == 0) { 230*219b2ee8SDavid du Colombier errorflg = 1; 231*219b2ee8SDavid du Colombier error(WARNING, "file %s:%d illegal token\n", filename, line); 232*219b2ee8SDavid du Colombier } else if (rv < 0) break; 233*219b2ee8SDavid du Colombier if (debug) { 234*219b2ee8SDavid du Colombier Bprint(Bstderr, "%s\n", stoken); 235*219b2ee8SDavid du Colombier } 236*219b2ee8SDavid du Colombier 237*219b2ee8SDavid du Colombier if (strcmp(stoken, "name") == 0) { 238*219b2ee8SDavid du Colombier if ((rv=Bgetfield(Bfd, 's', stoken, 128)) == 0) { 239*219b2ee8SDavid du Colombier errorflg = 1; 240*219b2ee8SDavid du Colombier error(WARNING, "file %s:%d illegal token\n", filename, line); 241*219b2ee8SDavid du Colombier } else if (rv < 0) break; 242*219b2ee8SDavid du Colombier } else if (strcmp(stoken, "named") == 0) { 243*219b2ee8SDavid du Colombier Brdline(Bfd, '\n'); 244*219b2ee8SDavid du Colombier } else if (strcmp(stoken, "fontname") == 0) { 245*219b2ee8SDavid du Colombier if ((rv=Bgetfield(Bfd, 's', stoken, 128)) == 0) { 246*219b2ee8SDavid du Colombier errorflg = 1; 247*219b2ee8SDavid du Colombier error(WARNING, "file %s:%d illegal token\n", filename, line); 248*219b2ee8SDavid du Colombier } else if (rv < 0) break; 249*219b2ee8SDavid du Colombier } else if (strcmp(stoken, "spacewidth") == 0) { 250*219b2ee8SDavid du Colombier if ((rv=Bgetfield(Bfd, 'd', &ntoken, 0)) == 0) { 251*219b2ee8SDavid du Colombier errorflg = 1; 252*219b2ee8SDavid du Colombier error(WARNING, "file %s:%d illegal token\n", filename, line); 253*219b2ee8SDavid du Colombier } else if (rv < 0) break; 254*219b2ee8SDavid du Colombier troffontab[trindex].spacewidth = ntoken; 255*219b2ee8SDavid du Colombier thisfont = RUNEGETGROUP(' '); 256*219b2ee8SDavid du Colombier thischar = RUNEGETCHAR(' '); 257*219b2ee8SDavid du Colombier for (cp = &(troffontab[trindex].charent[thisfont][thischar]); *cp != 0; cp = &((*cp)->next)) 258*219b2ee8SDavid du Colombier if ((*cp)->name) 259*219b2ee8SDavid du Colombier if (strcmp((*cp)->name, " ") == 0) 260*219b2ee8SDavid du Colombier break; 261*219b2ee8SDavid du Colombier 262*219b2ee8SDavid du Colombier if (*cp == 0) *cp = galloc(0, sizeof(struct charent), "readtroffmetric:charent"); 263*219b2ee8SDavid du Colombier (*cp)->postfontid = thisfont; 264*219b2ee8SDavid du Colombier (*cp)->postcharid = thischar; 265*219b2ee8SDavid du Colombier (*cp)->troffcharwidth = ntoken; 266*219b2ee8SDavid du Colombier (*cp)->name = galloc(0, 2, "readtroffmetric: char name"); 267*219b2ee8SDavid du Colombier (*cp)->next = 0; 268*219b2ee8SDavid du Colombier strcpy((*cp)->name, " "); 269*219b2ee8SDavid du Colombier } else if (strcmp(stoken, "special") == 0) { 270*219b2ee8SDavid du Colombier troffontab[trindex].special = TRUE; 271*219b2ee8SDavid du Colombier } else if (strcmp(stoken, "charset") == 0) { 272*219b2ee8SDavid du Colombier line++; 273*219b2ee8SDavid du Colombier break; 274*219b2ee8SDavid du Colombier } 275*219b2ee8SDavid du Colombier if (!errorflg) { 276*219b2ee8SDavid du Colombier line++; 277*219b2ee8SDavid du Colombier } 278*219b2ee8SDavid du Colombier } while(!errorflg && rv>=0); 279*219b2ee8SDavid du Colombier while(!errorflg && rv>=0) { 280*219b2ee8SDavid du Colombier if ((rv=Bgetfield(Bfd, 's', stoken, 128)) == 0) { 281*219b2ee8SDavid du Colombier errorflg = 1; 282*219b2ee8SDavid du Colombier error(WARNING, "file %s:%d illegal rune token <0x%x> rv=%d\n", filename, line, troffchar, rv); 283*219b2ee8SDavid du Colombier } else if (rv < 0) break; 284*219b2ee8SDavid du Colombier if (utflen(stoken) > 1) specharflag = TRUE; 285*219b2ee8SDavid du Colombier else specharflag = FALSE; 286*219b2ee8SDavid du Colombier /* if this character is a quote we have to use the previous characters info */ 287*219b2ee8SDavid du Colombier if ((rv=Bgetfield(Bfd, 'r', "e, 0)) == 0) { 288*219b2ee8SDavid du Colombier errorflg = 1; 289*219b2ee8SDavid du Colombier error(WARNING, "file %s:%d illegal width or quote token <0x%x> rv=%d\n", filename, line, quote, rv); 290*219b2ee8SDavid du Colombier } else if (rv < 0) break; 291*219b2ee8SDavid du Colombier if (quote == '"') { 292*219b2ee8SDavid du Colombier /* need some code here */ 293*219b2ee8SDavid du Colombier 294*219b2ee8SDavid du Colombier goto flush; 295*219b2ee8SDavid du Colombier } else { 296*219b2ee8SDavid du Colombier Bungetrune(Bfd); 297*219b2ee8SDavid du Colombier } 298*219b2ee8SDavid du Colombier 299*219b2ee8SDavid du Colombier if ((rv=Bgetfield(Bfd, 'd', &width, 0)) == 0) { 300*219b2ee8SDavid du Colombier errorflg = 1; 301*219b2ee8SDavid du Colombier error(WARNING, "file %s:%d illegal width token <0x%x> rv=%d\n", filename, line, troffchar, rv); 302*219b2ee8SDavid du Colombier } else if (rv < 0) break; 303*219b2ee8SDavid du Colombier if ((rv=Bgetfield(Bfd, 'd', &flag, 0)) == 0) { 304*219b2ee8SDavid du Colombier errorflg = 1; 305*219b2ee8SDavid du Colombier error(WARNING, "file %s:%d illegal flag token <0x%x> rv=%d\n", filename, line, troffchar, rv); 306*219b2ee8SDavid du Colombier } else if (rv < 0) break; 307*219b2ee8SDavid du Colombier if ((rv=Bgetfield(Bfd, 'd', &charnum, 0)) == 0) { 308*219b2ee8SDavid du Colombier errorflg = 1; 309*219b2ee8SDavid du Colombier error(WARNING, "file %s:%d illegal character number token <0x%x> rv=%d\n", filename, line, troffchar, rv); 310*219b2ee8SDavid du Colombier } else if (rv < 0) break; 311*219b2ee8SDavid du Colombier flush: 312*219b2ee8SDavid du Colombier str = Brdline(Bfd, '\n'); 313*219b2ee8SDavid du Colombier /* stash the crap from the end of the line for debugging */ 314*219b2ee8SDavid du Colombier if (debug) { 315*219b2ee8SDavid du Colombier if (str == 0) { 316*219b2ee8SDavid du Colombier Bprint(Bstderr, "premature EOF\n"); 317*219b2ee8SDavid du Colombier return(0); 318*219b2ee8SDavid du Colombier } 319*219b2ee8SDavid du Colombier str[Blinelen(Bfd)-1] = '\0'; 320*219b2ee8SDavid du Colombier } 321*219b2ee8SDavid du Colombier line++; 322*219b2ee8SDavid du Colombier chartorune(&troffchar, stoken); 323*219b2ee8SDavid du Colombier if (specharflag) { 324*219b2ee8SDavid du Colombier if (debug) 325*219b2ee8SDavid du Colombier Bprint(Bstderr, "%s %d %d 0x%x %s # special\n",stoken, width, flag, charnum, str); 326*219b2ee8SDavid du Colombier } 327*219b2ee8SDavid du Colombier if (strcmp(stoken, "---") == 0) { 328*219b2ee8SDavid du Colombier thisfont = RUNEGETGROUP(charnum); 329*219b2ee8SDavid du Colombier thischar = RUNEGETCHAR(charnum); 330*219b2ee8SDavid du Colombier stoken[0] = '\0'; 331*219b2ee8SDavid du Colombier } else { 332*219b2ee8SDavid du Colombier thisfont = RUNEGETGROUP(troffchar); 333*219b2ee8SDavid du Colombier thischar = RUNEGETCHAR(troffchar); 334*219b2ee8SDavid du Colombier } 335*219b2ee8SDavid du Colombier for (cp = &(troffontab[trindex].charent[thisfont][thischar]); *cp != 0; cp = &((*cp)->next)) 336*219b2ee8SDavid du Colombier if ((*cp)->name) { 337*219b2ee8SDavid du Colombier if (debug) Bprint(Bstderr, "installing <%s>, found <%s>\n", stoken, (*cp)->name); 338*219b2ee8SDavid du Colombier if (strcmp((*cp)->name, stoken) == 0) 339*219b2ee8SDavid du Colombier break; 340*219b2ee8SDavid du Colombier } 341*219b2ee8SDavid du Colombier if (*cp == 0) *cp = galloc(0, sizeof(struct charent), "readtroffmetric:charent"); 342*219b2ee8SDavid du Colombier (*cp)->postfontid = RUNEGETGROUP(charnum); 343*219b2ee8SDavid du Colombier (*cp)->postcharid = RUNEGETCHAR(charnum); 344*219b2ee8SDavid du Colombier (*cp)->troffcharwidth = width; 345*219b2ee8SDavid du Colombier (*cp)->name = galloc(0, strlen(stoken)+1, "readtroffmetric: char name"); 346*219b2ee8SDavid du Colombier (*cp)->next = 0; 347*219b2ee8SDavid du Colombier strcpy((*cp)->name, stoken); 348*219b2ee8SDavid du Colombier if (debug) { 349*219b2ee8SDavid du Colombier if (specharflag) 350*219b2ee8SDavid du Colombier Bprint(Bstderr, "%s", stoken); 351*219b2ee8SDavid du Colombier else 352*219b2ee8SDavid du Colombier Bputrune(Bstderr, troffchar); 353*219b2ee8SDavid du Colombier Bprint(Bstderr, " %d %d 0x%x %s # psfontid=0x%x pscharid=0x%x thisfont=0x%x thischar=0x%x\n", 354*219b2ee8SDavid du Colombier width, flag, charnum, str, 355*219b2ee8SDavid du Colombier (*cp)->postfontid, 356*219b2ee8SDavid du Colombier (*cp)->postcharid, 357*219b2ee8SDavid du Colombier thisfont, thischar); 358*219b2ee8SDavid du Colombier } 359*219b2ee8SDavid du Colombier } 360*219b2ee8SDavid du Colombier Bterm(Bfd); 361*219b2ee8SDavid du Colombier Bflush(Bstderr); 362*219b2ee8SDavid du Colombier return(1); 363*219b2ee8SDavid du Colombier } 364*219b2ee8SDavid du Colombier 365*219b2ee8SDavid du Colombier /* find index of troff font name in table 366*219b2ee8SDavid du Colombier * returns -1 if name is not in table 367*219b2ee8SDavid du Colombier * returns -2 if it cannot allocate memory 368*219b2ee8SDavid du Colombier * returns -3 if there is a font mapping problem 369*219b2ee8SDavid du Colombier * If insflg is not zero 370*219b2ee8SDavid du Colombier * and the name is not found in the table, insert it. 371*219b2ee8SDavid du Colombier */ 372*219b2ee8SDavid du Colombier int 373*219b2ee8SDavid du Colombier findtfn(char *fontname, BOOLEAN insflg) { 374*219b2ee8SDavid du Colombier struct troffont *tp; 375*219b2ee8SDavid du Colombier int i, j; 376*219b2ee8SDavid du Colombier 377*219b2ee8SDavid du Colombier if (debug) { 378*219b2ee8SDavid du Colombier if (fontname==0) fprint(2, "findtfn(0x%x,%d)\n", fontname, insflg); 379*219b2ee8SDavid du Colombier else fprint(2, "findtfn(%s,%d)\n", fontname, insflg); 380*219b2ee8SDavid du Colombier } 381*219b2ee8SDavid du Colombier for (i=0; i<troffontcnt; i++) { 382*219b2ee8SDavid du Colombier if (troffontab[i].trfontid==0) { 383*219b2ee8SDavid du Colombier error(WARNING, "findtfn:troffontab[%d].trfontid=0x%x, botch!\n", 384*219b2ee8SDavid du Colombier i, troffontab[i].trfontid); 385*219b2ee8SDavid du Colombier continue; 386*219b2ee8SDavid du Colombier } 387*219b2ee8SDavid du Colombier if (strcmp(troffontab[i].trfontid, fontname) == 0) 388*219b2ee8SDavid du Colombier return(i); 389*219b2ee8SDavid du Colombier } 390*219b2ee8SDavid du Colombier if (insflg) { 391*219b2ee8SDavid du Colombier tp = (struct troffont *)galloc(troffontab, sizeof(struct troffont)*(troffontcnt+1), "findtfn: struct troffont:"); 392*219b2ee8SDavid du Colombier if (tp == 0) 393*219b2ee8SDavid du Colombier return(-2); 394*219b2ee8SDavid du Colombier troffontab = tp; 395*219b2ee8SDavid du Colombier tp = &(troffontab[troffontcnt]); 396*219b2ee8SDavid du Colombier i = strlen(fontname); 397*219b2ee8SDavid du Colombier tp->trfontid = galloc(0, i+1, "findtfn: trfontid:"); 398*219b2ee8SDavid du Colombier 399*219b2ee8SDavid du Colombier /* initialize new troff font entry with name and numeric fields to 0 */ 400*219b2ee8SDavid du Colombier strncpy(tp->trfontid, fontname, i); 401*219b2ee8SDavid du Colombier tp->trfontid[i] = '\0'; 402*219b2ee8SDavid du Colombier tp->special = FALSE; 403*219b2ee8SDavid du Colombier tp->spacewidth = 0; 404*219b2ee8SDavid du Colombier tp->psfmapsize = 0; 405*219b2ee8SDavid du Colombier tp->psfmap = 0; 406*219b2ee8SDavid du Colombier for (i=0; i<NUMOFONTS; i++) 407*219b2ee8SDavid du Colombier for (j=0; j<FONTSIZE; j++) 408*219b2ee8SDavid du Colombier tp->charent[i][j] = 0; 409*219b2ee8SDavid du Colombier troffontcnt++; 410*219b2ee8SDavid du Colombier if (!readtroffmetric(fontname, troffontcnt-1)) 411*219b2ee8SDavid du Colombier return(-3); 412*219b2ee8SDavid du Colombier if (!readpsfontdesc(fontname, troffontcnt-1)) 413*219b2ee8SDavid du Colombier return(-3); 414*219b2ee8SDavid du Colombier return(troffontcnt-1); 415*219b2ee8SDavid du Colombier } 416*219b2ee8SDavid du Colombier return(-1); 417*219b2ee8SDavid du Colombier } 418*219b2ee8SDavid du Colombier 419*219b2ee8SDavid du Colombier void 420*219b2ee8SDavid du Colombier finish(void) { 421*219b2ee8SDavid du Colombier int i; 422*219b2ee8SDavid du Colombier 423*219b2ee8SDavid du Colombier Bprint(Bstdout, "%s", TRAILER); 424*219b2ee8SDavid du Colombier Bprint(Bstdout, "done\n"); 425*219b2ee8SDavid du Colombier Bprint(Bstdout, "%s", DOCUMENTFONTS); 426*219b2ee8SDavid du Colombier 427*219b2ee8SDavid du Colombier for (i=0; i<pfnamcnt; i++) 428*219b2ee8SDavid du Colombier if (pfnafontmtab[i].used) 429*219b2ee8SDavid du Colombier Bprint(Bstdout, " %s", pfnafontmtab[i].str); 430*219b2ee8SDavid du Colombier Bprint(Bstdout, "\n"); 431*219b2ee8SDavid du Colombier 432*219b2ee8SDavid du Colombier Bprint(Bstdout, "%s %d\n", PAGES, pages_printed); 433*219b2ee8SDavid du Colombier 434*219b2ee8SDavid du Colombier } 435