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