1219b2ee8SDavid du Colombier /* Unicode | PostScript 2219b2ee8SDavid du Colombier * start end | offset font name 3219b2ee8SDavid du Colombier * 0x0000 0x00ff 0x00 LucidaSansUnicode00 4219b2ee8SDavid du Colombier */ 5219b2ee8SDavid du Colombier #include <u.h> 6219b2ee8SDavid du Colombier #include <libc.h> 7219b2ee8SDavid du Colombier #include <bio.h> 8219b2ee8SDavid du Colombier #include "common.h" 9219b2ee8SDavid du Colombier #include "tr2post.h" 10219b2ee8SDavid du Colombier #include "comments.h" 11219b2ee8SDavid du Colombier #include "path.h" 12219b2ee8SDavid du Colombier 13219b2ee8SDavid du Colombier /* Postscript font names, e.g., `LucidaSansUnicode00' 14219b2ee8SDavid du Colombier * names may only be added because reference to the 15219b2ee8SDavid du Colombier * names is made by indexing into this table. 16219b2ee8SDavid du Colombier */ 17219b2ee8SDavid du Colombier static struct pfnament *pfnafontmtab = 0; 18219b2ee8SDavid du Colombier static int pfnamcnt = 0; 19219b2ee8SDavid du Colombier int curpostfontid = -1; 20219b2ee8SDavid du Colombier int curfontsize = -1; 21219b2ee8SDavid du Colombier int curtrofffontid = -1; 22219b2ee8SDavid du Colombier static int curfontpos = -1; 23*7dd7cddfSDavid du Colombier static int fontheight = 0; 24*7dd7cddfSDavid du Colombier static int fontslant = 0; 25219b2ee8SDavid du Colombier 26219b2ee8SDavid du Colombier /* This is troffs mounted font table. It is an anachronism resulting 27219b2ee8SDavid du Colombier * from the design of the APS typesetter. fontmnt is the 28219b2ee8SDavid du Colombier * number of positions available. fontmnt is really 11, but 29219b2ee8SDavid du Colombier * should not be limited. 30219b2ee8SDavid du Colombier */ 31219b2ee8SDavid du Colombier int fontmnt = 0; 32219b2ee8SDavid du Colombier char **fontmtab; 33219b2ee8SDavid du Colombier 34219b2ee8SDavid du Colombier struct troffont *troffontab = 0; 35219b2ee8SDavid du Colombier 36219b2ee8SDavid du Colombier int troffontcnt = 0; 37219b2ee8SDavid du Colombier 38219b2ee8SDavid du Colombier void 39219b2ee8SDavid du Colombier mountfont(int pos, char *fontname) { 40219b2ee8SDavid du Colombier int i; 41219b2ee8SDavid du Colombier 42219b2ee8SDavid du Colombier if (debug) Bprint(Bstderr, "mountfont(%d, %s)\n", pos, fontname); 43219b2ee8SDavid du Colombier if (pos < 0 || pos >= fontmnt) 44219b2ee8SDavid du Colombier error(FATAL, "cannot mount a font at position %d,\n can only mount into postions 0-%d\n", 45219b2ee8SDavid du Colombier pos, fontmnt-1); 46219b2ee8SDavid du Colombier 47219b2ee8SDavid du Colombier i = strlen(fontname); 48219b2ee8SDavid du Colombier fontmtab[pos] = galloc(fontmtab[pos], i+1, "mountfont():fontmtab"); 49219b2ee8SDavid du Colombier strcpy(fontmtab[pos], fontname); 50219b2ee8SDavid du Colombier if (curfontpos == pos) curfontpos = -1; 51219b2ee8SDavid du Colombier } 52219b2ee8SDavid du Colombier 53219b2ee8SDavid du Colombier void 54219b2ee8SDavid du Colombier settrfont(void) { 55219b2ee8SDavid du Colombier if (curfontpos == fontpos) return; 56219b2ee8SDavid du Colombier 57219b2ee8SDavid du Colombier if (fontmtab[fontpos] == 0) 58219b2ee8SDavid du Colombier error(FATAL, "Font at position %d was not initialized, botch!\n", fontpos); 59219b2ee8SDavid du Colombier 60219b2ee8SDavid du Colombier curtrofffontid = findtfn(fontmtab[fontpos], 1); 61219b2ee8SDavid du Colombier if (debug) Bprint(Bstderr, "settrfont()-> curtrofffontid=%d\n", curtrofffontid); 62219b2ee8SDavid du Colombier curfontpos = fontpos; 63219b2ee8SDavid du Colombier if (curtrofffontid < 0) { 64219b2ee8SDavid du Colombier int i; 65219b2ee8SDavid du Colombier 66219b2ee8SDavid du Colombier error(WARNING, "fontpos=%d\n", fontpos); 67219b2ee8SDavid du Colombier for (i=0; i<fontmnt; i++) 68219b2ee8SDavid du Colombier if (fontmtab[i] == 0) 69219b2ee8SDavid du Colombier error(WARNING, "fontmtab[%d]=0x0\n", i); 70219b2ee8SDavid du Colombier else 71219b2ee8SDavid du Colombier error(WARNING, "fontmtab[%d]=%s\n", i, fontmtab[i]); 72219b2ee8SDavid du Colombier exits("settrfont()"); 73219b2ee8SDavid du Colombier } 74219b2ee8SDavid du Colombier } 75219b2ee8SDavid du Colombier 76219b2ee8SDavid du Colombier void 77219b2ee8SDavid du Colombier setpsfont(int psftid, int fontsize) { 78219b2ee8SDavid du Colombier if (psftid == curpostfontid && fontsize == curfontsize) return; 79219b2ee8SDavid du Colombier if (psftid >= pfnamcnt) 80219b2ee8SDavid du Colombier error(FATAL, "Postscript font index=%d used but not defined, there are only %d fonts\n", 81219b2ee8SDavid du Colombier psftid, pfnamcnt); 82219b2ee8SDavid du Colombier 83219b2ee8SDavid du Colombier endstring(); 84219b2ee8SDavid du Colombier if (pageon()) { 85219b2ee8SDavid du Colombier Bprint(Bstdout, "%d /%s f\n", fontsize, pfnafontmtab[psftid].str); 86*7dd7cddfSDavid du Colombier if ( fontheight != 0 || fontslant != 0 ) 87*7dd7cddfSDavid du Colombier Bprint(Bstdout, "%d %d changefont\n", fontslant, (fontheight != 0) ? fontheight : fontsize); 88219b2ee8SDavid du Colombier pfnafontmtab[psftid].used = 1; 89219b2ee8SDavid du Colombier curpostfontid = psftid; 90219b2ee8SDavid du Colombier curfontsize = fontsize; 91219b2ee8SDavid du Colombier } 92219b2ee8SDavid du Colombier } 93219b2ee8SDavid du Colombier 94219b2ee8SDavid du Colombier /* find index of PostScript font name in table 95219b2ee8SDavid du Colombier * returns -1 if name is not in table 96219b2ee8SDavid du Colombier * If insflg is not zero 97219b2ee8SDavid du Colombier * and the name is not found in the table, insert it. 98219b2ee8SDavid du Colombier */ 99219b2ee8SDavid du Colombier int 100219b2ee8SDavid du Colombier findpfn(char *fontname, int insflg) { 101219b2ee8SDavid du Colombier char *tp; 102219b2ee8SDavid du Colombier int i; 103219b2ee8SDavid du Colombier 104219b2ee8SDavid du Colombier for (i=0; i<pfnamcnt; i++) { 105219b2ee8SDavid du Colombier if (strcmp(pfnafontmtab[i].str, fontname) == 0) 106219b2ee8SDavid du Colombier return(i); 107219b2ee8SDavid du Colombier } 108219b2ee8SDavid du Colombier if (insflg) { 109219b2ee8SDavid du Colombier tp = galloc(pfnafontmtab, sizeof(struct pfnament)*(pfnamcnt+1), "findpfn():pfnafontmtab"); 110219b2ee8SDavid du Colombier if (tp == 0) 111219b2ee8SDavid du Colombier return(-2); 112219b2ee8SDavid du Colombier pfnafontmtab = (struct pfnament *)tp; 113219b2ee8SDavid du Colombier i = strlen(fontname); 114219b2ee8SDavid du Colombier pfnafontmtab[pfnamcnt].str = galloc(0, i+1, "findpfn():pfnafontmtab[].str"); 115219b2ee8SDavid du Colombier strncpy(pfnafontmtab[pfnamcnt].str, fontname, i); 116219b2ee8SDavid du Colombier pfnafontmtab[pfnamcnt].str[i] = '\0'; 117*7dd7cddfSDavid du Colombier pfnafontmtab[pfnamcnt].used = 0; 118219b2ee8SDavid du Colombier return(pfnamcnt++); 119219b2ee8SDavid du Colombier } 120219b2ee8SDavid du Colombier return(-1); 121219b2ee8SDavid du Colombier } 122219b2ee8SDavid du Colombier 123219b2ee8SDavid du Colombier char postroffdirname[] = "/sys/lib/postscript/troff"; /* "/sys/lib/postscript/troff/"; */ 124219b2ee8SDavid du Colombier char troffmetricdirname[] = "/sys/lib/troff/font"; /* "/sys/lib/troff/font/devutf/"; */ 125219b2ee8SDavid du Colombier 126219b2ee8SDavid du Colombier int 127219b2ee8SDavid du Colombier readpsfontdesc(char *fontname, int trindex) { 128219b2ee8SDavid du Colombier static char *filename = 0; 129219b2ee8SDavid du Colombier Biobuf *bfd; 130219b2ee8SDavid du Colombier Biobufhdr *Bfd; 131219b2ee8SDavid du Colombier int warn = 0, errorflg = 0, line =1, rv; 132219b2ee8SDavid du Colombier int start, end, offset; 133219b2ee8SDavid du Colombier int startfont, endfont, startchar, endchar, i, pfid; 134219b2ee8SDavid du Colombier char psfontnam[128]; 135219b2ee8SDavid du Colombier struct troffont *tp; 136219b2ee8SDavid du Colombier struct charent *cp[]; 137219b2ee8SDavid du Colombier 138219b2ee8SDavid du Colombier if (debug) Bprint(Bstderr, "readpsfontdesc(%s,%d)\n", fontname, trindex); 139219b2ee8SDavid du Colombier filename=galloc(filename, strlen(postroffdirname)+1+strlen(fontname)+1, "readpsfontdesc: cannot allocate memory\n"); 140219b2ee8SDavid du Colombier sprint(filename, "%s/%s", postroffdirname, fontname); 141219b2ee8SDavid du Colombier 142219b2ee8SDavid du Colombier bfd = Bopen(filename, OREAD); 143219b2ee8SDavid du Colombier if (bfd == 0) { 144219b2ee8SDavid du Colombier error(WARNING, "cannot open file %s\n", filename); 145219b2ee8SDavid du Colombier return(0); 146219b2ee8SDavid du Colombier } 147219b2ee8SDavid du Colombier Bfd = &(bfd->Biobufhdr); 148219b2ee8SDavid du Colombier 149219b2ee8SDavid du Colombier do { 150219b2ee8SDavid du Colombier offset = 0; 151219b2ee8SDavid du Colombier if ((rv=Bgetfield(Bfd, 'd', &start, 0)) == 0) { 152219b2ee8SDavid du Colombier errorflg = 1; 153219b2ee8SDavid du Colombier error(WARNING, "file %s:%d illegal start value\n", filename, line); 154219b2ee8SDavid du Colombier } else if (rv < 0) break; 155219b2ee8SDavid du Colombier if ((rv=Bgetfield(Bfd, 'd', &end, 0)) == 0) { 156219b2ee8SDavid du Colombier errorflg = 1; 157219b2ee8SDavid du Colombier error(WARNING, "file %s:%d illegal end value\n", filename, line); 158219b2ee8SDavid du Colombier } else if (rv < 0) break; 159219b2ee8SDavid du Colombier if ((rv=Bgetfield(Bfd, 'd', &offset, 0)) < 0) { 160219b2ee8SDavid du Colombier errorflg = 1; 161219b2ee8SDavid du Colombier error(WARNING, "file %s:%d illegal offset value\n", filename, line); 162219b2ee8SDavid du Colombier } 163219b2ee8SDavid du Colombier if ((rv=Bgetfield(Bfd, 's', psfontnam, 128)) == 0) { 164219b2ee8SDavid du Colombier errorflg = 1; 165219b2ee8SDavid du Colombier error(WARNING, "file %s:%d illegal fontname value\n", filename, line); 166219b2ee8SDavid du Colombier } else if (rv < 0) break; 167219b2ee8SDavid du Colombier Brdline(Bfd, '\n'); 168219b2ee8SDavid du Colombier if (!errorflg) { 169219b2ee8SDavid du Colombier struct psfent *psfentp; 170219b2ee8SDavid du Colombier startfont = RUNEGETGROUP(start); 171219b2ee8SDavid du Colombier startchar = RUNEGETCHAR(start); 172219b2ee8SDavid du Colombier endfont = RUNEGETGROUP(end); 173219b2ee8SDavid du Colombier endchar = RUNEGETCHAR(end); 174219b2ee8SDavid du Colombier pfid = findpfn(psfontnam, 1); 175219b2ee8SDavid du Colombier if (startfont != endfont) { 176219b2ee8SDavid du Colombier error(WARNING, "font descriptions must not cross 256 glyph block boundary\n"); 177219b2ee8SDavid du Colombier errorflg = 1; 178219b2ee8SDavid du Colombier break; 179219b2ee8SDavid du Colombier } 180219b2ee8SDavid du Colombier tp = &(troffontab[trindex]); 181219b2ee8SDavid du Colombier tp->psfmap = galloc(tp->psfmap, ++(tp->psfmapsize)*sizeof(struct psfent), "readpsfontdesc():psfmap"); 182219b2ee8SDavid du Colombier psfentp = &(tp->psfmap[tp->psfmapsize-1]); 183219b2ee8SDavid du Colombier psfentp->start = start; 184219b2ee8SDavid du Colombier psfentp->end = end; 185219b2ee8SDavid du Colombier psfentp->offset = offset; 186219b2ee8SDavid du Colombier psfentp->psftid = pfid; 187*7dd7cddfSDavid du Colombier if (debug) { 188*7dd7cddfSDavid du Colombier Bprint(Bstderr, "\tpsfmap->start=0x%x\n", start); 189*7dd7cddfSDavid du Colombier Bprint(Bstderr, "\tpsfmap->end=0x%x\n", end); 190*7dd7cddfSDavid du Colombier Bprint(Bstderr, "\tpsfmap->offset=0x%x\n", offset); 191*7dd7cddfSDavid du Colombier Bprint(Bstderr, "\tpsfmap->pfid=0x%x\n", pfid); 192*7dd7cddfSDavid du Colombier } 193219b2ee8SDavid du Colombier /* 194219b2ee8SDavid du Colombier for (i=startchar; i<=endchar; i++) { 195219b2ee8SDavid du Colombier tp->charent[startfont][i].postfontid = pfid; 196219b2ee8SDavid du Colombier tp->charent[startfont][i].postcharid = i + offset - startchar; 197219b2ee8SDavid du Colombier } 198219b2ee8SDavid du Colombier */ 199219b2ee8SDavid du Colombier if (debug) { 200219b2ee8SDavid du Colombier Bprint(Bstderr, "%x %x ", start, end); 201219b2ee8SDavid du Colombier if (offset) Bprint(Bstderr, "%x ", offset); 202219b2ee8SDavid du Colombier Bprint(Bstderr, "%s\n", psfontnam); 203219b2ee8SDavid du Colombier } 204219b2ee8SDavid du Colombier line++; 205219b2ee8SDavid du Colombier } 206219b2ee8SDavid du Colombier } while(errorflg != 1); 207219b2ee8SDavid du Colombier Bterm(Bfd); 208219b2ee8SDavid du Colombier return(1); 209219b2ee8SDavid du Colombier } 210219b2ee8SDavid du Colombier 211219b2ee8SDavid du Colombier int 212219b2ee8SDavid du Colombier readtroffmetric(char *fontname, int trindex) { 213219b2ee8SDavid du Colombier static char *filename = 0; 214219b2ee8SDavid du Colombier Biobuf *bfd; 215219b2ee8SDavid du Colombier Biobufhdr *Bfd; 216219b2ee8SDavid du Colombier int warn = 0, errorflg = 0, line =1, rv; 217219b2ee8SDavid du Colombier struct troffont *tp; 218219b2ee8SDavid du Colombier struct charent **cp; 219219b2ee8SDavid du Colombier char stoken[128], *str; 220219b2ee8SDavid du Colombier int ntoken; 221219b2ee8SDavid du Colombier Rune troffchar, quote; 222219b2ee8SDavid du Colombier int width, flag, charnum, thisfont, thischar; 223219b2ee8SDavid du Colombier BOOLEAN specharflag; 224219b2ee8SDavid du Colombier 225219b2ee8SDavid du Colombier if (debug) Bprint(Bstderr, "readtroffmetric(%s,%d)\n", fontname, trindex); 226219b2ee8SDavid du Colombier filename=galloc(filename, strlen(troffmetricdirname)+4+strlen(devname)+1+strlen(fontname)+1, "readtroffmetric():filename"); 227219b2ee8SDavid du Colombier sprint(filename, "%s/dev%s/%s", troffmetricdirname, devname, fontname); 228219b2ee8SDavid du Colombier 229219b2ee8SDavid du Colombier bfd = Bopen(filename, OREAD); 230219b2ee8SDavid du Colombier if (bfd == 0) { 231219b2ee8SDavid du Colombier error(WARNING, "cannot open file %s\n", filename); 232219b2ee8SDavid du Colombier return(0); 233219b2ee8SDavid du Colombier } 234219b2ee8SDavid du Colombier Bfd = &(bfd->Biobufhdr); 235219b2ee8SDavid du Colombier do { 236219b2ee8SDavid du Colombier /* deal with the few lines at the beginning of the 237219b2ee8SDavid du Colombier * troff font metric files. 238219b2ee8SDavid du Colombier */ 239219b2ee8SDavid du Colombier if ((rv=Bgetfield(Bfd, 's', stoken, 128)) == 0) { 240219b2ee8SDavid du Colombier errorflg = 1; 241219b2ee8SDavid du Colombier error(WARNING, "file %s:%d illegal token\n", filename, line); 242219b2ee8SDavid du Colombier } else if (rv < 0) break; 243219b2ee8SDavid du Colombier if (debug) { 244219b2ee8SDavid du Colombier Bprint(Bstderr, "%s\n", stoken); 245219b2ee8SDavid du Colombier } 246219b2ee8SDavid du Colombier 247219b2ee8SDavid du Colombier if (strcmp(stoken, "name") == 0) { 248219b2ee8SDavid du Colombier if ((rv=Bgetfield(Bfd, 's', stoken, 128)) == 0) { 249219b2ee8SDavid du Colombier errorflg = 1; 250219b2ee8SDavid du Colombier error(WARNING, "file %s:%d illegal token\n", filename, line); 251219b2ee8SDavid du Colombier } else if (rv < 0) break; 252219b2ee8SDavid du Colombier } else if (strcmp(stoken, "named") == 0) { 253219b2ee8SDavid du Colombier Brdline(Bfd, '\n'); 254219b2ee8SDavid du Colombier } else if (strcmp(stoken, "fontname") == 0) { 255219b2ee8SDavid du Colombier if ((rv=Bgetfield(Bfd, 's', stoken, 128)) == 0) { 256219b2ee8SDavid du Colombier errorflg = 1; 257219b2ee8SDavid du Colombier error(WARNING, "file %s:%d illegal token\n", filename, line); 258219b2ee8SDavid du Colombier } else if (rv < 0) break; 259219b2ee8SDavid du Colombier } else if (strcmp(stoken, "spacewidth") == 0) { 260219b2ee8SDavid du Colombier if ((rv=Bgetfield(Bfd, 'd', &ntoken, 0)) == 0) { 261219b2ee8SDavid du Colombier errorflg = 1; 262219b2ee8SDavid du Colombier error(WARNING, "file %s:%d illegal token\n", filename, line); 263219b2ee8SDavid du Colombier } else if (rv < 0) break; 264219b2ee8SDavid du Colombier troffontab[trindex].spacewidth = ntoken; 265219b2ee8SDavid du Colombier thisfont = RUNEGETGROUP(' '); 266219b2ee8SDavid du Colombier thischar = RUNEGETCHAR(' '); 267219b2ee8SDavid du Colombier for (cp = &(troffontab[trindex].charent[thisfont][thischar]); *cp != 0; cp = &((*cp)->next)) 268219b2ee8SDavid du Colombier if ((*cp)->name) 269219b2ee8SDavid du Colombier if (strcmp((*cp)->name, " ") == 0) 270219b2ee8SDavid du Colombier break; 271219b2ee8SDavid du Colombier 272219b2ee8SDavid du Colombier if (*cp == 0) *cp = galloc(0, sizeof(struct charent), "readtroffmetric:charent"); 273219b2ee8SDavid du Colombier (*cp)->postfontid = thisfont; 274219b2ee8SDavid du Colombier (*cp)->postcharid = thischar; 275219b2ee8SDavid du Colombier (*cp)->troffcharwidth = ntoken; 276219b2ee8SDavid du Colombier (*cp)->name = galloc(0, 2, "readtroffmetric: char name"); 277219b2ee8SDavid du Colombier (*cp)->next = 0; 278219b2ee8SDavid du Colombier strcpy((*cp)->name, " "); 279219b2ee8SDavid du Colombier } else if (strcmp(stoken, "special") == 0) { 280219b2ee8SDavid du Colombier troffontab[trindex].special = TRUE; 281219b2ee8SDavid du Colombier } else if (strcmp(stoken, "charset") == 0) { 282219b2ee8SDavid du Colombier line++; 283219b2ee8SDavid du Colombier break; 284219b2ee8SDavid du Colombier } 285219b2ee8SDavid du Colombier if (!errorflg) { 286219b2ee8SDavid du Colombier line++; 287219b2ee8SDavid du Colombier } 288219b2ee8SDavid du Colombier } while(!errorflg && rv>=0); 289219b2ee8SDavid du Colombier while(!errorflg && rv>=0) { 290219b2ee8SDavid du Colombier if ((rv=Bgetfield(Bfd, 's', stoken, 128)) == 0) { 291219b2ee8SDavid du Colombier errorflg = 1; 292219b2ee8SDavid du Colombier error(WARNING, "file %s:%d illegal rune token <0x%x> rv=%d\n", filename, line, troffchar, rv); 293219b2ee8SDavid du Colombier } else if (rv < 0) break; 294219b2ee8SDavid du Colombier if (utflen(stoken) > 1) specharflag = TRUE; 295219b2ee8SDavid du Colombier else specharflag = FALSE; 296219b2ee8SDavid du Colombier /* if this character is a quote we have to use the previous characters info */ 297219b2ee8SDavid du Colombier if ((rv=Bgetfield(Bfd, 'r', "e, 0)) == 0) { 298219b2ee8SDavid du Colombier errorflg = 1; 299219b2ee8SDavid du Colombier error(WARNING, "file %s:%d illegal width or quote token <0x%x> rv=%d\n", filename, line, quote, rv); 300219b2ee8SDavid du Colombier } else if (rv < 0) break; 301219b2ee8SDavid du Colombier if (quote == '"') { 302219b2ee8SDavid du Colombier /* need some code here */ 303219b2ee8SDavid du Colombier 304219b2ee8SDavid du Colombier goto flush; 305219b2ee8SDavid du Colombier } else { 306219b2ee8SDavid du Colombier Bungetrune(Bfd); 307219b2ee8SDavid du Colombier } 308219b2ee8SDavid du Colombier 309219b2ee8SDavid du Colombier if ((rv=Bgetfield(Bfd, 'd', &width, 0)) == 0) { 310219b2ee8SDavid du Colombier errorflg = 1; 311219b2ee8SDavid du Colombier error(WARNING, "file %s:%d illegal width token <0x%x> rv=%d\n", filename, line, troffchar, rv); 312219b2ee8SDavid du Colombier } else if (rv < 0) break; 313219b2ee8SDavid du Colombier if ((rv=Bgetfield(Bfd, 'd', &flag, 0)) == 0) { 314219b2ee8SDavid du Colombier errorflg = 1; 315219b2ee8SDavid du Colombier error(WARNING, "file %s:%d illegal flag token <0x%x> rv=%d\n", filename, line, troffchar, rv); 316219b2ee8SDavid du Colombier } else if (rv < 0) break; 317219b2ee8SDavid du Colombier if ((rv=Bgetfield(Bfd, 'd', &charnum, 0)) == 0) { 318219b2ee8SDavid du Colombier errorflg = 1; 319219b2ee8SDavid du Colombier error(WARNING, "file %s:%d illegal character number token <0x%x> rv=%d\n", filename, line, troffchar, rv); 320219b2ee8SDavid du Colombier } else if (rv < 0) break; 321219b2ee8SDavid du Colombier flush: 322219b2ee8SDavid du Colombier str = Brdline(Bfd, '\n'); 323219b2ee8SDavid du Colombier /* stash the crap from the end of the line for debugging */ 324219b2ee8SDavid du Colombier if (debug) { 325219b2ee8SDavid du Colombier if (str == 0) { 326219b2ee8SDavid du Colombier Bprint(Bstderr, "premature EOF\n"); 327219b2ee8SDavid du Colombier return(0); 328219b2ee8SDavid du Colombier } 329219b2ee8SDavid du Colombier str[Blinelen(Bfd)-1] = '\0'; 330219b2ee8SDavid du Colombier } 331219b2ee8SDavid du Colombier line++; 332219b2ee8SDavid du Colombier chartorune(&troffchar, stoken); 333219b2ee8SDavid du Colombier if (specharflag) { 334219b2ee8SDavid du Colombier if (debug) 335219b2ee8SDavid du Colombier Bprint(Bstderr, "%s %d %d 0x%x %s # special\n",stoken, width, flag, charnum, str); 336219b2ee8SDavid du Colombier } 337219b2ee8SDavid du Colombier if (strcmp(stoken, "---") == 0) { 338219b2ee8SDavid du Colombier thisfont = RUNEGETGROUP(charnum); 339219b2ee8SDavid du Colombier thischar = RUNEGETCHAR(charnum); 340219b2ee8SDavid du Colombier stoken[0] = '\0'; 341219b2ee8SDavid du Colombier } else { 342219b2ee8SDavid du Colombier thisfont = RUNEGETGROUP(troffchar); 343219b2ee8SDavid du Colombier thischar = RUNEGETCHAR(troffchar); 344219b2ee8SDavid du Colombier } 345219b2ee8SDavid du Colombier for (cp = &(troffontab[trindex].charent[thisfont][thischar]); *cp != 0; cp = &((*cp)->next)) 346219b2ee8SDavid du Colombier if ((*cp)->name) { 347219b2ee8SDavid du Colombier if (debug) Bprint(Bstderr, "installing <%s>, found <%s>\n", stoken, (*cp)->name); 348219b2ee8SDavid du Colombier if (strcmp((*cp)->name, stoken) == 0) 349219b2ee8SDavid du Colombier break; 350219b2ee8SDavid du Colombier } 351219b2ee8SDavid du Colombier if (*cp == 0) *cp = galloc(0, sizeof(struct charent), "readtroffmetric:charent"); 352219b2ee8SDavid du Colombier (*cp)->postfontid = RUNEGETGROUP(charnum); 353219b2ee8SDavid du Colombier (*cp)->postcharid = RUNEGETCHAR(charnum); 354219b2ee8SDavid du Colombier (*cp)->troffcharwidth = width; 355219b2ee8SDavid du Colombier (*cp)->name = galloc(0, strlen(stoken)+1, "readtroffmetric: char name"); 356219b2ee8SDavid du Colombier (*cp)->next = 0; 357219b2ee8SDavid du Colombier strcpy((*cp)->name, stoken); 358219b2ee8SDavid du Colombier if (debug) { 359219b2ee8SDavid du Colombier if (specharflag) 360219b2ee8SDavid du Colombier Bprint(Bstderr, "%s", stoken); 361219b2ee8SDavid du Colombier else 362219b2ee8SDavid du Colombier Bputrune(Bstderr, troffchar); 363219b2ee8SDavid du Colombier Bprint(Bstderr, " %d %d 0x%x %s # psfontid=0x%x pscharid=0x%x thisfont=0x%x thischar=0x%x\n", 364219b2ee8SDavid du Colombier width, flag, charnum, str, 365219b2ee8SDavid du Colombier (*cp)->postfontid, 366219b2ee8SDavid du Colombier (*cp)->postcharid, 367219b2ee8SDavid du Colombier thisfont, thischar); 368219b2ee8SDavid du Colombier } 369219b2ee8SDavid du Colombier } 370219b2ee8SDavid du Colombier Bterm(Bfd); 371219b2ee8SDavid du Colombier Bflush(Bstderr); 372219b2ee8SDavid du Colombier return(1); 373219b2ee8SDavid du Colombier } 374219b2ee8SDavid du Colombier 375219b2ee8SDavid du Colombier /* find index of troff font name in table 376219b2ee8SDavid du Colombier * returns -1 if name is not in table 377219b2ee8SDavid du Colombier * returns -2 if it cannot allocate memory 378219b2ee8SDavid du Colombier * returns -3 if there is a font mapping problem 379219b2ee8SDavid du Colombier * If insflg is not zero 380219b2ee8SDavid du Colombier * and the name is not found in the table, insert it. 381219b2ee8SDavid du Colombier */ 382219b2ee8SDavid du Colombier int 383219b2ee8SDavid du Colombier findtfn(char *fontname, BOOLEAN insflg) { 384219b2ee8SDavid du Colombier struct troffont *tp; 385219b2ee8SDavid du Colombier int i, j; 386219b2ee8SDavid du Colombier 387219b2ee8SDavid du Colombier if (debug) { 388219b2ee8SDavid du Colombier if (fontname==0) fprint(2, "findtfn(0x%x,%d)\n", fontname, insflg); 389219b2ee8SDavid du Colombier else fprint(2, "findtfn(%s,%d)\n", fontname, insflg); 390219b2ee8SDavid du Colombier } 391219b2ee8SDavid du Colombier for (i=0; i<troffontcnt; i++) { 392219b2ee8SDavid du Colombier if (troffontab[i].trfontid==0) { 393219b2ee8SDavid du Colombier error(WARNING, "findtfn:troffontab[%d].trfontid=0x%x, botch!\n", 394219b2ee8SDavid du Colombier i, troffontab[i].trfontid); 395219b2ee8SDavid du Colombier continue; 396219b2ee8SDavid du Colombier } 397219b2ee8SDavid du Colombier if (strcmp(troffontab[i].trfontid, fontname) == 0) 398219b2ee8SDavid du Colombier return(i); 399219b2ee8SDavid du Colombier } 400219b2ee8SDavid du Colombier if (insflg) { 401219b2ee8SDavid du Colombier tp = (struct troffont *)galloc(troffontab, sizeof(struct troffont)*(troffontcnt+1), "findtfn: struct troffont:"); 402219b2ee8SDavid du Colombier if (tp == 0) 403219b2ee8SDavid du Colombier return(-2); 404219b2ee8SDavid du Colombier troffontab = tp; 405219b2ee8SDavid du Colombier tp = &(troffontab[troffontcnt]); 406219b2ee8SDavid du Colombier i = strlen(fontname); 407219b2ee8SDavid du Colombier tp->trfontid = galloc(0, i+1, "findtfn: trfontid:"); 408219b2ee8SDavid du Colombier 409219b2ee8SDavid du Colombier /* initialize new troff font entry with name and numeric fields to 0 */ 410219b2ee8SDavid du Colombier strncpy(tp->trfontid, fontname, i); 411219b2ee8SDavid du Colombier tp->trfontid[i] = '\0'; 412219b2ee8SDavid du Colombier tp->special = FALSE; 413219b2ee8SDavid du Colombier tp->spacewidth = 0; 414219b2ee8SDavid du Colombier tp->psfmapsize = 0; 415219b2ee8SDavid du Colombier tp->psfmap = 0; 416219b2ee8SDavid du Colombier for (i=0; i<NUMOFONTS; i++) 417219b2ee8SDavid du Colombier for (j=0; j<FONTSIZE; j++) 418219b2ee8SDavid du Colombier tp->charent[i][j] = 0; 419219b2ee8SDavid du Colombier troffontcnt++; 420219b2ee8SDavid du Colombier if (!readtroffmetric(fontname, troffontcnt-1)) 421219b2ee8SDavid du Colombier return(-3); 422219b2ee8SDavid du Colombier if (!readpsfontdesc(fontname, troffontcnt-1)) 423219b2ee8SDavid du Colombier return(-3); 424219b2ee8SDavid du Colombier return(troffontcnt-1); 425219b2ee8SDavid du Colombier } 426219b2ee8SDavid du Colombier return(-1); 427219b2ee8SDavid du Colombier } 428219b2ee8SDavid du Colombier 429219b2ee8SDavid du Colombier void 430219b2ee8SDavid du Colombier finish(void) { 431219b2ee8SDavid du Colombier int i; 432219b2ee8SDavid du Colombier 433219b2ee8SDavid du Colombier Bprint(Bstdout, "%s", TRAILER); 434219b2ee8SDavid du Colombier Bprint(Bstdout, "done\n"); 435219b2ee8SDavid du Colombier Bprint(Bstdout, "%s", DOCUMENTFONTS); 436219b2ee8SDavid du Colombier 437219b2ee8SDavid du Colombier for (i=0; i<pfnamcnt; i++) 438219b2ee8SDavid du Colombier if (pfnafontmtab[i].used) 439219b2ee8SDavid du Colombier Bprint(Bstdout, " %s", pfnafontmtab[i].str); 440219b2ee8SDavid du Colombier Bprint(Bstdout, "\n"); 441219b2ee8SDavid du Colombier 442219b2ee8SDavid du Colombier Bprint(Bstdout, "%s %d\n", PAGES, pages_printed); 443219b2ee8SDavid du Colombier 444219b2ee8SDavid du Colombier } 445*7dd7cddfSDavid du Colombier 446*7dd7cddfSDavid du Colombier /* Set slant to n degrees. Disable slanting if n is 0. */ 447*7dd7cddfSDavid du Colombier void 448*7dd7cddfSDavid du Colombier t_slant(int n) { 449*7dd7cddfSDavid du Colombier fontslant = n; 450*7dd7cddfSDavid du Colombier curpostfontid = -1; 451*7dd7cddfSDavid du Colombier } 452*7dd7cddfSDavid du Colombier 453*7dd7cddfSDavid du Colombier /* Set character height to n points. Disabled if n is 0 or the current size. */ 454*7dd7cddfSDavid du Colombier 455*7dd7cddfSDavid du Colombier void 456*7dd7cddfSDavid du Colombier t_charht(int n) { 457*7dd7cddfSDavid du Colombier fontheight = (n == fontsize) ? 0 : n; 458*7dd7cddfSDavid du Colombier curpostfontid = -1; 459*7dd7cddfSDavid du Colombier } 460