This is resident.c in view mode; [Download] [Up]
/* For use with emTeX set FONTPATH to "TEXTFM" */ #ifndef FONTPATH #define FONTPATH "TEXFONTS" #endif /* * This code reads in and handles the defaults for the program from the * file config.sw. This entire file is a bit kludgy, sorry. */ #include "dvips.h" /* The copyright notice in that file is included too! */ #include "paths.h" #include <kpathsea/c-pathch.h> #include <kpathsea/pathsearch.h> #include <kpathsea/tex-file.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 error() ; extern integer scalewidth() ; extern int tfmload() ; extern FILE *search() ; extern shalfword pkbyte() ; extern integer pkquad() ; extern integer pktrio() ; extern Boolean pkopen() ; extern char *getenv() ; extern char *newstring() ; extern int add_header() ; extern int add_name() ; extern char *get_name() ; extern int system() ; extern void handlepapersize() ; extern void checkstrings() ; void getpsinfo() ; extern void *revlist() ; /* * These are the external variables we use. */ #ifdef DEBUG extern integer debug_flag; #endif /* DEBUG */ extern integer pagecopies ; extern int overridemag ; extern long bytesleft ; extern quarterword *raster ; extern FILE *pkfile ; extern char *oname ; extern Boolean downloadpspk ; extern integer swmem, fontmem ; extern Boolean noenv ; #ifdef FONTLIB extern char *flipath, *fliname ; #endif extern char *paperfmt ; extern char *nextstring ; extern char *maxstring ; extern char *warningmsg ; extern Boolean disablecomments ; extern Boolean compressed ; extern int quiet ; extern int filter ; extern Boolean reverse ; extern Boolean usesPSfonts ; extern Boolean nosmallchars ; extern Boolean removecomments ; extern Boolean safetyenclose ; extern Boolean dopprescan ; extern integer maxsecsize ; extern integer mag ; extern Boolean sepfiles ; extern int actualdpi ; extern int vactualdpi ; extern int maxdrift ; extern int vmaxdrift ; extern char *printer ; extern char *mfmode ; extern int mfmode_option; extern int oname_option; extern Boolean sendcontrolD ; extern unsigned lastresortsizes[] ; extern integer hoff, voff ; extern struct papsiz *papsizes ; extern Boolean secure ; extern integer hpapersize, vpapersize ; extern int landscape ; /* * To maintain a list of document fonts, we use the following * pointer. */ struct header_list *ps_fonts_used ; /* * Our hash routine. */ int hash(s) char *s ; { int h = 12 ; while (*s != 0) h = (h + h + *s++) % RESHASHPRIME ; return(h) ; } /* * Reverse the hash chains. */ void revpslists() { register int i ; for (i=0; i<RESHASHPRIME; i++) reshash[i] = (struct resfont *)revlist(reshash[i]) ; } /* * 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 that 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->Keyname, name)==0) return(p) ; return(NULL) ; } /* * This routine adds an entry. */ void add_entry(TeXname, PSname, specinfo, downloadinfo) char *TeXname, *PSname, *specinfo, *downloadinfo ; { struct resfont *p ; int h ; if (PSname == NULL) PSname = TeXname ; p = (struct resfont *)mymalloc((integer)sizeof(struct resfont)) ; p->Keyname = TeXname ; p->PSname = PSname ; p->TeXname = TeXname ; p->specialinstructions = specinfo ; if (downloadinfo && *downloadinfo) p->downloadheader = downloadinfo ; else p->downloadheader = 0 ; h = hash(TeXname) ; p->next = reshash[h] ; p->sent = 0 ; reshash[h] = p ; } /* * Now our residentfont routine. Returns the number of characters in * this font, based on the TFM file. */ extern char *infont ; int residentfont(curfnt) register fontdesctype *curfnt ; { register shalfword i ; struct resfont *p ; /* * First we determine if we can find this font in the resident list. */ if (*curfnt->area) return 0 ; /* resident fonts never have a nonstandard font area */ if ((p=lookup(curfnt->name))==NULL) return 0 ; /* * This is not yet the correct way to do things, but it is useful as it * is so we leave it in. The problem: if resident Times-Roman is * re-encoded, then it will be downloaded as bitmaps; this is not * right. The solution will be to introduce two types of `<' * directives, one that downloads fonts and one that downloads * short headers that are innocuous. */ if (p->downloadheader && downloadpspk) { #ifdef DEBUG if (dd(D_FONTS)) (void)fprintf(stderr,"Using PK font %s for <%s>.\n", curfnt->name, p->PSname) ; #endif /* DEBUG */ return 0 ; } /* * We clear out some pointers: */ #ifdef DEBUG if (dd(D_FONTS)) (void)fprintf(stderr,"Font %s <%s> is resident.\n", curfnt->name, p->PSname) ; #endif /* DEBUG */ curfnt->resfont = p ; curfnt->name = p->TeXname ; for (i=0; i<256; i++) { curfnt->chardesc[i].TFMwidth = 0 ; curfnt->chardesc[i].packptr = NULL ; curfnt->chardesc[i].pixelwidth = 0 ; curfnt->chardesc[i].flags = 0 ; } add_name(p->PSname, &ps_fonts_used) ; /* * We include the font here. But we only should need to include the * font if we have a stupid spooler; smart spoolers should be able * to supply it automatically. */ if (p->downloadheader) { char *cp = p->downloadheader ; char *q ; infont = p->PSname ; while (1) { q = cp ; while (*cp && *cp != ' ') cp++ ; if (*cp) { *cp = 0 ; add_header(q) ; *cp++ = ' ' ; } else { add_header(q) ; break ; } infont = 0 ; } infont = 0 ; } i = tfmload(curfnt) ; if (i < 0) i = 1 ; usesPSfonts = 1 ; return(i) ; } #define INLINE_SIZE (500) static char was_inline[INLINE_SIZE] ; void bad_config() { error("Error in config file:") ; (void)fprintf(stderr, "%s\n", was_inline) ; exit(1) ; } /* * We use this function so we can support strings delimited by * double quotes with spaces in them. We also accept strings * with spaces in them, but kill off any spaces at the end. */ char *configstring(s, nullok) char *s ; int nullok ; { char tstr[300] ; char *p = tstr ; while (*s && *s <= ' ') s++ ; if (*s == '"') { s++ ; while (*s != 10 && *s != 0 && *s != '"' && p < tstr+290) *p++ = *s++ ; } else { while (*s && p < tstr+290) *p++ = *s++ ; while (*(p-1) <= ' ' && p > tstr) p-- ; } *p = 0 ; if (p == tstr && ! nullok) bad_config() ; return newstring(tstr) ; } /* 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. */ static char *psmapfile = PSMAPFILE ; void getdefaults(s) char *s ; { FILE *deffile ; char PSname[300] ; register char *p ; int i, j ; integer hsiz, vsiz ; int canaddtopaper = 0 ; if (printer == NULL) { if (s) { strcpy(PSname, s) ; } else { strcpy(PSname, DVIPSRC) ; } } else { #if defined(MSDOS) || defined(OS2) strcpy(PSname, printer) ; strcat(PSname, ".cfg") ; #else strcpy(PSname, "config.") ; strcat(PSname, printer) ; #endif } if ((deffile=search(configpath,PSname,READ))!=NULL) { while (fgets(was_inline, INLINE_SIZE, deffile)!=NULL) { /* * We need to get rid of the newline. */ for (p=was_inline; *p; p++) ; if (p > was_inline) *(p-1) = 0 ; if (was_inline[0] != '@') canaddtopaper = 0 ; switch (was_inline[0]) { /* * Handling paper size information: * * If line is empty, then we clear out the paper size information * we have so far. * * If it is `@+', then we add to the current paper size info. * * If it is `name hsize vsize', then we start a new definition. */ case '@' : p = was_inline + 1 ; while (*p && *p <= ' ') p++ ; if (*p == 0) { papsizes = 0 ; /* throw away memory */ } else if (*p == '+') { if (canaddtopaper == 0) error( " @+ in config files must immediately following a @ lines") ; else { *(nextstring-1) = '\n' ;/* IBM: VM/CMS - changed 10 to "\n" */ p++ ; while (*p && *p == ' ') p++ ; strcpy(nextstring, p) ; nextstring += strlen(p) + 1 ; } } else { struct papsiz *ps ; ps = (struct papsiz *)mymalloc((integer)sizeof(struct papsiz)) ; ps->next = papsizes ; papsizes = ps ; ps->name = p ; while (*p && *p > ' ') p++ ; *p++ = 0 ; ps->name = newstring(ps->name) ; while (*p && *p <= ' ') p++ ; handlepapersize(p, &hsiz, &vsiz) ; ps->xsize = hsiz ; ps->ysize = vsiz ; ps->specdat = nextstring++ ; canaddtopaper = 1 ; } break ; case 'a' : dopprescan = (was_inline[1] != '0') ; break ; case 'b': #ifdef SHORTINT if (sscanf(was_inline+1, "%ld", &pagecopies) != 1) bad_config() ; #else if (sscanf(was_inline+1, "%d", &pagecopies) != 1) bad_config() ; #endif if (pagecopies < 1 || pagecopies > 1000) bad_config() ; break ; case 'm' : #ifdef SHORTINT if (sscanf(was_inline+1, "%ld", &swmem) != 1) bad_config() ; #else /* ~SHORTINT */ if (sscanf(was_inline+1, "%d", &swmem) != 1) bad_config() ; #endif /* ~SHORTINT */ swmem += fontmem ; /* grab headers we've seen already */ break ; case 'M' : /* If the user specified a -mode, don't replace it. */ if (!mfmode_option) mfmode = configstring(was_inline+1, 0) ; break ; case 'o' : if (!oname_option) { oname = configstring(was_inline+1, 1) ; if (*oname && oname[strlen(oname)-1] == ':') sendcontrolD = 1 ; /* if we send to a device, *we* are spooler */ } break ; case 'O' : p = was_inline + 1 ; handlepapersize(p, &hoff, &voff) ; break ; #ifdef FONTLIB case 'L' : { char tempname[300] ; extern char *fliparse() ; if (sscanf(was_inline+1, "%s", PSname) != 1) bad_config() ; else { flipath = getpath(fliparse(PSname,tempname), flipath); fliname = newstring(tempname) ; } } break ; #endif case 'T' : if (sscanf(was_inline+1, "%s", PSname) != 1) bad_config() ; else SET_CLIENT_PATH (kpse_tfm_format, PSname); break ; case 'P' : if (sscanf(was_inline+1, "%s", PSname) != 1) bad_config() ; else SET_CLIENT_PATH (kpse_pk_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 { psmapfile = configstring(was_inline+1, 0) ; } 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 SET_CLIENT_PATH (kpse_pict_format, PSname); break ; case 's': safetyenclose = 1 ; break ; case 'H' : if (sscanf(was_inline+1, "%s", PSname) != 1) bad_config() ; else SET_CLIENT_PATH (kpse_dvips_header_format, PSname); break ; case '%': case ' ' : case '*' : case '#' : case ';' : case '=' : case 0 : case '\n' : break ; case 'r' : reverse = (was_inline[1] != '0') ; 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] = 0 ; break ; case 'D' : if (sscanf(was_inline+1, "%d", &actualdpi) != 1) bad_config() ; if (actualdpi < 10 || actualdpi > 10000) bad_config() ; vactualdpi = actualdpi; break ; /* * Execute a command. This can be dangerous, but can also be very useful. */ case 'E' : #ifdef SECURE error("dvips was compiled with SECURE, which disables E in config") ; #else if (secure) { error("dvips -R option used, which disables E in config") ; break ; } (void)system(was_inline+1) ; #endif break ; case 'K': removecomments = (was_inline[1] != '0') ; break ; case 'U': nosmallchars = (was_inline[1] != '0') ; break ; case 'W': for (p=was_inline+1; *p && *p <= ' '; p++) ; if (*p) warningmsg = newstring(p) ; else warningmsg = 0 ; break ; case 'X' : if (sscanf(was_inline+1, "%d", &actualdpi) != 1) bad_config() ; if (actualdpi < 10 || actualdpi > 10000) bad_config() ; break ; case 'Y' : if (sscanf(was_inline+1, "%d", &vactualdpi) != 1) bad_config() ; if (vactualdpi < 10 || vactualdpi > 10000) bad_config() ; break ; case 'x': case 'y': if (sscanf(was_inline+1, "%d", &mag) != 1) bad_config() ; overridemag = (was_inline[0] == 'x') ? 1 : -1 ; break ; case 'e' : if (sscanf(was_inline+1, "%d", &maxdrift) != 1) bad_config() ; if (maxdrift < 0) bad_config() ; vmaxdrift = maxdrift; break ; case 'q' : case 'Q' : quiet = (was_inline[1] != '0') ; break ; case 'f' : case 'F' : filter = (was_inline[1] != '0') ; break ; case 'h' : if (sscanf(was_inline+1, "%s", PSname) != 1) bad_config() ; else (void)add_header(PSname) ; break ; case 'i' : if (sscanf(was_inline+1, "%d", &maxsecsize) != 1) maxsecsize = 0 ; sepfiles = 1 ; break ; case 'I': noenv = (was_inline[1] != '0') ; break ; case 'N' : disablecomments = (was_inline[1] != '0') ; break ; case 'Z' : compressed = (was_inline[1] != '0') ; break ; case 't' : if (sscanf(was_inline+1, "%s", PSname) != 1) bad_config() ; else { if (strcmp(PSname, "landscape") == 0) { if (hpapersize || vpapersize) error( "both landscape and papersize specified; ignoring landscape") ; else landscape = 1 ; } else paperfmt = newstring(PSname) ; } break ; default: bad_config() ; } } (void)fclose(deffile) ; } else { if (printer) { char msg[1000]; sprintf (msg, "! no config file for printer `%s'", printer); error(msg); } } } /* * If a character pointer is passed in, use that name; else, use the * default (possibly set) name. */ void getpsinfo(name) char *name ; { FILE *deffile ; register char *p ; char *specinfo, *downloadinfo ; char downbuf[500] ; char specbuf[500] ; if (name == 0) name = psmapfile ; if ((deffile=search(configpath, name, READ))!=NULL) { while (fgets(was_inline, INLINE_SIZE, deffile)!=NULL) { p = was_inline ; if (*p > ' ' && *p != '*' && *p != '#' && *p != ';' && *p != '%') { char *TeXname = NULL ; char *PSname = NULL ; specinfo = NULL ; downloadinfo = NULL ; downbuf[0] = 0 ; specbuf[0] = 0 ; while (*p) { while (*p && *p <= ' ') p++ ; if (*p) { if (*p == '"') { if (specinfo) { strcat(specbuf, specinfo) ; strcat(specbuf, " ") ; } specinfo = p + 1 ; } else if (*p == '<') { if (downloadinfo) { strcat(downbuf, downloadinfo) ; strcat(downbuf, " ") ; } while (p[1] == ' ' || p[1] == '\t') p++; 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 (specinfo) strcat(specbuf, specinfo) ; if (downloadinfo) strcat(downbuf, downloadinfo) ; if (TeXname) { TeXname = newstring(TeXname) ; specinfo = newstring(specbuf) ; PSname = newstring(PSname) ; downloadinfo = newstring(downbuf) ; add_entry(TeXname, PSname, specinfo, downloadinfo) ; } } } (void)fclose(deffile) ; } checkstrings() ; } #if 0 /* Print the path P with label TITLE. */ static void print_path (title, p) string title; string p; { fprintf (stderr, "%s path: \t", title); if (p == NULL) fprintf (stderr, "(null)\n"); else if (p == NULL) fprintf (stderr, "(empty)\n"); else fprintf (stderr, "%s", p); putc ('\n', stderr); } #endif void checkenv(which) int which ; { /* Now irrelevant; kpathsea does all the initializations. */ }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.