home *** CD-ROM | disk | FTP | other *** search
- /*
- * 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 <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() ;
- extern Boolean pkopen() ;
- extern char *pkpath, *vfpath, *tfmpath, *configpath, *headerpath ;
- /*
- * 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[2000] ;
- 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[200] ;
-
- if (name == 0)
- name = psinfoname ;
- if ((deffile=search(configpath,name))!=NULL) {
- while (fgets(was_inline, 100, 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) ;
- }
- }
- /*
- * Now we have the getdefaults routine.
- */
- void
- getdefaults(s)
- char *s ;
- {
- FILE *deffile ;
- char PSname[100] ;
- register char *p ;
- int i, j ;
- static int again = 0 ;
- char *d = configpath ;
-
- if (s) {
- strcpy(PSname, s) ;
- } else {
- d = "~" ;
- strcpy(PSname, ".dvipsrc") ;
- }
- if ((deffile=search(d,PSname))!=NULL) {
- while (fgets(was_inline, 300, deffile)!=NULL) {
- switch (was_inline[0]) {
- case 'T' :
- if (sscanf(was_inline+1, "%s", PSname) != 1) bad_config() ;
- else tfmpath = newstring(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 pkpath = newstring(PSname) ;
- break ;
- case 'H':
- if (sscanf(was_inline+1, "%s", PSname) != 1) bad_config() ;
- else headerpath = newstring(PSname) ;
- break ;
- case 'V' : case 'v' :
- if (sscanf(was_inline+1, "%s", PSname) != 1) bad_config() ;
- else vfpath = newstring(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) ;
- }
-