This is loadfont.c in view mode; [Download] [Up]
/* * loadfont.c of dvisw software package * loads a pk file into memory. */ #include "structures.h" #include <strings.h> /* * These are the external routines we use. */ extern void error() ; extern integer scalewidth() ; extern void tfmload() ; extern FILE *pksearch() ; extern void makefont() ; extern shalfword dvibyte() ; extern halfword twobytes() ; extern integer threebytes() ; extern integer signedquad() ; extern shalfword signedbyte() ; extern shalfword signedpair() ; extern integer signedtrio() ; extern void movmem(), cmpmem() ; extern void free() ; extern void unpack() ; extern void setstatus(), qstatus() ; extern void TPSinit(), TPSdf(), TPSdc(), TPSbop(), TPSeop() ; extern void texflush() ; extern void TPSdfe(), TPSrfe(), TPSdfes() ; extern void pswrite() ; extern int residentfont(), virtualfont() ; extern void add_header() ; /* * These are the external variables we use. */ static quarterword *svirpos ; extern quarterword *virpos ; extern char temperrorbuf[] ; extern fontdesctype *fontlist, *curfnt ; extern integer dvimag ; extern FILE *pkfile ; extern FILE *dvifile ; extern integer curpos ; extern char *pkpath ; extern real pxlconv ; extern real screendpi ; #ifdef DEBUG extern int debugon ; #endif extern int *existsize ; FILE *readingpk ; integer scurpos ; integer curid ; int lastresortsizes[40] ; /* * We use mymalloc here. */ void *mymalloc() ; void *tempbuf() ; char lastfile[400] ; extern TeXfontdesctype *TeXfontlist ; Boolean pkopen(tft, dpi) register TeXfontdesctype *tft ; int dpi ; { register char *d, *n ; n = tft->name ; if (*n==0) { n++ ; d = pkpath ; } else { d = n ; while (*n) n++ ; n++ ; } sprintf(lastfile, "%s.%dpk", n, dpi) ; sprintf(temperrorbuf, "Loading %s", lastfile) ; qstatus(temperrorbuf) ; { int del ; for (del=0; del<=1+dpi/500; del=del>0?-del:-del+1) { (void)sprintf(lastfile, "%s.%dpk", n, dpi + del) ; if (pkfile=pksearch(d, lastfile, n, dpi + del)) goto fontfound ; } } if (d == pkpath) { (void)sprintf(lastfile, "%s.%dpk", n, dpi) ; makefont(n, (int)dpi) ; if (pkfile = pksearch(d, lastfile, n, dpi)) goto fontfound ; } /* * If nothing above worked, then we get desparate. We attempt to * open the stupid font at one of a small set of predefined sizes, * and then use PostScript scaling to generate the correct size. * * We much prefer scaling up to scaling down, since scaling down * can omit character features, so we try the larger sizes first, * and then work down. */ { int i, j ; if (lastresortsizes[0] && dpi < 30000) { for (i=0; lastresortsizes[i] < dpi; i++) ; for (j = i-1; j >= 0; j--) { (void)sprintf(lastfile, "%s.%dpk", n, lastresortsizes[j]) ; if (pkfile=pksearch(d, lastfile, n, lastresortsizes[j])) { dpi = lastresortsizes[j] ; tft->loaded->alreadyscaled = 0 ; goto sfontfound ; } } for (j = i; lastresortsizes[j] < 30000; j++) { (void)sprintf(lastfile, "%s.%dpk", n, lastresortsizes[j]) ; if (pkfile=pksearch(d, lastfile, n, lastresortsizes[j])) { dpi = lastresortsizes[j] ; tft->loaded->alreadyscaled = 0 ; goto sfontfound ; } } } } strcat(temperrorbuf, " [blocks]") ; qstatus(temperrorbuf) ; return 0 ; sfontfound: ; #ifdef DEBUG strcat(temperrorbuf, " [scaled]") ; qstatus(temperrorbuf) ; if (debugon > 1) printf("Had to scale %d to %d\n", dpi, tft->loaded->dpi) ; #endif fontfound: readingpk = dvifile ; scurpos = curpos ; svirpos = virpos ; virpos = 0 ; dvifile = pkfile ; tft->loaded->loadeddpi = dpi ; return(1) ; } /* * This routine compares two strings in sucession, for font names. */ short str2cmp(a, b) register char *a, *b ; { while (*a!=0 && *a==*b) { a++ ; b++ ; } if (*a!=0 || *b!=0) return(0) ; a++ ; b++ ; while (*a!=0 && *a==*b) { a++ ; b++ ; } return (*a==0 && *b==0) ; } void bytepack(p, w, h) register char *p ; register int w, h ; { register char *q ; register int i ; w = (w + 7) / 8 ; if ((w & 1) == 0) return ; q = p + w ; p = q + 1 ; while (h > 1) { for (i=w; i>0; i--) *q++ = *p++ ; p++ ; h-- ; } } /* * Now our loadfont routine. */ void loadfont(tft) register TeXfontdesctype *tft ; { register fontdesctype *cf ; register chardesctype *cd ; register integer k ; register integer length ; register integer cmd ; register integer i, j ; register integer cc ; register integer scaledsize = tft->scaledsize ; register integer cheight, cwidth ; register integer xoffset, yoffset ; register integer dpi ; register shalfword *p, *q ; int fontwidths[256] ; /* * First, we scan through the linked list of fonts in memory, looking * for one that matches ours. */ dpi = pxlconv * (float)scaledsize / tft->designsize + 0.5 ; /* * Now we check to see if that value is close to some other value. * Close is within one. If so, we load that size. There should * never be an error of more than one; the only errors are due to * floating point and magnifications being only valid to about three * sig digits. */ for (i=0; existsize[i] < dpi; i++) ; if (existsize[i] == dpi + 1) dpi = existsize[i] ; else if (existsize[i-1] == dpi - 1) dpi = existsize[i-1] ; if (debugon > 5) printf("Looking for %s %ld %ld\n", tft->name+1, tft->scaledsize, dpi) ; for (cf=fontlist; cf!=NULL; cf=cf->next) { if (cf->dpi==dpi && str2cmp(cf->name, tft->name)) break ; } if (cf!=NULL) { if (debugon > 5) printf("Found: %s\n", cf->name+1) ; tft->loaded = cf ; for (i=0; i<cf->maxchars; i++) tft->scaledwidth[i] = scalewidth(cf->chardesc[i].TFMwidth, tft->scaledsize) ; if (cf->virtual) { fontmaptype *fm ; for (fm = cf->localfonts; fm; fm = fm->next) { tft = fm->tdesc ; tft->scaledsize = scalewidth(scaledsize, tft->origssize) ; } } return ; } if (debugon > 5) printf("Not found.\n") ; /* * Didn't find any, we allocate a new fontdesc. */ i = 0 ; while (tft->name[i++]!=0) ; while (tft->name[i++]!=0) ; cf = mymalloc(sizeof(fontdesctype)+i, MEMF_CLEAR) ; curfnt = cf ; cf->chardesc = mymalloc(sizeof(chardesctype) * 256, MEMF_CLEAR) ; cf->maxchars = 256 ; while (i >= 0) { cf->name[i] = tft->name[i] ; i-- ; } tft->loaded = cf ; cf->next = fontlist ; fontlist = cf ; cf->dpi = dpi ; cf->id = curid++ ; cf->resfont = NULL ; if (residentfont(tft)) { float fontscale ; struct resfont *rf = cf->resfont ; static int firstPSfont = 1 ; char num[50] ; char nfn[10] ; #ifdef POPRESTORE TPSeop() ; #endif if (firstPSfont) { add_header("texps.pro") ; firstPSfont = 0 ; } for (i=0; i<256; i++) fontwidths[i] = 0 ; for (i=0; i<cf->maxchars; i++) fontwidths[i] = cf->chardesc[i].pixelwidth ; sprintf(nfn, "Q%ld", curid-1) ; if (rf->downloadheader) { char *cp = rf->downloadheader ; char *q ; while (1) { q = cp ; while (*cp && *cp != ' ') cp++ ; if (*cp) { *cp = 0 ; add_header(q) ; *cp++ = ' ' ; } else { add_header(q) ; break ; } } } pswrite(" /") ; pswrite(nfn) ; pswrite(" /") ; pswrite(nfn) ; for (i=255; i>=0; i--) { sprintf(num, " %d", fontwidths[i]) ; pswrite(num) ; } pswrite(" {") ; if (rf->specialinstructions) pswrite(rf->specialinstructions) ; pswrite("} 256 ") ; fontscale = tft->scaledsize / 655360.0 ; fontscale *= dvimag / 7200.0 ; fontscale *= screendpi ; sprintf(num, "%f ", fontscale) ; pswrite(num) ; pswrite("/") ; pswrite(rf->PSname) ; pswrite(" rf ") ; TPSrfe(curid-1) ; #ifdef POPRESTORE TPSbop() ; #else texflush() ; #endif if (debugon > 5) printf("Font was resident.\n") ; goto scalethem ; } else if (virtualfont(tft)) { if (debugon > 5) printf("Font was virtual.\n") ; goto scalethem ; } if (!(i=pkopen(tft, dpi))) { tfmload(tft, 1) ; scalethem: for (i=0; i<cf->maxchars; i++) tft->scaledwidth[i] = scalewidth(cf->chardesc[i].TFMwidth, tft->scaledsize) ; return ; } #ifdef POPRESTORE TPSeop() ; #endif TPSdf(cf->id) ; if (dvibyte()!=247) error("! bad pk file, expected pre") ; if (dvibyte()!=89) error("! bad version of pk file") ; for(i=dvibyte(); i>0; i--) j=dvibyte() ; k = signedquad() >> 4 ; if (k > tft->designsize + 2 || k < tft->designsize - 2) error("design size mismatch") ; signedquad() ; signedquad() ; signedquad() ; /* * Now we get down to the serious business of reading character definitions. */ while ((cmd=dvibyte())!=245) { if (cmd < 240) { switch (cmd & 7) { case 0: case 1: case 2: case 3: length = (cmd & 7) * 256 + dvibyte() - 8 ; cc = dvibyte() ; cd = cf->chardesc+cc ; cd->TFMwidth = threebytes() ; cd->pixelwidth = dvibyte() ; cwidth = dvibyte() ; cheight = dvibyte() ; xoffset = signedbyte() ; yoffset = signedbyte() ; break ; case 4: length = dvibyte() * 256 ; length = length + dvibyte() - 13 ; cc = dvibyte() ; cd = cf->chardesc+cc ; cd->TFMwidth = threebytes() ; cd->pixelwidth = twobytes() ; cwidth = twobytes() ; cheight = twobytes() ; xoffset = signedpair() ; yoffset = signedpair() ; break ; case 7: length = signedquad() - 28 ; cc = signedquad() ; cd = cf->chardesc+cc ; cd->TFMwidth = signedquad() ; cd->pixelwidth = (signedquad() + 32768) >> 16 ; signedquad() ; cwidth = signedquad() ; cheight = signedquad() ; xoffset = signedquad() ; yoffset = signedquad() ; break ; case 5: case 6: default: error("! lost sync in pk file (character too big)") ; return ; } i = cheight * ((cwidth + 15) / 16) ; p = tempbuf(length + 2 * i + 10) ; if (i > 0) { fread(p, 1, length, dvifile) ; q = p + (length + 3) / 2 ; unpack(p, q, cwidth, cheight, cmd) ; } else { cwidth = 1 ; cheight = 1 ; q = p ; *q = ~0 ; } /* * It's an ugly, ugly story, but now we need to byte-pack the word-packed * data. Of course, we do this only if the data isn't already byte packed. */ bytepack(q, cwidth, cheight) ; i = cheight * ((cwidth + 7) / 8) ; TPSdc(q, i, cwidth, cheight, xoffset, cheight - yoffset - 1, cd->pixelwidth, cc) ; } else { k = 0 ; switch (cmd) { case 243: k = dvibyte() ; if (k > 127) k -= 256 ; case 242: k = k * 256 + dvibyte() ; case 241: k = k * 256 + dvibyte() ; case 240: k = k * 256 + dvibyte() ; while (k-- > 0) i = dvibyte() ; break ; case 244: k = signedquad() ; break ; case 246: break ; default: error("! lost sync in pk file") ; } } } fclose(dvifile) ; dvifile = readingpk ; curpos = scurpos ; virpos = svirpos ; readingpk = NULL ; for (i=0; i<cf->maxchars; i++) tft->scaledwidth[i] = scalewidth(cf->chardesc[i].TFMwidth, tft->scaledsize) ; if (cf->dpi == cf->loadeddpi) TPSdfe() ; else TPSdfes(cf->dpi, cf->loadeddpi) ; #ifdef POPRESTORE TPSbop() ; #else texflush() ; #endif }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.