ftp.nice.ch/pub/next/text/tex/apps/TeXview-kp0.25.s.tar.gz#/TeXview-grey/resident.c

This is resident.c in view mode; [Download] [Up]

/*
 *   resident.c of TeXview software package.  (C) 1986 Radical Eye Software.
 *   This code reads in and handles the postscript fonts.
 */
#include "structures.h"
#include "paths.h"
#include <kpathsea/tex-file.h>
#include <string.h>
/*
 *   This is the structure definition for resident fonts.  We use
 *   a small and simple hash table to handle these.  We don't need
 *   a big hash table.
 */
struct resfont *reshash[RESHASHPRIME] ;
/*
 *   These are the external routines we use.
 */
extern void add_header() ;
extern void error() ;
extern integer scalewidth() ;
extern void tfmload() ;
extern FILE *search() ;
extern void setenvvars() ;
extern char *malloc() ;
extern void setenvvars() ;
extern shalfword pkbyte() ;
extern integer pkquad() ;
extern integer pktrio() ;
/*
 *   These are the external variables we use.
 */
extern int lastresortsizes[] ;
/*
 *   We use malloc here.
 */
char *mymalloc() ;
/*
 *   Allocate a new string.
 */
char *newstring(s)
char *s ;
{
   if (s==NULL)
      return(NULL) ;
   else
      return(strcpy(mymalloc(strlen(s)+1), s)) ;
}
/*
 *   Our hash routine.
 */
int
hash(s)
   char *s ;
{
   int h = 12 ;

   while (*s != 0)
      h = (h + h + *s++) % RESHASHPRIME ;
   return(h) ;
}
/*
 *   Cleanres marks all resident fonts as not being yet sent.
 */
void cleanres() {
   register int i ;
   register struct resfont *p ;

   for (i=0; i<RESHASHPRIME; i++)
      for (p=reshash[i]; p; p=p->next)
         p->sent = 0 ;
}
/*
 *   The routine which looks up a font name.
 */
struct resfont *
lookup(name)
   char *name ;
{
   struct resfont *p ;

   for (p=reshash[hash(name)]; p!=NULL; p=p->next)
      if (strcmp(p->TeXname, name)==0)
         return(p) ;
   return(NULL) ;
}
/*
 *   This routine adds an entry.
 */
void
add_entry(Keyname, TeXname, PSname, specinfo, downloadinfo)
   char *Keyname, *TeXname, *PSname, *specinfo, *downloadinfo ;
{
   struct resfont *p ;
   int h ;

   if (PSname == NULL)
      PSname = TeXname ;
   else if (strcmp(PSname, TeXname) && Keyname != PSname)
      add_entry(PSname, TeXname, PSname, specinfo, downloadinfo) ;
   p = (struct resfont *)malloc((unsigned int)sizeof(struct resfont)) ;
   if (p==NULL)
      error("! out of memory") ;
   p->Keyname = Keyname ;
   p->PSname = PSname ;
   p->TeXname = TeXname ;
   p->specialinstructions = specinfo ;
   p->downloadheader = downloadinfo ;
   h = hash(Keyname) ;
   p->next = reshash[h] ;
   p->sent = 0 ;
   reshash[h] = p ;
}
/*
 *   Now our residentfont routine.
 */
Boolean
residentfont(curfnt)
register TeXfontdesctype *curfnt ;
{
   register shalfword i ;
   struct resfont *p ;

/*
 *   First we determine if we can find this font in the resident list.
 */
   if (*curfnt->name)
      return 0 ; /* resident fonts never have a nonstandard font area */
   if ((p=lookup(curfnt->name+1))==NULL)
      return 0 ;
/*
 *   We clear out some pointers:
 */
   curfnt->loaded->resfont = p ;
   for (i=0; i<256; i++) {
      curfnt->loaded->chardesc[i].TFMwidth = 0 ;
      curfnt->loaded->chardesc[i].pixelwidth = 0 ;
   }
   tfmload(curfnt, 0) ;
   return(1) ;
}
static char was_inline[1200] ;
void bad_config() {
   error("Error in config file:") ;
   error(was_inline) ;
}
char *psinfoname = RESFONTSFILE ;
void getpsinfo(name)
char *name ;
{
   FILE *deffile ;
   char *p ;
   char *specinfo, *downloadinfo ;
   char downbuf[1000] ;

   if (name == 0)
      name = psinfoname ;
   if ((deffile=search(configpath,name))!=NULL) {
      while (fgets(was_inline, 1000, deffile)!=NULL) {
         p = was_inline ;
         if (*p > ' ' && *p != '*' && *p != '#' && *p != ';') {
            char *TeXname = NULL ;
            char *PSname = NULL ;
            specinfo = NULL ;
            downloadinfo = NULL ;
            downbuf[0] = 0 ;
            p = was_inline ;
            while (*p) {
               while (*p && *p <= ' ')
                  p++ ;
               if (*p) {
                  if (*p == '"')
                     specinfo = p + 1 ;
                  else if (*p == '<') {
                     if (downloadinfo) {
                        strcat(downbuf, downloadinfo) ;
                        strcat(downbuf, " ") ;
                     }
                     downloadinfo = p + 1 ;
                  } else if (TeXname)
                     PSname = p ;
                  else
                     TeXname = p ;
                  if (*p == '"') {
                     p++ ;
                     while (*p != '"' && *p)
                        p++ ;
                  } else
                     while (*p > ' ')
                        p++ ;
                  if (*p)
                     *p++ = 0 ;
               }
            }
            if (downloadinfo)
               strcat(downbuf, downloadinfo) ;
            if (TeXname) {
               TeXname = newstring(TeXname) ;
               specinfo = newstring(specinfo) ;
               PSname = newstring(PSname) ;
               if (downbuf[0])
                  downloadinfo = newstring(downbuf) ;
               add_entry(TeXname, TeXname, PSname, specinfo, downloadinfo) ;
            }
         }
      }
      (void)fclose(deffile) ;
   }
}
/* We use this in `getdefaults' to modify the kpathsea structure for the
   paths we read.  See kpathsea/tex-file.[ch].  */
