diff options
Diffstat (limited to 'Build/source/texk/dvipsk/flib.c')
-rw-r--r-- | Build/source/texk/dvipsk/flib.c | 341 |
1 files changed, 341 insertions, 0 deletions
diff --git a/Build/source/texk/dvipsk/flib.c b/Build/source/texk/dvipsk/flib.c new file mode 100644 index 00000000000..8b5e88e9bb4 --- /dev/null +++ b/Build/source/texk/dvipsk/flib.c @@ -0,0 +1,341 @@ +/* + * Here's some code to handle font libraries. Not needed unless you are + * running on a system that can't handle files well. Not endorsed by + * Tomas Rokicki or Radical Eye Software; use at your own risk. + */ +#ifdef FONTLIB +#include "dvips.h" /* The copyright notice in that file is included too! */ +#include "paths.h" +/* + * The external declarations: + */ +#include "protos_add.h" + +/* + * font library structures + */ +struct fli_entry { + unsigned long offset; + char *name; +}; + +struct fli_size { + unsigned long size; + halfword entries; + struct fli_entry *entry; +}; + +struct fli_lib { + char *name; + halfword sizes; + struct fli_size *size; + struct fli_lib *next; +}; + +struct fli_lib *firstlib = NULL; + +struct fli_centry { + struct fli_lib *lib; + FILE *fp; +}; + +#define FLICSIZE 4 +struct fli_centry *fli_cache[FLICSIZE]; + +Boolean flib = 0; /* non zero if reading a font library */ + +halfword +pkdouble(void) +{ + register halfword i; + i = pkbyte(); + i = i * 256 + pkbyte(); + return(i); +} +/* + * fliload opens each font library, then reads in its + * directory for later use. + * fli_cache is initialized. + */ +void +fliload(void) +{ + int i; + halfword version1, version2; + Boolean needext; + char fontname[50]; + char name[50]; + char *fli; + unsigned long dpi; + halfword len, numsizes, numfonts; + halfword numflib = 0; + struct fli_lib *lib=NULL, *next_lib=NULL; + struct fli_size *size; + struct fli_entry *entry; + + /* initialise fli cache */ + for (i=0; i<FLICSIZE; i++) { + fli_cache[i] = (struct fli_centry *) + mymalloc((integer)sizeof(struct fli_centry)); + fli_cache[i]->lib = (struct fli_lib *)NULL; + fli_cache[i]->fp = (FILE *)NULL; + } + + fli = fliname; + + while (*fli) { + /* get next font library name from fliname */ + needext=1; + for (i=0; *fli && *fli!=PATHSEP; i++) + if ( (name[i] = *fli++) == '.') + needext=0; + name[i] = '\0'; + if (*fli) + fli++; /* skip PATHSEP */ + if (*name) { + /* got fli name, now search for it */ + if (needext) + strcat(name,".fli"); + + if ( (pkfile=search(flipath,name,READBIN)) != (FILE *)NULL ) { + /* for each font library */ + for (i=0; i<4; i++) { + fontname[i] = pkbyte(); /* read header */ + } + version1 = pkbyte(); + version2 = pkbyte(); + if (strncmp(fontname,"FLIB",4)!=0 || version1 != 2 || version2 != 0) + badpk("incorrect font library format"); + + (void) pkdouble(); /* ignore directory length */ + numsizes = pkdouble(); /* number of sizes */ + numfonts = pkdouble(); /* number of fonts */ + len = pkdouble(); /* length of comment */ + for (i=0; i<len; i++) + pkbyte(); /* skip comment */ +#ifdef DEBUG + if (dd(D_FONTS)) + fprintf(stderr,"Font library %s has %d font size%s, %d font%s\n", + name, numsizes , numsizes !=1 ? "s" : "", + numfonts, numfonts!=1 ? "s" : ""); +#endif /* DEBUG */ + + next_lib = (struct fli_lib *) + mymalloc((integer)sizeof(struct fli_lib)); + if (firstlib == (struct fli_lib *)NULL) + firstlib = next_lib; + else + lib->next = next_lib; + lib = next_lib; + size = (struct fli_size *) + mymalloc((integer)numsizes * sizeof(struct fli_size)); + entry = (struct fli_entry *) + mymalloc((integer)numfonts * sizeof(struct fli_entry)); + lib->name = newstring(name); + lib->sizes = numsizes; + lib->size = size; + lib->next = (struct fli_lib *)NULL; + + for (;numsizes>0; numsizes--, size++) { + /* for each font size in this library */ + pkdouble(); /* length of size entry - ignore */ + numfonts = pkdouble(); /* number of fonts */ + dpi = pkquad(); /* DPI (fixed point 16.16) */ + +#ifdef DEBUG + if (dd(D_FONTS)) + fprintf(stderr,"Font library %s size %.5gdpi has %d font%s\n", + name, dpi/65536.0, numfonts, numfonts!=1 ? "s" : ""); +#endif /* DEBUG */ + size->size = dpi; + size->entries = numfonts; + size->entry = entry; + for (;numfonts > 0; numfonts--, entry++) { + /* read each entry */ + pkquad(); /* ignore length of font */ + entry->offset = pkquad(); /* offset to font */ + len = pkbyte(); /* length of name */ + for (i=0; i<len; i++) + fontname[i] = pkbyte(); + fontname[len] = '\0'; + entry->name = newstring(fontname); + } /* end for numfonts>0 */ + } /* end for numsizes>0 */ + if (numflib < FLICSIZE) { /* leave first few open */ + fli_cache[numflib]->lib = lib; + fli_cache[numflib]->fp = pkfile; + } + else + fclose(pkfile); + numflib++; + } /* end if opened library */ + } /* end if (*name) */ + } +} + + +/* + * flisearch searches all the font libraries for a PK font. + * returns FILE pointer positioned to PK font in font library + * flisearch caches file pointers for 4 font libraries. + */ +FILE * +flisearch(char *n, halfword dpi) +{ + halfword dpi1, numsizes, numfonts; + struct fli_lib *lib=NULL; + struct fli_size *size; + struct fli_entry *entry; + struct fli_centry *centry; + int i; + Boolean found; + + if (firstlib == (struct fli_lib *)NULL) + return((FILE *)NULL); /* return if no font libraries */ + +#ifdef DEBUG + if (dd(D_FONTS)) { + fprintf(stderr,"Trying %s at %ddpi\nfli open:", n, dpi); + for (i=0; i<FLICSIZE; i++) /* dump cache contents */ + if (fli_cache[i]->lib != (struct fli_lib *)NULL) + fprintf(stderr, " %s",(fli_cache[i]->lib)->name); + fprintf(stderr,"\n"); + } +#endif /* DEBUG */ + for (lib = firstlib; lib != (struct fli_lib *)NULL; lib = lib->next ) { + /* for each font library */ + numsizes = lib->sizes; + size = lib->size; +#ifdef DEBUG + if (dd(D_FONTS)) + fprintf(stderr," Searching %s\n", lib->name); +#endif /* DEBUG */ + for (; numsizes>0; numsizes--, size++) { + /* for each font size in this library */ + dpi1 = (halfword)((size->size+32768L)/65536); + if ( dpi1 == dpi ) { + /* if correct size then search for font */ +#ifdef DEBUG + if (dd(D_FONTS)) + fprintf(stderr, " Checking size %ddpi\n",dpi1); +#endif /* DEBUG */ + entry = size->entry; + for (numfonts=size->entries;numfonts > 0; numfonts--, entry++) { + if (strcmp(entry->name,n)==0) { + /* if correct font name then look for it in cache */ + found = 0; + for (i=0; i<FLICSIZE && !found; i++) { /* check if fli in cache */ + if ( fli_cache[i]->lib == lib ) { + /* found it, so move to front */ + centry = fli_cache[i]; + for (; i>0; i--) + fli_cache[i] = fli_cache[i-1]; + found=1; + fli_cache[0] = centry; + pkfile = fli_cache[0]->fp; /* font libary already open */ + } + } + if (!found) { /* if not in cache then re-open it */ + /* make space at front */ + fclose(fli_cache[FLICSIZE-1]->fp); + centry = fli_cache[FLICSIZE-1]; + for (i=FLICSIZE-1; i>0; i--) + fli_cache[i] = fli_cache[i-1]; + /* put this font library at front */ + if ( (pkfile=search(flipath,lib->name,READBIN)) == (FILE *)NULL ) { + sprintf(errbuf,"Can't reopen font library %.500s", lib->name); + error(errbuf); + return((FILE *)NULL); + } + fli_cache[0] = centry; + fli_cache[0]->lib = lib; + fli_cache[0]->fp = pkfile; + } + flib = 1; /* tell loadfont() not to close it */ + /* then seek font within library */ + sprintf(name,"%.500s %.500s %ddpi",lib->name, n, dpi1); + if (fseek(pkfile,entry->offset,0) ) + badpk("couldn't seek font"); + /* make sure it is a PK font */ + if (pkbyte()==247) /* pre byte */ + if (pkbyte()==89) { /* id byte */ + if ( fseek(pkfile,entry->offset,0) ) + badpk("couldn't seek font"); + return(pkfile); /* found it */ + } + sprintf(errbuf,"%.500s %.500s %ddpi isn't PK format, ignoring", + lib->name, n, dpi1); + error(errbuf); + } /* end if name correct */ + } /* end for numfonts>0 */ + } + else { + /* if not correct size then skip */ +#ifdef DEBUG + if (dd(D_FONTS)) + fprintf(stderr, " Skipping size %ddpi\n", dpi1); +#endif /* DEBUG */ + } + } /* end for numsizes>0 */ + } + return((FILE *)NULL); +} + +/* parse the font library path, putting all directory names in path, + * and all font library names in name. + * Directory names have a trailing DIRSEP. + */ +char * +fliparse(char *path, char *name) +{ + char *p, *prevp; /* pointers to path */ + char *n, *prevn; /* pointers to name */ + char *s; + + p = path; + n = name; + s = path; + + while (*s) { + prevp = p; + prevn = n; + while (*s && *s != PATHSEP) { + /* copy till PATHSEP */ + *p++ = *s; + *n++ = *s; + s++; + } + *n = '\0'; + if (*s) + s++; /* skip PATHSEP */ + + if ( *prevn=='\0' || prevn[strlen(prevn)-1] == DIRSEP ) { + n = prevn; /* ignore name if it is dir */ + if (*prevn) + p--; /* backup over DIRSEP */ + *p++ = PATHSEP; + prevp = p; + } + else { + p = prevp; /* ignore path if it is library name */ + *n++ = PATHSEP; + prevn = n; + } + + } + *p = '\0'; + *n = '\0'; + if (n!=name && *--n==PATHSEP) + *n = '\0'; /* remove trailing PATHSEP from name */ + if (p!=path && *--p==PATHSEP) + *p = '\0'; /* remove trailing PATHSEP from path */ + return(path); +} /* end fliparse */ +#else +/* + * Some systems don't like .o files that compile to nothing, so we + * provide a stub routine. + */ +void fliload() {} +#endif + |