home *** CD-ROM | disk | FTP | other *** search
/ OpenStep 3.3J / os33j.iso / NextLibrary / TeX / tex / src / dvips / flib.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-01-19  |  11.2 KB  |  352 lines

  1. /*
  2.  *   Here's some code to handle font libraries.  Not needed unless you are
  3.  *   running on a system that can't handle files well.  Not endorsed by
  4.  *   Tomas Rokicki or Radical Eye Software; use at your own risk.
  5.  */
  6. #ifdef FONTLIB
  7. #include "dvips.h"
  8. #include "paths.h"
  9. extern FILE *search() ;
  10. extern char *newstring() ;
  11. extern shalfword pkbyte() ;
  12. extern void badpk() ;
  13. extern integer pkquad() ;
  14. extern int debug_flag ;
  15. extern char errbuf[] ;
  16. extern char *flipath ;
  17. extern char *fliname ;
  18. extern FILE *pkfile ;
  19. /*
  20.  * font library structures
  21.  */
  22. struct fli_entry {
  23.    unsigned long  offset;
  24.    char          *name;
  25. };
  26.  
  27. struct fli_size {
  28.    unsigned long     size;
  29.    halfword          entries;
  30.    struct fli_entry *entry;
  31. };
  32.  
  33. struct fli_lib {
  34.    char            *name;
  35.    halfword         sizes;
  36.    struct fli_size *size;
  37.    struct fli_lib  *next;
  38. };
  39.  
  40. struct fli_lib *firstlib = NULL;
  41.  
  42. struct fli_centry {
  43.    struct fli_lib  *lib;
  44.    FILE            *fp;
  45. };
  46.  
  47. #define FLICSIZE 4
  48. struct fli_centry *fli_cache[FLICSIZE];
  49.  
  50. Boolean flib = 0;  /* non zero if reading a font library */
  51.  
  52. halfword
  53. pkdouble()
  54. {
  55.    register halfword i ;
  56.    i = pkbyte() ;
  57.    i = i * 256 + pkbyte() ;
  58.    return(i) ;
  59. }
  60. extern char name[] ;
  61. /*
  62.  *   fliload opens each font library, then reads in its
  63.  *   directory for later use.
  64.  *   fli_cache is initialized.
  65.  */
  66. void
  67. fliload()
  68. {
  69.    int i ;
  70.    halfword version1, version2;
  71.    Boolean needext;
  72.    char fontname[50]; 
  73.    char name[50] ;
  74.    char *fli;
  75.    unsigned long dpi;
  76.    halfword len, numsizes, numfonts;
  77.    halfword numflib = 0 ;
  78.    struct fli_lib *lib=NULL, *next_lib=NULL;
  79.    struct fli_size *size;
  80.    struct fli_entry *entry;
  81.  
  82.    /* initialise fli cache */
  83.    for (i=0; i<FLICSIZE; i++) {
  84.       fli_cache[i] = (struct fli_centry *)
  85.                       mymalloc((integer)sizeof(struct fli_centry)); 
  86.       fli_cache[i]->lib = (struct fli_lib *)NULL;
  87.       fli_cache[i]->fp = (FILE *)NULL;
  88.    }
  89.  
  90.    fli = fliname;
  91.  
  92.    while (*fli) {
  93.       /* get next font library name from fliname */
  94.       needext=1;
  95.       for (i=0; *fli && *fli!=PATHSEP; i++)
  96.          if ( (name[i] = *fli++) == '.')
  97.             needext=0;
  98.       name[i] = '\0';
  99.       if (*fli)
  100.          fli++;  /* skip PATHSEP */
  101.       if (*name) { 
  102.          /* got fli name, now search for it */
  103.          if (needext)
  104.             strcat(name,".fli");
  105.  
  106.          if ( (pkfile=search(flipath,name,READBIN)) != (FILE *)NULL ) {
  107.             /* for each font library */
  108.             for (i=0; i<4; i++) {
  109.               fontname[i] = pkbyte();  /* read header */
  110.             }
  111.             version1 = pkbyte();
  112.             version2 = pkbyte();
  113.             if (strncmp(fontname,"FLIB",4)!=0 || version1 != 2 || version2 != 0)
  114.                badpk("incorrect font library format");
  115.  
  116.             (void) pkdouble();       /* ignore directory length */
  117.             numsizes = pkdouble();   /* number of sizes */
  118.             numfonts = pkdouble();   /* number of fonts */
  119.             len = pkdouble();        /* length of comment */
  120.             for (i=0; i<len; i++)
  121.                (void)pkbyte();       /* skip comment */
  122. #ifdef DEBUG
  123.    if (dd(D_FONTS))
  124.       (void)fprintf(stderr,"Font library %s has %d font size%s, %d font%s\n",
  125.          name, numsizes , numsizes !=1 ? "s" : "", 
  126.          numfonts, numfonts!=1 ? "s" : "");
  127. #endif /* DEBUG */
  128.  
  129.             next_lib =  (struct fli_lib *)
  130.                       mymalloc((integer)sizeof(struct fli_lib)); 
  131.             if (firstlib == (struct fli_lib *)NULL)
  132.                firstlib = next_lib;
  133.             else
  134.                lib->next = next_lib;
  135.             lib = next_lib;
  136.             size = (struct fli_size *)
  137.                         mymalloc((integer)numsizes * sizeof(struct fli_size)); 
  138.             entry = (struct fli_entry *)
  139.                         mymalloc((integer)numfonts * sizeof(struct fli_entry)); 
  140.             lib->name = newstring(name);
  141.             lib->sizes = numsizes;
  142.             lib->size = size;
  143.             lib->next = (struct fli_lib *)NULL;
  144.  
  145.             for ( ;numsizes>0; numsizes--, size++) { 
  146.                /* for each font size in this library */
  147.                (void)pkdouble();      /* length of size entry - ignore */
  148.                numfonts = pkdouble(); /* number of fonts */
  149.                dpi = pkquad();        /* DPI (fixed point 16.16) */
  150.  
  151. #ifdef DEBUG
  152.    if (dd(D_FONTS))
  153.       (void)fprintf(stderr,"Font library %s size %.5gdpi has %d font%s\n", 
  154.                   name, dpi/65536.0, numfonts, numfonts!=1 ? "s" : "");
  155. #endif /* DEBUG */
  156.                size->size    = dpi ;
  157.                size->entries = numfonts ;
  158.                size->entry   = entry ;
  159.                   for ( ;numfonts > 0; numfonts--, entry++) {
  160.                      /* read each entry */
  161.                      (void)pkquad();            /* ignore length of font */
  162.                      entry->offset = pkquad();  /* offset to font */
  163.                      len = pkbyte();            /* length of name */
  164.                      for (i=0; i<len; i++)
  165.                         fontname[i] = pkbyte();
  166.                      fontname[len] = '\0';
  167.                      entry->name = newstring(fontname);
  168.                   } /* end for numfonts>0 */
  169.             }  /* end for numsizes>0 */
  170.             if (numflib < FLICSIZE) { /* leave first few open */
  171.                fli_cache[numflib]->lib = lib;
  172.                fli_cache[numflib]->fp = pkfile;
  173.             }
  174.             else
  175.                (void)fclose(pkfile);
  176.             numflib++;
  177.          }  /* end if opened library */
  178.       } /* end if (*name) */
  179.    }
  180. }
  181.    
  182.  
  183. /*
  184.  *   flisearch searches all the font libraries for a PK font.
  185.  *   returns FILE pointer positioned to PK font in font library
  186.  *   flisearch caches file pointers for 4 font libraries.
  187.  */
  188. FILE *
  189. flisearch(n, dpi)
  190. char *n;
  191. halfword dpi;
  192. {
  193.    halfword dpi1, numsizes, numfonts;
  194.    struct fli_lib *lib=NULL;
  195.    struct fli_size *size;
  196.    struct fli_entry *entry;
  197.    struct fli_centry *centry;
  198.    int i;
  199.    Boolean found;
  200.    int del ;
  201.    
  202.    if (firstlib == (struct fli_lib *)NULL)
  203.       return((FILE *)NULL);  /* return if no font libraries */
  204.  
  205. #ifdef DEBUG
  206.       if (dd(D_FONTS)) { 
  207.          (void)fprintf(stderr,"Trying %s at %ddpi\nfli open:", n, dpi);
  208.           for (i=0; i<FLICSIZE; i++)  /* dump cache contents */
  209.             if (fli_cache[i]->lib != (struct fli_lib *)NULL)
  210.               (void)fprintf(stderr, "   %s",(fli_cache[i]->lib)->name);
  211.          (void)fprintf(stderr,"\n");
  212.       }
  213. #endif /* DEBUG */
  214.    for (lib = firstlib; lib != (struct fli_lib *)NULL; lib = lib->next ) {
  215.       /* for each font library */
  216.       numsizes = lib->sizes ;
  217.       size = lib->size ;
  218. #ifdef DEBUG
  219.       if (dd(D_FONTS))
  220.          (void)fprintf(stderr,"  Searching %s\n", lib->name);
  221. #endif /* DEBUG */
  222.       for (; numsizes>0; numsizes--, size++) { 
  223.          /* for each font size in this library */
  224.          dpi1 = (halfword)((size->size+32768L)/65536) ;
  225.          if ( dpi1 == dpi ) {
  226.             /* if correct size then search for font */
  227. #ifdef DEBUG
  228.             if (dd(D_FONTS))
  229.                (void)fprintf(stderr, "    Checking size %ddpi\n",dpi1);
  230. #endif /* DEBUG */
  231.             entry = size->entry ;
  232.             for (numfonts=size->entries ;numfonts > 0; numfonts--, entry++) {
  233.                if (strcmp(entry->name,n)==0) {
  234.                   /* if correct font name then look for it in cache */
  235.                      found = 0;
  236.                      for (i=0; i<FLICSIZE && !found; i++) {  /* check if fli in cache */
  237.                         if ( fli_cache[i]->lib == lib ) {
  238.                            /* found it, so move to front */
  239.                            centry = fli_cache[i];
  240.                            for (; i>0; i--)
  241.                              fli_cache[i] = fli_cache[i-1];
  242.                            found=1;
  243.                            fli_cache[0] = centry;
  244.                            pkfile = fli_cache[0]->fp;  /* font libary already open */
  245.                         }
  246.                      }
  247.                      if (!found) { /* if not in cache then re-open it */
  248.                         /* make space at front */
  249.                         (void)fclose(fli_cache[FLICSIZE-1]->fp); 
  250.                         centry = fli_cache[FLICSIZE-1];
  251.                         for (i=FLICSIZE-1; i>0; i--)
  252.                              fli_cache[i] = fli_cache[i-1];
  253.                         /* put this font library at front */
  254.                         if ( (pkfile=search(flipath,lib->name,READBIN)) == (FILE *)NULL ) {
  255.                            sprintf(errbuf,"Can't reopen font library %s", lib->name);
  256.                            error(errbuf);
  257.                            return((FILE *)NULL);
  258.             }
  259.                         fli_cache[0] = centry;
  260.                         fli_cache[0]->lib = lib;
  261.                         fli_cache[0]->fp  = pkfile;
  262.                      }
  263.                      flib = 1 ;  /* tell loadfont() not to close it */
  264.                      /* then seek font within library */
  265.                      (void)sprintf(name,"%s %s %ddpi",lib->name, n, dpi1) ;
  266.                      if ( fseek(pkfile,entry->offset,0) )
  267.                            badpk("couldn't seek font");
  268.                         /* make sure it is a PK font */
  269.                         if (pkbyte()==247) /* pre byte */
  270.                            if (pkbyte()==89) {  /* id byte */
  271.                               if ( fseek(pkfile,entry->offset,0) )
  272.                                  badpk("couldn't seek font");
  273.                               return(pkfile); /* found it */
  274.                            }
  275.                         sprintf(errbuf,"%s %s %ddpi isn't PK format, ignoring",
  276.                               lib->name, n, dpi1);
  277.                         error(errbuf);
  278.                } /* end if name correct */
  279.             } /* end for numfonts>0 */
  280.          }
  281.          else {
  282.             /* if not correct size then skip */
  283. #ifdef DEBUG
  284.       if (dd(D_FONTS))
  285.          (void)fprintf(stderr, "    Skipping size %ddpi\n", dpi1);
  286. #endif /* DEBUG */
  287.          }
  288.       }  /* end for numsizes>0 */
  289.    }
  290.    return((FILE *)NULL);
  291. }
  292.  
  293. /* parse the font library path, putting all directory names in path, 
  294.  * and all font library names in name.  
  295.  * Directory names have a trailing DIRSEP.
  296.  */
  297. char *
  298. fliparse(path, name)
  299.         char *path, *name ;
  300. {
  301.    char *p, *prevp ;           /* pointers to path */
  302.    char *n, *prevn ;           /* pointers to name */
  303.    char *s ;
  304.  
  305.    p = path ;
  306.    n = name ;
  307.    s = path ;
  308.  
  309.    while (*s) {
  310.       prevp = p ;
  311.       prevn = n ;
  312.       while (*s && *s != PATHSEP) {
  313.          /* copy till PATHSEP */
  314.          *p++ = *s; 
  315.          *n++ = *s;
  316.          s++;
  317.       }  
  318.       *n = '\0' ;
  319.       if (*s)
  320.          s++;  /* skip PATHSEP */
  321.  
  322.       if ( *prevn=='\0' || prevn[strlen(prevn)-1] == DIRSEP ) {
  323.          n = prevn ; /* ignore name if it is dir */
  324.          if (*prevn)
  325.             p--;     /* backup over DIRSEP */
  326.          *p++ = PATHSEP;
  327.          prevp = p ;
  328.       }
  329.       else {
  330.          p = prevp ; /* ignore path if it is library name */
  331.          *n++ = PATHSEP;
  332.          prevn = n ;
  333.       }
  334.  
  335.    }
  336.    *p = '\0' ;
  337.    *n = '\0' ;
  338.    if (n!=name && *--n==PATHSEP)
  339.       *n = '\0'; /* remove trailing PATHSEP from name */
  340.    if (p!=path && *--p==PATHSEP)
  341.       *p = '\0'; /* remove trailing PATHSEP from path */
  342.    return(path);
  343. }               /* end fliparse */
  344. #else
  345. /*
  346.  *   Some systems don't like .o files that compile to nothing, so we
  347.  *   provide a stub routine.
  348.  */
  349. void fliload() {}
  350. #endif
  351.  
  352.