#define SET_CLIENT_PATH(filefmt, val) \
  kpse_format_info[filefmt].client_path = xstrdup (val)

/*
 *   Now we have the getdefaults routine.
 */
void
getdefaults(s)
char *s ;
{
   FILE *deffile ;
   char PSname[400] ;
   register char *p ;
   int i, j ;
   static int again = 0 ;

   if (s) {
      strcpy(PSname, s) ;
   } else {
      strcpy(PSname, ".dvipsrc") ;
   }
   if ((deffile=search(configpath,PSname))!=NULL) {
      while (fgets(was_inline, 500, deffile)!=NULL) {
       switch (was_inline[0]) {
case 'T' : 
         if (sscanf(was_inline+1, "%s", PSname) != 1) bad_config() ;
         else SET_CLIENT_PATH (kpse_tfm_format, PSname);
         break ;
case 'p' :
         p = was_inline + 1 ;
         while (*p && *p <= ' ')
            p++ ;
         if (*p == '+') {
            if (sscanf(p+1, "%s", PSname) != 1) bad_config() ;
            getpsinfo(PSname) ;
         } else {
            if (sscanf(p, "%s", PSname) != 1) bad_config() ;
            psinfoname = newstring(PSname) ;
         }
         break ;
case 'P' :
         if (sscanf(was_inline+1, "%s", PSname) != 1) bad_config() ;
         else SET_CLIENT_PATH (kpse_pk_format, PSname);
         break ;
case 'H':
         if (sscanf(was_inline+1, "%s", PSname) != 1) bad_config() ;
         else SET_CLIENT_PATH (kpse_dvips_header_format, PSname);
         break ;
case 'V' : case 'v' :
         if (sscanf(was_inline+1, "%s", PSname) != 1) bad_config() ;
         else SET_CLIENT_PATH (kpse_vf_format, PSname);
         break ;
/*
case 's' :
         if (sscanf(was_inline+1, "%s", PSname) != 1) bad_config() ;
         else figpath = newstring(PSname) ;
         break ;
 */
/*
 *   This case is for last resort font scaling; I hate this, but enough
 *   people have in no uncertain terms demanded it that I'll go ahead and
 *   add it.
 *
 *   This line must have numbers on it, resolutions, to search for the
 *   font as a last resort, and then the font will be scaled.  These
 *   resolutions should be in increasing order.
 *
 *   For most machines, just `300' is sufficient here; on the NeXT,
 *   `300 400' may be more appropriate.
 */
case 'R':
         i = 0 ;
         p = was_inline + 1 ;
         while (*p) {
            while (*p && *p <= ' ')
               p++ ;
            if ('0' <= *p && *p <= '9') {
               j = 0 ;
               while ('0' <= *p && *p <= '9')
                  j = 10 * j + (*p++ - '0') ;
               if (i > 0)
                  if (lastresortsizes[i-1] > j) {
                     error("last resort sizes (R) must be sorted") ;
                     bad_config() ;
                  }
               lastresortsizes[i++] = j ;
            } else {
               if (*p == 0)
                  break ;
               error("! only numbers expected on `R' line in config!") ;
            }
         }
         lastresortsizes[i] = 32000 ;
         break ;
case 'h' : 
         if (sscanf(was_inline+1, "%s", PSname) != 1) bad_config() ;
         else add_header(PSname) ;
         break ;
default:
         break ;
      }
     }
     (void)fclose(deffile) ;
   }
   if (again) {
      return ;
   } else
      again = 1 ;
   getpsinfo(0) ;
}

These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.