home *** CD-ROM | disk | FTP | other *** search
/ NeXTSTEP 3.3.4.17 [SPARC, PA-RISC] / nextstep33_risc.iso / NextLibrary / TeX / tex / src / texview / resident.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-01-27  |  8.1 KB  |  319 lines

  1. /*
  2.  *   resident.c of TeXview software package.  (C) 1986 Radical Eye Software.
  3.  *   This code reads in and handles the postscript fonts.
  4.  */
  5. #include "structures.h"
  6. #include "paths.h"
  7. #include <string.h>
  8. /*
  9.  *   This is the structure definition for resident fonts.  We use
  10.  *   a small and simple hash table to handle these.  We don't need
  11.  *   a big hash table.
  12.  */
  13. struct resfont *reshash[RESHASHPRIME] ;
  14. /*
  15.  *   These are the external routines we use.
  16.  */
  17. extern void add_header() ;
  18. extern void error() ;
  19. extern integer scalewidth() ;
  20. extern void tfmload() ;
  21. extern FILE *search() ;
  22. extern void setenvvars() ;
  23. extern char *malloc() ;
  24. extern void setenvvars() ;
  25. extern shalfword pkbyte() ;
  26. extern integer pkquad() ;
  27. extern integer pktrio() ;
  28. extern Boolean pkopen() ;
  29. extern char *pkpath, *vfpath, *tfmpath, *configpath, *headerpath ;
  30. /*
  31.  *   These are the external variables we use.
  32.  */
  33. extern int lastresortsizes[] ;
  34. /*
  35.  *   We use malloc here.
  36.  */
  37. char *mymalloc() ;
  38. /*
  39.  *   Allocate a new string.
  40.  */
  41. char *newstring(s)
  42. char *s ;
  43. {
  44.    if (s==NULL)
  45.       return(NULL) ;
  46.    else
  47.       return(strcpy(mymalloc(strlen(s)+1), s)) ;
  48. }
  49. /*
  50.  *   Our hash routine.
  51.  */
  52. int
  53. hash(s)
  54.    char *s ;
  55. {
  56.    int h = 12 ;
  57.  
  58.    while (*s != 0)
  59.       h = (h + h + *s++) % RESHASHPRIME ;
  60.    return(h) ;
  61. }
  62. /*
  63.  *   Cleanres marks all resident fonts as not being yet sent.
  64.  */
  65. void cleanres() {
  66.    register int i ;
  67.    register struct resfont *p ;
  68.  
  69.    for (i=0; i<RESHASHPRIME; i++)
  70.       for (p=reshash[i]; p; p=p->next)
  71.          p->sent = 0 ;
  72. }
  73. /*
  74.  *   The routine which looks up a font name.
  75.  */
  76. struct resfont *
  77. lookup(name)
  78.    char *name ;
  79. {
  80.    struct resfont *p ;
  81.  
  82.    for (p=reshash[hash(name)]; p!=NULL; p=p->next)
  83.       if (strcmp(p->TeXname, name)==0)
  84.          return(p) ;
  85.    return(NULL) ;
  86. }
  87. /*
  88.  *   This routine adds an entry.
  89.  */
  90. void
  91. add_entry(Keyname, TeXname, PSname, specinfo, downloadinfo)
  92.    char *Keyname, *TeXname, *PSname, *specinfo, *downloadinfo ;
  93. {
  94.    struct resfont *p ;
  95.    int h ;
  96.  
  97.    if (PSname == NULL)
  98.       PSname = TeXname ;
  99.    else if (strcmp(PSname, TeXname) && Keyname != PSname)
  100.       add_entry(PSname, TeXname, PSname, specinfo, downloadinfo) ;
  101.    p = (struct resfont *)malloc((unsigned int)sizeof(struct resfont)) ;
  102.    if (p==NULL)
  103.       error("! out of memory") ;
  104.    p->Keyname = Keyname ;
  105.    p->PSname = PSname ;
  106.    p->TeXname = TeXname ;
  107.    p->specialinstructions = specinfo ;
  108.    p->downloadheader = downloadinfo ;
  109.    h = hash(Keyname) ;
  110.    p->next = reshash[h] ;
  111.    p->sent = 0 ;
  112.    reshash[h] = p ;
  113. }
  114. /*
  115.  *   Now our residentfont routine.
  116.  */
  117. Boolean
  118. residentfont(curfnt)
  119. register TeXfontdesctype *curfnt ;
  120. {
  121.    register shalfword i ;
  122.    struct resfont *p ;
  123.  
  124. /*
  125.  *   First we determine if we can find this font in the resident list.
  126.  */
  127.    if (*curfnt->name)
  128.       return 0 ; /* resident fonts never have a nonstandard font area */
  129.    if ((p=lookup(curfnt->name+1))==NULL)
  130.       return 0 ;
  131. /*
  132.  *   We clear out some pointers:
  133.  */
  134.    curfnt->loaded->resfont = p ;
  135.    for (i=0; i<256; i++) {
  136.       curfnt->loaded->chardesc[i].TFMwidth = 0 ;
  137.       curfnt->loaded->chardesc[i].pixelwidth = 0 ;
  138.    }
  139.    tfmload(curfnt, 0) ;
  140.    return(1) ;
  141. }
  142. static char was_inline[2000] ;
  143. void bad_config() {
  144.    error("Error in config file:") ;
  145.    error(was_inline) ;
  146. }
  147. char *psinfoname = RESFONTSFILE ;
  148. void getpsinfo(name)
  149. char *name ;
  150. {
  151.    FILE *deffile ;
  152.    char *p ;
  153.    char *specinfo, *downloadinfo ;
  154.    char downbuf[200] ;
  155.  
  156.    if (name == 0)
  157.       name = psinfoname ;
  158.    if ((deffile=search(configpath,name))!=NULL) {
  159.       while (fgets(was_inline, 100, deffile)!=NULL) {
  160.          p = was_inline ;
  161.          if (*p > ' ' && *p != '*' && *p != '#' && *p != ';') {
  162.             char *TeXname = NULL ;
  163.             char *PSname = NULL ;
  164.             specinfo = NULL ;
  165.             downloadinfo = NULL ;
  166.             downbuf[0] = 0 ;
  167.             p = was_inline ;
  168.             while (*p) {
  169.                while (*p && *p <= ' ')
  170.                   p++ ;
  171.                if (*p) {
  172.                   if (*p == '"')
  173.                      specinfo = p + 1 ;
  174.                   else if (*p == '<') {
  175.                      if (downloadinfo) {
  176.                         strcat(downbuf, downloadinfo) ;
  177.                         strcat(downbuf, " ") ;
  178.                      }
  179.                      downloadinfo = p + 1 ;
  180.                   } else if (TeXname)
  181.                      PSname = p ;
  182.                   else
  183.                      TeXname = p ;
  184.                   if (*p == '"') {
  185.                      p++ ;
  186.                      while (*p != '"' && *p)
  187.                         p++ ;
  188.                   } else
  189.                      while (*p > ' ')
  190.                         p++ ;
  191.                   if (*p)
  192.                      *p++ = 0 ;
  193.                }
  194.             }
  195.             if (downloadinfo)
  196.                strcat(downbuf, downloadinfo) ;
  197.             if (TeXname) {
  198.                TeXname = newstring(TeXname) ;
  199.                specinfo = newstring(specinfo) ;
  200.                PSname = newstring(PSname) ;
  201.                if (downbuf[0])
  202.                   downloadinfo = newstring(downbuf) ;
  203.                add_entry(TeXname, TeXname, PSname, specinfo, downloadinfo) ;
  204.             }
  205.          }
  206.       }
  207.       (void)fclose(deffile) ;
  208.    }
  209. }
  210. /*
  211.  *   Now we have the getdefaults routine.
  212.  */
  213. void
  214. getdefaults(s)
  215. char *s ;
  216. {
  217.    FILE *deffile ;
  218.    char PSname[100] ;
  219.    register char *p ;
  220.    int i, j ;
  221.    static int again = 0 ;
  222.    char *d = configpath ;
  223.  
  224.    if (s) {
  225.       strcpy(PSname, s) ;
  226.    } else {
  227.       d = "~" ;
  228.       strcpy(PSname, ".dvipsrc") ;
  229.    }
  230.    if ((deffile=search(d,PSname))!=NULL) {
  231.       while (fgets(was_inline, 300, deffile)!=NULL) {
  232.        switch (was_inline[0]) {
  233. case 'T' : 
  234.          if (sscanf(was_inline+1, "%s", PSname) != 1) bad_config() ;
  235.          else tfmpath = newstring(PSname) ;
  236.          break ;
  237. case 'p' :
  238.          p = was_inline + 1 ;
  239.          while (*p && *p <= ' ')
  240.             p++ ;
  241.          if (*p == '+') {
  242.             if (sscanf(p+1, "%s", PSname) != 1) bad_config() ;
  243.             getpsinfo(PSname) ;
  244.          } else {
  245.             if (sscanf(p, "%s", PSname) != 1) bad_config() ;
  246.             psinfoname = newstring(PSname) ;
  247.          }
  248.          break ;
  249. case 'P' :
  250.          if (sscanf(was_inline+1, "%s", PSname) != 1) bad_config() ;
  251.          else pkpath = newstring(PSname) ;
  252.          break ;
  253. case 'H':
  254.          if (sscanf(was_inline+1, "%s", PSname) != 1) bad_config() ;
  255.          else headerpath = newstring(PSname) ;
  256.          break ;
  257. case 'V' : case 'v' :
  258.          if (sscanf(was_inline+1, "%s", PSname) != 1) bad_config() ;
  259.          else vfpath = newstring(PSname) ;
  260.          break ;
  261. /*
  262. case 's' :
  263.          if (sscanf(was_inline+1, "%s", PSname) != 1) bad_config() ;
  264.          else figpath = newstring(PSname) ;
  265.          break ;
  266.  */
  267. /*
  268.  *   This case is for last resort font scaling; I hate this, but enough
  269.  *   people have in no uncertain terms demanded it that I'll go ahead and
  270.  *   add it.
  271.  *
  272.  *   This line must have numbers on it, resolutions, to search for the
  273.  *   font as a last resort, and then the font will be scaled.  These
  274.  *   resolutions should be in increasing order.
  275.  *
  276.  *   For most machines, just `300' is sufficient here; on the NeXT,
  277.  *   `300 400' may be more appropriate.
  278.  */
  279. case 'R':
  280.          i = 0 ;
  281.          p = was_inline + 1 ;
  282.          while (*p) {
  283.             while (*p && *p <= ' ')
  284.                p++ ;
  285.             if ('0' <= *p && *p <= '9') {
  286.                j = 0 ;
  287.                while ('0' <= *p && *p <= '9')
  288.                   j = 10 * j + (*p++ - '0') ;
  289.                if (i > 0)
  290.                   if (lastresortsizes[i-1] > j) {
  291.                      error("last resort sizes (R) must be sorted") ;
  292.                      bad_config() ;
  293.                   }
  294.                lastresortsizes[i++] = j ;
  295.             } else {
  296.                if (*p == 0)
  297.                   break ;
  298.                error("! only numbers expected on `R' line in config!") ;
  299.             }
  300.          }
  301.          lastresortsizes[i] = 32000 ;
  302.          break ;
  303. case 'h' : 
  304.          if (sscanf(was_inline+1, "%s", PSname) != 1) bad_config() ;
  305.          else add_header(PSname) ;
  306.          break ;
  307. default:
  308.          break ;
  309.       }
  310.      }
  311.      (void)fclose(deffile) ;
  312.    }
  313.    if (again) {
  314.       return ;
  315.    } else
  316.       again = 1 ;
  317.    getpsinfo(0) ;
  318. }
  319.