Back to index

tetex-bin  3.0
flib.c
Go to the documentation of this file.
00001 /*
00002  *   Here's some code to handle font libraries.  Not needed unless you are
00003  *   running on a system that can't handle files well.  Not endorsed by
00004  *   Tomas Rokicki or Radical Eye Software; use at your own risk.
00005  */
00006 #ifdef FONTLIB
00007 #include "dvips.h"
00008 #include "paths.h"
00009 #include "protos.h"
00010 extern int debug_flag ;
00011 extern char errbuf[] ;
00012 extern char *flipath ;
00013 extern char *fliname ;
00014 extern FILE *pkfile ;
00015 /*
00016  * font library structures
00017  */
00018 struct fli_entry {
00019    unsigned long  offset;
00020    char          *name;
00021 };
00022 
00023 struct fli_size {
00024    unsigned long     size;
00025    halfword          entries;
00026    struct fli_entry *entry;
00027 };
00028 
00029 struct fli_lib {
00030    char            *name;
00031    halfword         sizes;
00032    struct fli_size *size;
00033    struct fli_lib  *next;
00034 };
00035 
00036 struct fli_lib *firstlib = NULL;
00037 
00038 struct fli_centry {
00039    struct fli_lib  *lib;
00040    FILE            *fp;
00041 };
00042 
00043 #define FLICSIZE 4
00044 struct fli_centry *fli_cache[FLICSIZE];
00045 
00046 Boolean flib = 0;  /* non zero if reading a font library */
00047 
00048 halfword
00049 pkdouble P1H(void)
00050 {
00051    register halfword i ;
00052    i = pkbyte() ;
00053    i = i * 256 + pkbyte() ;
00054    return(i) ;
00055 }
00056 extern char name[] ;
00057 /*
00058  *   fliload opens each font library, then reads in its
00059  *   directory for later use.
00060  *   fli_cache is initialized.
00061  */
00062 void
00063 fliload P1H(void)
00064 {
00065    int i ;
00066    halfword version1, version2;
00067    Boolean needext;
00068    char fontname[50]; 
00069    char name[50] ;
00070    char *fli;
00071    unsigned long dpi;
00072    halfword len, numsizes, numfonts;
00073    halfword numflib = 0 ;
00074    struct fli_lib *lib=NULL, *next_lib=NULL;
00075    struct fli_size *size;
00076    struct fli_entry *entry;
00077 
00078    /* initialise fli cache */
00079    for (i=0; i<FLICSIZE; i++) {
00080       fli_cache[i] = (struct fli_centry *)
00081                       mymalloc((integer)sizeof(struct fli_centry)); 
00082       fli_cache[i]->lib = (struct fli_lib *)NULL;
00083       fli_cache[i]->fp = (FILE *)NULL;
00084    }
00085 
00086    fli = fliname;
00087 
00088    while (*fli) {
00089       /* get next font library name from fliname */
00090       needext=1;
00091       for (i=0; *fli && *fli!=PATHSEP; i++)
00092          if ( (name[i] = *fli++) == '.')
00093             needext=0;
00094       name[i] = '\0';
00095       if (*fli)
00096          fli++;  /* skip PATHSEP */
00097       if (*name) { 
00098          /* got fli name, now search for it */
00099          if (needext)
00100             strcat(name,".fli");
00101 
00102          if ( (pkfile=search(flipath,name,READBIN)) != (FILE *)NULL ) {
00103             /* for each font library */
00104             for (i=0; i<4; i++) {
00105               fontname[i] = pkbyte();  /* read header */
00106             }
00107             version1 = pkbyte();
00108             version2 = pkbyte();
00109             if (strncmp(fontname,"FLIB",4)!=0 || version1 != 2 || version2 != 0)
00110                badpk("incorrect font library format");
00111 
00112             (void) pkdouble();       /* ignore directory length */
00113             numsizes = pkdouble();   /* number of sizes */
00114             numfonts = pkdouble();   /* number of fonts */
00115             len = pkdouble();        /* length of comment */
00116             for (i=0; i<len; i++)
00117                (void)pkbyte();       /* skip comment */
00118 #ifdef DEBUG
00119    if (dd(D_FONTS))
00120       (void)fprintf(stderr,"Font library %s has %d font size%s, %d font%s\n",
00121          name, numsizes , numsizes !=1 ? "s" : "", 
00122          numfonts, numfonts!=1 ? "s" : "");
00123 #endif /* DEBUG */
00124 
00125             next_lib =  (struct fli_lib *)
00126                       mymalloc((integer)sizeof(struct fli_lib)); 
00127             if (firstlib == (struct fli_lib *)NULL)
00128                firstlib = next_lib;
00129             else
00130                lib->next = next_lib;
00131             lib = next_lib;
00132             size = (struct fli_size *)
00133                         mymalloc((integer)numsizes * sizeof(struct fli_size)); 
00134             entry = (struct fli_entry *)
00135                         mymalloc((integer)numfonts * sizeof(struct fli_entry)); 
00136             lib->name = newstring(name);
00137             lib->sizes = numsizes;
00138             lib->size = size;
00139             lib->next = (struct fli_lib *)NULL;
00140 
00141             for ( ;numsizes>0; numsizes--, size++) { 
00142                /* for each font size in this library */
00143                (void)pkdouble();      /* length of size entry - ignore */
00144                numfonts = pkdouble(); /* number of fonts */
00145                dpi = pkquad();        /* DPI (fixed point 16.16) */
00146 
00147 #ifdef DEBUG
00148    if (dd(D_FONTS))
00149       (void)fprintf(stderr,"Font library %s size %.5gdpi has %d font%s\n", 
00150                   name, dpi/65536.0, numfonts, numfonts!=1 ? "s" : "");
00151 #endif /* DEBUG */
00152                size->size    = dpi ;
00153                size->entries = numfonts ;
00154                size->entry   = entry ;
00155                   for ( ;numfonts > 0; numfonts--, entry++) {
00156                      /* read each entry */
00157                      (void)pkquad();            /* ignore length of font */
00158                      entry->offset = pkquad();  /* offset to font */
00159                      len = pkbyte();            /* length of name */
00160                      for (i=0; i<len; i++)
00161                         fontname[i] = pkbyte();
00162                      fontname[len] = '\0';
00163                      entry->name = newstring(fontname);
00164                   } /* end for numfonts>0 */
00165             }  /* end for numsizes>0 */
00166             if (numflib < FLICSIZE) { /* leave first few open */
00167                fli_cache[numflib]->lib = lib;
00168                fli_cache[numflib]->fp = pkfile;
00169             }
00170             else
00171                (void)fclose(pkfile);
00172             numflib++;
00173          }  /* end if opened library */
00174       } /* end if (*name) */
00175    }
00176 }
00177    
00178 
00179 /*
00180  *   flisearch searches all the font libraries for a PK font.
00181  *   returns FILE pointer positioned to PK font in font library
00182  *   flisearch caches file pointers for 4 font libraries.
00183  */
00184 FILE *
00185 flisearch P2C(char *, n, halfword, dpi)
00186 {
00187    halfword dpi1, numsizes, numfonts;
00188    struct fli_lib *lib=NULL;
00189    struct fli_size *size;
00190    struct fli_entry *entry;
00191    struct fli_centry *centry;
00192    int i;
00193    Boolean found;
00194    
00195    if (firstlib == (struct fli_lib *)NULL)
00196       return((FILE *)NULL);  /* return if no font libraries */
00197 
00198 #ifdef DEBUG
00199       if (dd(D_FONTS)) { 
00200          (void)fprintf(stderr,"Trying %s at %ddpi\nfli open:", n, dpi);
00201           for (i=0; i<FLICSIZE; i++)  /* dump cache contents */
00202             if (fli_cache[i]->lib != (struct fli_lib *)NULL)
00203               (void)fprintf(stderr, "   %s",(fli_cache[i]->lib)->name);
00204          (void)fprintf(stderr,"\n");
00205       }
00206 #endif /* DEBUG */
00207    for (lib = firstlib; lib != (struct fli_lib *)NULL; lib = lib->next ) {
00208       /* for each font library */
00209       numsizes = lib->sizes ;
00210       size = lib->size ;
00211 #ifdef DEBUG
00212       if (dd(D_FONTS))
00213          (void)fprintf(stderr,"  Searching %s\n", lib->name);
00214 #endif /* DEBUG */
00215       for (; numsizes>0; numsizes--, size++) { 
00216          /* for each font size in this library */
00217          dpi1 = (halfword)((size->size+32768L)/65536) ;
00218          if ( dpi1 == dpi ) {
00219             /* if correct size then search for font */
00220 #ifdef DEBUG
00221             if (dd(D_FONTS))
00222                (void)fprintf(stderr, "    Checking size %ddpi\n",dpi1);
00223 #endif /* DEBUG */
00224             entry = size->entry ;
00225             for (numfonts=size->entries ;numfonts > 0; numfonts--, entry++) {
00226                if (strcmp(entry->name,n)==0) {
00227                   /* if correct font name then look for it in cache */
00228                      found = 0;
00229                      for (i=0; i<FLICSIZE && !found; i++) {  /* check if fli in cache */
00230                         if ( fli_cache[i]->lib == lib ) {
00231                            /* found it, so move to front */
00232                            centry = fli_cache[i];
00233                            for (; i>0; i--)
00234                              fli_cache[i] = fli_cache[i-1];
00235                            found=1;
00236                            fli_cache[0] = centry;
00237                            pkfile = fli_cache[0]->fp;  /* font libary already open */
00238                         }
00239                      }
00240                      if (!found) { /* if not in cache then re-open it */
00241                         /* make space at front */
00242                         (void)fclose(fli_cache[FLICSIZE-1]->fp); 
00243                         centry = fli_cache[FLICSIZE-1];
00244                         for (i=FLICSIZE-1; i>0; i--)
00245                              fli_cache[i] = fli_cache[i-1];
00246                         /* put this font library at front */
00247                         if ( (pkfile=search(flipath,lib->name,READBIN)) == (FILE *)NULL ) {
00248                            sprintf(errbuf,"Can't reopen font library %s", lib->name);
00249                            error(errbuf);
00250                            return((FILE *)NULL);
00251                      }
00252                         fli_cache[0] = centry;
00253                         fli_cache[0]->lib = lib;
00254                         fli_cache[0]->fp  = pkfile;
00255                      }
00256                      flib = 1 ;  /* tell loadfont() not to close it */
00257                      /* then seek font within library */
00258                      (void)sprintf(name,"%s %s %ddpi",lib->name, n, dpi1) ;
00259                      if ( fseek(pkfile,entry->offset,0) )
00260                            badpk("couldn't seek font");
00261                         /* make sure it is a PK font */
00262                         if (pkbyte()==247) /* pre byte */
00263                            if (pkbyte()==89) {  /* id byte */
00264                               if ( fseek(pkfile,entry->offset,0) )
00265                                  badpk("couldn't seek font");
00266                               return(pkfile); /* found it */
00267                            }
00268                         sprintf(errbuf,"%s %s %ddpi isn't PK format, ignoring",
00269                               lib->name, n, dpi1);
00270                         error(errbuf);
00271                } /* end if name correct */
00272             } /* end for numfonts>0 */
00273          }
00274          else {
00275             /* if not correct size then skip */
00276 #ifdef DEBUG
00277       if (dd(D_FONTS))
00278          (void)fprintf(stderr, "    Skipping size %ddpi\n", dpi1);
00279 #endif /* DEBUG */
00280          }
00281       }  /* end for numsizes>0 */
00282    }
00283    return((FILE *)NULL);
00284 }
00285 
00286 /* parse the font library path, putting all directory names in path, 
00287  * and all font library names in name.  
00288  * Directory names have a trailing DIRSEP.
00289  */
00290 char *
00291 fliparse P2C(char *, path, char *, name)
00292 {
00293    char *p, *prevp ;           /* pointers to path */
00294    char *n, *prevn ;           /* pointers to name */
00295    char *s ;
00296 
00297    p = path ;
00298    n = name ;
00299    s = path ;
00300 
00301    while (*s) {
00302       prevp = p ;
00303       prevn = n ;
00304       while (*s && *s != PATHSEP) {
00305          /* copy till PATHSEP */
00306          *p++ = *s; 
00307          *n++ = *s;
00308          s++;
00309       }  
00310       *n = '\0' ;
00311       if (*s)
00312          s++;  /* skip PATHSEP */
00313 
00314       if ( *prevn=='\0' || prevn[strlen(prevn)-1] == DIRSEP ) {
00315          n = prevn ; /* ignore name if it is dir */
00316          if (*prevn)
00317             p--;     /* backup over DIRSEP */
00318          *p++ = PATHSEP;
00319          prevp = p ;
00320       }
00321       else {
00322          p = prevp ; /* ignore path if it is library name */
00323          *n++ = PATHSEP;
00324          prevn = n ;
00325       }
00326 
00327    }
00328    *p = '\0' ;
00329    *n = '\0' ;
00330    if (n!=name && *--n==PATHSEP)
00331       *n = '\0'; /* remove trailing PATHSEP from name */
00332    if (p!=path && *--p==PATHSEP)
00333       *p = '\0'; /* remove trailing PATHSEP from path */
00334    return(path);
00335 }               /* end fliparse */
00336 #else
00337 /*
00338  *   Some systems don't like .o files that compile to nothing, so we
00339  *   provide a stub routine.
00340  */
00341 void fliload() {}
00342 #endif
00343