/* * 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; ilib = (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; inext = 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; iname = 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; ilib != (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; ilib == 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