/* Copyright 1990,1991,1992,1993,1994,1995,1996,1997,1998,1999 Y&Y, Inc. Copyright 2007 TeX Users Group This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ /********************************************************************** * * Program for decompressing and extracting font files in PFA & PFB format * **********************************************************************/ /* Revised 1999 June 13 to run in DLL form */ #ifdef _WINDOWS #define NOCOMM #define NOSOUND #define NODRIVERS #define STRICT #include #endif #include #include #include #include #include #ifdef _WINDOWS // We must define MYLIBAPI as __declspec(dllexport) before including // dvipsone.h, then dvipsone.h will see that we have already // defined MYLIBAPI and will not (re)define it as __declspec(dllimport) #define MYLIBAPI __declspec(dllexport) // #include "dvipsone.h" #endif #include "dvipsone.h" #ifdef _WINDOWS #pragma warning(disable:4100) // unreferenced formal variable #endif #pragma warning(disable:4127) // conditional expression is constant #pragma hdrstop /* malloc.h not really needed */ #define ZEROS 512 /* 512 zeros required at end of eexec section */ #define ZEROSPERLINE 64 /* 64 zeros per line for safety */ #define NOTDEF 256 /* special code for .notdef = MAXCHRS */ #define COORDINATE "+" /* prefix for reencoded font 97/June/1 */ /* this has apparently not been finsihed */ unsigned short int cryptin; /* current seed for input decryption */ unsigned short int cryptout; /* current seed for output encryption */ char charseen[MAXCHRS + 1]; /* new - which CharStrings unpacked + NOTDEF */ int clm; /* current output column */ int binaryin = 0; /* non-zero => input binary, not hex */ int wantcreation=1; /* copy creation date through to output */ int aliasesexist=0; /* if *alias* found in font substitution file */ int syntheticsexist=0; /* if *synthetic* in font substitution file */ /* normally not set to avoid need to check table */ int type3flag = 0; /* non-zero => font file is PKTOPS output */ /* zero => font file is Adobe Type 1 style */ int mmflag=0; /* non-zero => Multiple Master Font 94/Dec/6 */ int pssflag = 0; /* non-zero => `font' file is PSS stub 94/Dec/6 */ int instanceflag = 0; /* non-zero => MM instanced via PFM 97/June/1 */ int fontform = 0; /* 0 => unrecog, 1 => old form, 2 => new form */ /* used only if breakearly is on - NOT USED */ int standard = 0; /* non-zero => StandardEncoding --- NOT USED */ int texfont = 0; /* non-zero => Tex font --- NOT USED */ int fontchrs = MAXCHRS; /* actual number of characters in font */ int hybridflag; /* 1993/Aug/5 */ /* made global 1994/July/15 */ int bBaseNameDone = 1; /* if zero, need not add BaseFontName anymore */ /* int stripbadend=0; */ /* for now 95/Mar/1 */ // static char filefontname[MAXFONTNAME]=""; /* from file name */ static char filefontname[FNAMELEN]=""; /* from file name */ static char realfontname[FNAMELEN]=""; /* from /FontName */ /* but first guess from %!PS line */ int chrs = -1; /* current character working on */ unsigned long len; /* counter of bytes in binary input */ /* Fonts, that --- in Oblique or Narrow form --- are synthetic: */ char *syntheticfonts[] ={ "Helvetica", "Courier", "AvantGarde", "Univers", "Optima", "Futura", "NewsGothic", "EuroStyle", /* added 97/Oct/23 */ "TektonMM", /* added 99/Apr/12 */ "" }; /* The seventy-five ComputerModern font names - needed for uniqueID ? */ /* unsigned char *cmfonts[] = { "b10", "bsy10", "bx5", "bx6", "bx7", "bx8", "bx9", "bx10", "bx12", "bxsl10", "bxti10", "csc10", "dunh10", "ex10", "ff10", "fi10", "fib8", "inch", "itt10", "mi5", "mi6", "mi7", "mi8", "mi9", "mi10", "mi12", "mib10", "r5", "r6", "r7", "r8", "r9", "r10", "r12", "r17", "sl8", "sl9", "sl10", "sl12", "sltt10", "ss8", "ss9", "ss10", "ss12", "ss17", "ssbx10", "ssdc10", "ssi8", "ssi9", "ssi10", "ssi12", "ssi17", "ssq8", "ssqi8", "sy5", "sy6", "sy7", "sy8", "sy9", "sy10", "tcsc10", "tex8", "tex9", "tex10", "ti7", "ti8", "ti9", "ti10", "ti12", "tt8", "tt9", "tt10", "tt12", "u10", "vtt10" }; */ /* char *basecharacters="aceinousyzACEINOUSYZ"; *//* just basic 58 - Latin 1 */ /* char *basecharacters="aceinousyzACEINOUSYZdlrtDLRT";*/ /* ISO Latin 1 + 2 */ /* char *notbasecharacters="bfmpqvxBFMPQVX"; */ /* ??? */ /* aceinousyz 10 for standard 58 ISO Latin 1 */ /* acdeilnorustyz 14 also includes ISO Latin 2 */ /* acdeghijklnorstuwyz 19 full set */ /* omit bfmpqvx 7 cheaper to compute */ /* #define NUMACCENTS 14 */ /* use them straight out of standardencoding */ /* accents are at 193 to 207 */ /* static char *standardaccents[] = { "grave", "acute", "circumflex", "tilde", "macron", "breve", "dotaccent", "dieresis", "ring", "cedilla", "hungarumlaut", "ogonek", "caron", "dotlessi"}; */ /* well, this one is actually a base character */ /* font substitution table - obtained from file */ /* fontsubprop small enough to keep in near space - rest banished to far */ /* static int fontsubprop[MAXSUBSTITUTE]; *//* resident/forced/remapped/alias */ int fontsubprop[MAXSUBSTITUTE]; /* resident/forced/remapped/alias */ /* 1993/Nov/15 switches from fixed array to pointers into `namestring' */ /* static char charnames[MAXCHRS][MAXCHARNAME]; */ /* names read from encoding */ #define STRINGSPACE (MAXCHRS * MAXCHARNAME / 2) /* The above comes to 4096 bytes - textext = 650, SE = 945, ANSI = 1528 */ char *charnames[MAXCHRS]; /* encoding vector 1993/Nov/15 */ char namestring[STRINGSPACE]; /* for encoding vector 1993/Nov/15 */ int stringindex; /* index into above space */ /* various encoding vectors needed */ /* is the following really needed ? YES, if font file Encoding is standard */ static char *standardencoding[] = { "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "space", "exclam", "quotedbl", "numbersign", "dollar", "percent", "ampersand", "quoteright", "parenleft", "parenright", "asterisk", "plus", "comma", "hyphen", "period", "slash", "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "colon", "semicolon", "less", "equal", "greater", "question", "at", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "bracketleft", "backslash", "bracketright", "asciicircum", "underscore", "quoteleft", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "braceleft", "bar", "braceright", "asciitilde", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "nbspace", "exclamdown", "cent", "sterling", "fraction", "yen", "florin", "section", "currency", "quotesingle", "quotedblleft", "guillemotleft", "guilsinglleft", "guilsinglright", "fi", "fl", "", "endash", "dagger", "daggerdbl", "periodcentered", "", "paragraph", "bullet", "quotesinglbase", "quotedblbase", "quotedblright", "guillemotright", "ellipsis", "perthousand", "", "questiondown", "", "grave", "acute", "circumflex", "tilde", "macron", "breve", "dotaccent", "dieresis", "", "ring", "cedilla", "", "hungarumlaut", "ogonek", "caron", "emdash", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "AE", "", "ordfeminine", "", "", "", "", "Lslash", "Oslash", "OE", "ordmasculine", "", "", "", "", "", "ae", "", "", "", "dotlessi", "", "", "lslash", "oslash", "oe", "germandbls", "", "", "", "", }; /* TeX text encoding vector - is this needed ? Yes, if can't find file */ /* If sharing character names, copy upper part from StandardEncoding */ #ifdef SHAREENCODING static char *textext[TEXCHRS] = { /* TEXCHRS is 128 */ "Gamma", "Delta", "Theta", "Lambda", "Xi", "Pi", "Sigma", "Upsilon", "Phi", "Psi", "Omega", "ff", "fi", "fl", "ffi", "ffl", "dotlessi", "dotlessj", "grave", "acute", "caron", "breve", "macron", "ring", "cedilla", "germandbls", "ae", "oe", "oslash", "AE", "OE", "Oslash", "suppress" }; #else static char *textext[TEXCHRS] = { /* TEXCHRS is 128 */ "Gamma", "Delta", "Theta", "Lambda", "Xi", "Pi", "Sigma", "Upsilon", "Phi", "Psi", "Omega", "ff", "fi", "fl", "ffi", "ffl", "dotlessi", "dotlessj", "grave", "acute", "caron", "breve", "macron", "ring", "cedilla", "germandbls", "ae", "oe", "oslash", "AE", "OE", "Oslash", "suppress", "exclam", "quotedblright", "numbersign", "dollar", "percent", "ampersand", "quoteright", "parenleft", "parenright", "asterisk", "plus", "comma", "hyphen", "period", "slash", "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "colon", "semicolon", "exclamdown", "equal", "questiondown", "question", "at", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "bracketleft", "quotedblleft", "bracketright", "circumflex", "dotaccent", "quoteleft", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "endash", "emdash", "hungarumlaut", "tilde", "dieresis"}; #endif /* "grave", "acute", "circumflex", "tilde", */ /* "macron", "breve", "dotaccent", "dieresis", */ /* "ring", "cedilla", "hungarumlaut", "ogonek", */ /* "caron", "dotlessi", "", "" */ /* If sharing character names, copy lower part from StandardEncoding */ /* NOTE: has non-standard added positions `dotlessi' 157 `caron' 141 */ /* NOTE: if env var ENCODING set then *that* vector is used instead */ /* it is read in and overrides this Windows ANSI encoding */ /* SHAREENCODING means we copy over some pointers to save memory */ /* We might consider reading this one in from disk if needed */ /* Now that we may not be using it if ENCODING env var is set */ #ifdef SHAREENCODING static char *ansiencoding[256] = { "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "quotesinglbase", "florin", "quotedblbase", "ellipsis", "dagger", "daggerdbl", "circumflex", "perthousand", "Scaron", "guilsinglleft", "OE", "caron", "", "", "", "quoteleft", "quoteright", "quotedblleft", "quotedblright", "bullet", "endash", "emdash", "tilde", "trademark", "scaron", "guilsinglright", "oe", "dotlessi", "", "Ydieresis", "nbspace", "exclamdown", "cent", "sterling", "currency", "yen", "brokenbar", "section", "dieresis", "copyright", "ordfeminine", "guillemotleft", "logicalnot", "hyphen", "registered", "macron", "degree", "plusminus", "twosuperior", "threesuperior", "acute", "mu", "paragraph", "periodcentered", "cedilla", "onesuperior", "ordmasculine", "guillemotright", "onequarter", "onehalf", "threequarters", "questiondown", "Agrave", "Aacute", "Acircumflex", "Atilde", "Adieresis", "Aring", "AE", "Ccedilla", "Egrave", "Eacute", "Ecircumflex", "Edieresis", "Igrave", "Iacute", "Icircumflex", "Idieresis", "Eth", "Ntilde", "Ograve", "Oacute", "Ocircumflex", "Otilde", "Odieresis", "multiply", "Oslash", "Ugrave", "Uacute", "Ucircumflex", "Udieresis", "Yacute", "Thorn", "germandbls", "agrave", "aacute", "acircumflex", "atilde", "adieresis", "aring", "ae", "ccedilla", "egrave", "eacute", "ecircumflex", "edieresis", "igrave", "iacute", "icircumflex", "idieresis", "eth", "ntilde", "ograve", "oacute", "ocircumflex", "otilde", "odieresis", "divide", "oslash", "ugrave", "uacute", "ucircumflex", "udieresis", "yacute", "thorn", "ydieresis" }; #else static char *ansiencoding[] = { "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "space", "exclam", "quotedbl", "numbersign", "dollar", "percent", "ampersand", "quotesingle", "parenleft", "parenright", "asterisk", "plus", "comma", "hyphen", "period", "slash", "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "colon", "semicolon", "less", "equal", "greater", "question", "at", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "bracketleft", "backslash", "bracketright", "asciicircum", "underscore", "grave", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "braceleft", "bar", "braceright", "asciitilde", "", "", "", "quotesinglbase", "florin", "quotedblbase", "ellipsis", "dagger", "daggerdbl", "circumflex", "perthousand", "Scaron", "guilsinglleft", "OE", "caron", "", "", "", "quoteleft", "quoteright", "quotedblleft", "quotedblright", "bullet", "endash", "emdash", "tilde", "trademark", "scaron", "guilsinglright", "oe", "dotlessi", "", "Ydieresis", "nbspace", "exclamdown", "cent", "sterling", "currency", "yen", "brokenbar", "section", "dieresis", "copyright", "ordfeminine", "guillemotleft", "logicalnot", "hyphen", "registered", "macron", "degree", "plusminus", "twosuperior", "threesuperior", "acute", "mu", "paragraph", "periodcentered", "cedilla", "onesuperior", "ordmasculine", "guillemotright", "onequarter", "onehalf", "threequarters", "questiondown", "Agrave", "Aacute", "Acircumflex", "Atilde", "Adieresis", "Aring", "AE", "Ccedilla", "Egrave", "Eacute", "Ecircumflex", "Edieresis", "Igrave", "Iacute", "Icircumflex", "Idieresis", "Eth", "Ntilde", "Ograve", "Oacute", "Ocircumflex", "Otilde", "Odieresis", "multiply", "Oslash", "Ugrave", "Uacute", "Ucircumflex", "Udieresis", "Yacute", "Thorn", "germandbls", "agrave", "aacute", "acircumflex", "atilde", "adieresis", "aring", "ae", "ccedilla", "egrave", "eacute", "ecircumflex", "edieresis", "igrave", "iacute", "icircumflex", "idieresis", "eth", "ntilde", "ograve", "oacute", "ocircumflex", "otilde", "odieresis", "divide", "oslash", "ugrave", "uacute", "ucircumflex", "udieresis", "yacute", "thorn", "ydieresis" }; #endif /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */ int mmcount; /* how many MM base fonts added */ /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */ /* Stuff for initializing resident encoding vectors - to save memory */ void initializeencoding(int ansitexflag) { int k; #ifdef SHAREENCODING for (k = 33; k < 123; k++) textext[k] = standardencoding[k]; /* now for the fixups */ /* textext[32] = "suppress"; */ textext[34] = standardencoding[186]; /* "quotedblright" */ textext[60] = standardencoding[161]; /* "exclamdown" */ textext[62] = standardencoding[191]; /* "questiondown" */ textext[92] = standardencoding[170]; /* "quotedblleft" */ textext[94] = standardencoding[195]; /* "circumflex" */ textext[95] = standardencoding[199]; /* "dotaccent" */ textext[123] = standardencoding[177]; /* "endash" */ textext[124] = standardencoding[208]; /* "emdash" */ textext[125] = standardencoding[205]; /* "hungarumlaut" */ textext[126] = standardencoding[196]; /* "tilde" */ textext[127] = standardencoding[200]; /* "dieresis" */ for (k = 32; k < 128; k++) ansiencoding[k] = standardencoding[k]; ansiencoding[39] = standardencoding[169]; /* "quotesingle" */ ansiencoding[96] = standardencoding[193]; /* "grave" */ /* copy over accents for Adobe Level 1 PS interpreter bug as in PSCRIPT */ /* for (k = 0; k < 15; k++) ansiencoding[k] = standardencoding[k+193]; */ /* ansiencoding[15] = standardencoding[245]; *//* dotlessi*/ #endif /* copy over accents for Adobe Level 1 PS interpreter bug as in PSCRIPT */ /* actually, mostly we just need `caron', `dotlessi' and maybe `ring' ... */ if (!ansitexflag) { for (k = 0; k < 15; k++) ansiencoding[k] = standardencoding[k+193]; ansiencoding[15] = standardencoding[245]; /* dotlessi*/ } if (ansitexflag) { /* or do this in PostScript later ??? 93/Dec/18 */ /* this had a bug that was fixed 93/Dec/28 */ /* strcpy(ansiencoding[0], ""); */ /* avoid grave repeat */ /* strcpy(ansiencoding[1], ""); */ /* avoid acute repeat */ /* strcpy(ansiencoding[4], ""); */ /* avoid macron repeat */ /* strcpy(ansiencoding[5], ""); */ /* avoid breve repeat */ /* strcpy(ansiencoding[9], ""); */ /* avoid ring repeat */ /* strcpy(ansiencoding[10], ""); */ /* avoid cedilla repeat */ /* strcpy(ansiencoding[14], ""); */ /* avoid caron repeat */ /* 0 - 10 Greek - not in ANSI */ /* 11 - 15 f ligatures - not in ANSI */ /* 16 - 17 dotlessi dotlessj - not ANSI */ /* 16 - 24 dotlessi, dotlessj, grave, acute, caron, breve, macron, ring, cedilla */ /* 25 - 31 germandbls, ae, oe, oslash, AE, OE, Oslash */ /* actually: dotlessj, caron, breve, - and ring - missing in ANSI */ for (k = 16; k < 32; k++) ansiencoding[k] = textext[k]; ansiencoding[17] = ""; /* flush `dotlessj' */ ansiencoding[21] = ""; /* flush `breve' */ /* but keep `caron' and `ring' for PS interpreter bug fix (not in ANSI) */ /* potential problem with some characters now being repeated higher up ? */ } } /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */ /* stuff for reading in AFM/TFM files and extracting metric information */ /* provides alternate of reading AFM file instead */ /* if file can't be found or read, don't adjust metric information */ /* graceful exit with suitable error message */ void extgiveup(int code) { /* graceful exit with meaningful error message */ char *s=logline; if (*task != '\0') { sprintf(s, " while %s", task); s += strlen(s); } if (chrs >= 0) { sprintf(s, " for character %d ", chrs); s += strlen(s); } if (*filefontname != '\0') { sprintf(s, " in font %s", filefontname); s += strlen(s); } strcat(logline, "\n"); showline(logline, 1); /* exit(code); */ checkexit(code); /* 1995/Oct/28 */ } /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */ unsigned long readlength(FILE* input) { /* read four byte length code */ int c, k; unsigned long n = 0L; for (k=0; k < 4; k++) { c = getc(input); n = n >> 8; n = n | ((unsigned long) c << 24); } return n; } unsigned long maclength(FILE *input) { /* read four byte length code */ int k; unsigned long n = 0L; for (k = 0; k < 4; k++) n = (n << 8) | getc(input); return n; } int getnextnon(FILE *input) { int c; c = getc(input); if (c == '\r' && flushcr != 0) { c = getc(input); if (c != '\n') { (void) ungetc(c, input); c = '\n'; } } return c; } /* read a line up to newline (or return) */ /* returns EOF if at end of file */ int extgetline(FILE *input, char *buff) { /* was char *line */ char *s=buff; int c, k=0; c = getnextnon(input); /* if (flushcr != 0) while (c == '\r') c = getc(input); */ while (c != '\n') { if (c == EOF) return EOF; if (c == 128) { /* flush over ASCII section headers */ binaryin = 1; c = getc(input); if (c == 3) return EOF; if (c != 1) { sprintf(logline, " Expecting %s, not %d", "ASCII section code", c); showline(logline, 1); extgiveup(5); return EOF; } len = readlength(input); /* read and ignore ! */ c = getnextnon(input); if (c == EOF) return EOF; /* never */ if (c == '\n') break; } else if (c == 0) { /* Presumably Mac Style ASCII section code */ sprintf(logline, " AT BYTE %ld ", ftell(input)); /* debugging */ showline(logline, 0); binaryin = 1; (void) ungetc(c, input); len = maclength(input); c = getc(input); if (c == 5) return EOF; if (c != 1) { sprintf(logline, " Expecting %s, not %d", "Mac ASCII section code", c); showline(logline, 1); extgiveup(5); return EOF; } c = getc(input); if (c != 0) { sprintf(logline, " Invalid Mac ASCII section code %d", c); showline(logline, 1); extgiveup(5); return EOF; } len = len -2; c = getnextnon(input); if (c == EOF) return EOF; /* never */ /* if (c == '\r') c = '\n'; */ if (c == '\n') break; } *s++ = (char) c; k++; if (k >= MAXLINE) { showline(" Line too long in dviextra getline", 1); /* extgiveup(6); */ /* flushed */ *(s-1) = '\0'; /* terminate the junk at least */ if (verboseflag) { /* 93/Aug/13 */ showline("\n", 0); showline(buff, 1); showline("\n", 0); } /* read to end of line (or EOF) before going on ? */ while ((c = getnextnon(input)) != '\n') { if (c == EOF) return EOF; } errcount(0); /* 93/Aug/13 */ *buff = '\0'; /* flush this crap ! */ return 0; } c = getnextnon(input); /* flush any returns */ } *s++ = (char) c; k++; /* terminating '\n' */ *s++ = '\0'; return k; } /* hmm, return value of extgetrealline used to be never used ... */ int extgetrealline(FILE *input, char *buff) { /* get non-comment, non-blank */ int k; k = extgetline(input, buff); while ((*buff == '%' || *buff == '\n') && k >= 0) k = extgetline(input, buff); return k; } ////////////////////////////////////////////////////////////////////////////// int ksubst=0; // number of entries in substitution table char *makespace (char *s, int ndes, int nact) { int k; // char *s=logline; // for (k = nact; k < ndes; k++) putc(' ', output); for (k = nact; k < ndes; k++) *s++ = ' '; *s = '\0'; return s; } char *showproper (char *s, int proper) { if (proper == 0) return s; if ((proper & C_RESIDENT) != 0) sprintf(s, "%s ", RESIDENT); if ((proper & C_FORCESUB) != 0) sprintf(s, "%s ", FORCESUB); /* if ((proper & C_REMAPIT) != 0) sprintf(s, "%s ", REMAPIT); */ if ((proper & C_ALIASED) != 0) sprintf(s, "%s ", ALIASED); if ((proper & C_MISSING) != 0) sprintf(s, "*missing* "); if ((proper & C_UNUSED) != 0) sprintf(s, "*unused* "); /* if ((proper & C_DEPENDENT) != 0) sprintf(s, "*new-size* "); */ /* if ((proper & C_COMPOUND) != 0) sprintf(s, "%s ", COMPOUND); */ if ((proper & C_SYNTHETIC) != 0) sprintf(s, "%s ", SYNTHETIC); if ((proper & C_MTMI) != 0) sprintf(s, "%s ", MTMI); if ((proper & C_EPSF) != 0) sprintf(s, "%s ", EPSF); /* 94/Aug/15 */ if ((proper & C_DEPENDENT) != 0) sprintf(s, "*new-size* "); if ((proper & C_REMAPIT) != 0) sprintf(s, "%s ", REMAPIT); /* if ((proper & C_CONTROL) != 0) sprintf(s, "%s ", CONTROL); */ if ((proper & C_NOTBASE) != 0) sprintf(s, "*not-base* "); return s + strlen(s); } void showsubtable(void) { /* an experiment */ int k; char *s; // char oldname[MAXTEXNAME]; char oldname[FNAMELEN]; // char newname[MAXFONTNAME]; char newname[FNAMELEN]; // char vecname[MAXVECNAME]; /* 1994/Feb/4 */ char vecname[FNAMELEN]; showline("Font Substitution Table:\n", 0); for (k = 0; k < ksubst; k++) { // strcpy(oldname, fontsubfrom + k * MAXTEXNAME); if (fontsubfrom[k] != NULL) strcpy(oldname, fontsubfrom[k]); else *oldname = '\0'; // strcpy(newname, fontsubto + k * MAXFONTNAME); if (fontsubto[k] != NULL) strcpy(newname, fontsubto[k]); else *newname = '\0'; // strcpy(vecname, fontsubvec + k * MAXVECNAME); if (fontsubvec[k] != NULL) strcpy(vecname, fontsubvec[k]); else *vecname = '\0'; s = logline; sprintf(s, "%3d %s ", k, oldname); s += strlen(s); s = makespace(s, 10, strlen(oldname)); /* MAXTEXNAME ? */ sprintf(s, "=> %s ", newname); s += strlen(s); s = makespace(s, 16, strlen(newname)); /* MAXFONTNAME ? */ s = showproper(s, fontsubprop[k]); /* if (strcmp(fontsubvec[k], "") != 0) fprintf(output, "vec: %s", fontsubvec[k]); */ if (strcmp(vecname, "") != 0) { sprintf(s, "vec: %s", vecname); s += strlen(s); } // putc('\n', output); strcat(s, "\n"); showline(logline, 0); } // putc('\n', output); showline("\n", 0); } int original (int k) { /* recover TeX internal font number */ int m; for (m = 0; m < MAXFONTNUMBERS; m++) { if (finx[m] == (short) k) return m; // if (finx[m] == k) return m; } return -1; } void showfonttable (void) { /* an experiment */ int k, flag, originalfont; double atsize; int proper; // char oldname[MAXTEXNAME]; char oldname[FNAMELEN]; // char newname[MAXFONTNAME]; char newname[FNAMELEN]; char *s=logline; // fprintf(output, "Font Table:"); strcpy(s, "Font Table:"); s += strlen(s); if (mag != 1000) sprintf(s, " (Magnification %lg)", (double) mag / 1000); strcat(s, "\n"); showline(logline, 0); /* if (traceflag) printf("mmbase %d fnext %d\n", mmbase, fnext); */ for (k = 0; k < fnext; k++) { s = logline; proper = fontproper[k]; /* do only if fontsubflag >= 0 ? */ /* do only if (proper & C_DEPENDENT) != 0 ? */ /* don't bother to list if unused */ /* if (proper & C_UNUSED) != 0) continue; *//* remove 94/Oct/6 */ sprintf(s, "%3d ", k); s += strlen(s); originalfont = original(k); /* original TeX font number */ if (originalfont >= 0) sprintf(s, "(%3d) ", originalfont); else s = makespace(s, 6, 0); // strcpy(oldname, fontname + k * MAXTEXNAME); if (fontname[k] != NULL) strcpy(oldname, fontname[k]); else *oldname = '\0'; if (subfontname[k] != NULL) strcpy(newname, subfontname[k]); else *newname = '\0'; // strcpy(newname, subfontname + k * MAXFONTNAME); sprintf(s, "%s ", oldname); s += strlen(s); s = makespace(s, 10, strlen(oldname)); if (strcmp(newname, "") != 0 && strcmp(oldname, newname) != 0) { sprintf(s, "=> %s ", newname); s += strlen(s); s = makespace(s, 16, strlen(newname)); } atsize = (double) fs[k] * num / den * 72.27 / 254000; /* possibly also * mag / 1000 ? NO */ /* if (atsize != 0.0) fprintf(output, "at:%6.6lg pt ", atsize); */ if (atsize != 0.0) sprintf(s, "at:%6.5lg pt ", atsize); /* else if (originalfont < 0) fprintf(output, "base for remapped font "); */ /* else if (k >= mmbase) fprintf(output, "MM base font "); */ else if (proper & C_MULTIPLE) sprintf(s, "MM base font "); else if (proper & C_INSTANCE) sprintf(s, "MM instance "); else if (originalfont < 0) sprintf(s, "base for substitution "); /* or Multiple Master base font 94/Dec/6 */ else s = makespace(s, 13, 0); s +=strlen(s); flag = fontsubflag[k]; if (flag >= 0) { /* follow substitution pointer */ sprintf(s, "base: %2d ", flag); s +=strlen(s); originalfont = original(flag); if (originalfont >= 0) sprintf(s, "(%3d) ", originalfont); else s = makespace(s, 6, 0); s +=strlen(s); } s = showproper(s, proper); /* show properties */ /* printf("|"); */ // if (strcmp(fontvector[k], "") != 0) // if (*(fontvector + k * MAXVECNAME) != '\0') { if (fontvector[k] != NULL) { /* fprintf(output, "vec: %s", fontvector[k]); */ /* fprintf(output, "%s", fontvector[k]); */ // fputs(fontvector[k], output); /* 1992/July/18 */ strcat(s, fontvector[k]); s +=strlen(s); } // putc('\n', output); strcat(s, "\n"); showline(logline, 0); } showline("\n", 0); } /* void showencoding (FILE *output) { int i; for (i = 0; i < fontchrs; i++) fprintf(output, "%d: %s\n", i, charnames[i]); } */ /* debugging only */ /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */ /* moved to dvipslog.c to avoid compiler bug ! 1995/May/25 */ /* int readtfm(char *, FILE *, long widths[]); */ /* int readafm(char *, FILE *, long widths[]); */ /* int readpfm(char *, FILE *, long widths[]); */ /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */ /* New common routine 1992/Nov/28 */ /* does not use backslash if beginning is blank or already ends on : \ or / */ void makefilename (char filepath[], char *fontname) { char *s; if (strcmp(filepath, "") != 0) { /* 1992/Oct/30 */ s = filepath + strlen(filepath) - 1; if (*s != ':' && *s != '\\' && *s != '/') strcat(filepath, "\\"); } strcat(filepath, fontname); /* extension(filepath, ext); */ } /* returns -1 if name was changed - returns 0 if name was not changed */ int underscore (char *filename) { /* convert font file name to Adobe style */ int k, n, m; char *s, *t; s = removepath(filename); n = (int) strlen(s); if ((t = strchr(s, '.')) == NULL) t = s + strlen(s); m = t - s; if (m == 8) { /* printf("NO CHANGE IN %s\n", filename); */ /* debugging */ return 0; /* no change 95/May/28 */ } memmove(s + 8, t, (unsigned int) (n - m + 1)); for (k = m; k < 8; k++) s[k] = '_'; return -1; } /* removes underscores at end, assumes there is no file extension ... */ /* returns 0 if there were no underscores to remove - returns -1 otherwise */ int removeunder (char *filename) { /* remove Adobe style underscores */ char *s; s = filename + strlen(filename) - 1; if (*s != '_') return 0; /* 95/May/28 */ while (*s == '_') s--; *(s + 1) = '\0'; /* overwrite first underscore in seq */ return -1; } /* Consolidated code for TFM, AFM, and PFM in one place 95/Mar/31 */ FILE *lookformetrics (char *font, char *extension, char *path) { char fn_met[FNAMELEN]; FILE *fp_met=NULL; #ifndef SUBDIRSEARCH char *searchpath; #endif if (traceflag) { sprintf(logline, " Trying %s", path); /* debug 95/Mar/31 */ showline(logline, 0); } #ifdef SUBDIRSEARCH strcpy(fn_met, font); forceexten(fn_met, extension); fp_met = findandopen(fn_met, path, NULL, "rb", currentfirst); if (fp_met == NULL && tryunderscore != 0) { /* underscore (fn_met); */ /* fp_met = findandopen(fn_met, path, NULL, "rb", currentfirst); */ if (underscore(fn_met)) /* 95/May/28 */ fp_met = findandopen(fn_met, path, NULL, "rb", currentfirst); } #else searchpath = path; for (;;) { if ((searchpath=nextpathname(fn_met, searchpath)) == NULL) break; makefilename(fn_met, font); /* 1992/Nov/28 */ forceexten(fn_met, extension); if ((fp_met = fopen(fn_met, "rb")) == NULL) { if (tryunderscore == 0) continue; else { /* underscore(fn_met); if ((fp_met = fopen(fn_met, "rb")) == NULL) continue; else break; */ /* 1994/Aug/18 */ if (underscore(fn_met)) { /* 1995/May/28 */ if ((fp_met = fopen(fn_met, "rb")) != NULL) break; } continue; } } else break; /* 1994/Aug/18 */ } #endif if (traceflag) { /* 1995/Mar/31 */ if(fp_met != NULL) { sprintf(logline, " Using %s", fn_met); showline(logline, 0); } } return fp_met; } /* get character widths from .tfm or .afm or .pfm files - for substitution */ /* tfm is searched first because it is compact - hence fast */ /* pfm is searched last because widths are restricted to being integers */ /* returns max numeric code of character in metric info */ int readwidths (char *font, long widths[]) { FILE *fp_met=NULL; /* char fn_met[FNAMELEN]; */ int k; #ifndef SUBDIRSEARCH /* char *searchpath; */ #endif task = "looking for font metrics"; if (tfmpath != NULL) { fp_met = lookformetrics(font, "tfm", tfmpath); if (fp_met != NULL) { k = readtfm(font, fp_met, widths); fclose(fp_met); return k; } } if (texfonts != NULL) { fp_met = lookformetrics(font, "tfm", texfonts); if (fp_met != NULL) { k = readtfm(font, fp_met, widths); fclose(fp_met); return k; } } if (afmpath != NULL) { fp_met = lookformetrics(font, "afm", afmpath); if (fp_met != NULL) { k = readafm(font, fp_met, widths); fclose(fp_met); return k; } } if (pfmpath != NULL) { fp_met = lookformetrics(font, "pfm", pfmpath); if (fp_met != NULL) { k = readpfm(font, fp_met, widths); fclose(fp_met); return k; } } sprintf(logline, " WARNING: metrics not found for %s", font); showline(logline, 1); errcount(0); return 0; } /* for remapping and substituting font names */ /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */ /* stuff for dealing with font file itself */ int nextbytein(FILE *input) { /* get next byte from input */ int c, d; if (binaryin != 0) { if (len == 0) { c = getc(input); if (c != 0 && c != 128) { sprintf(logline, " Expecting %s, not %d", "binary length code", c); showline(logline, 1); extgiveup(3); return -1; } if (c == 128) { /* PC .pfb file */ c = getc(input); if (c == 1) { /* somewhat unexpected, but... */ len = readlength(input); binaryin = 0; return nextbytein(input); /* try reading in ASCII */ } else if (c != 2) { sprintf(logline, " Expecting %s, not %d", "binary section code", c); showline(logline, 1); extgiveup(5); return -1; } len = readlength(input); /* if (traceflag) printf("Binary Section %lu\n", len); */ } else { /* Mac style binary file c == 0 */ (void) ungetc(c, input); len = maclength(input); c = getc(input); if (c == 1) { /* somewhat unexpected, but... */ binaryin = 0; return nextbytein(input); /* try reading in ASCII */ } else if (c != 2) { sprintf(logline, " Expecting %s, not %d", "Mac binary section code", c); showline(logline, 1); extgiveup(5); return -1; } c = getc(input); if (c != 0) { sprintf(logline, " Invalid Mac style binary record %d", c); showline(logline, 1); extgiveup(15); return -1; } len = len - 2; } } /* c = getc(input); */ if ((c = getc(input)) == EOF) { sprintf(logline, " Unexpected EOF (%s)\n", "nextbytein"); showline(logline, 1); extgiveup(7); return -1; } len--; return c; } else { /* ASCII input */ c = getc(input); while (c <= ' ' && c != EOF) c = getc(input); if (c == EOF) { sprintf(logline, " Unexpected EOF (%s)\n", "nextbytein"); showline(logline, 1); extgiveup(7); return -1; } if (c >= '0' && c <= '9') c = c - '0'; /* use table ? */ else if (c >= 'A' && c <= 'F') c = c - 'A' + 10; else if (c >= 'a' && c <= 'f') c = c - 'a' + 10; else { sprintf(logline, " Invalid hex character: %d", c); showline(logline, 1); extgiveup(7); return -1; } d = getc(input); while (d <= ' ' && d != EOF) d = getc(input); if (d == EOF) { sprintf(logline, " Unexpected EOF (%s)\n", "nextbytein"); showline(logline, 1); extgiveup(7); return -1; } if (d >= '0' && d <= '9') d = d - '0'; /* use table ? */ else if (d >= 'A' && d <= 'F') d = d - 'A' + 10; else if (d >= 'a' && d <= 'f') d = d - 'a' + 10; else { sprintf(logline, " Invalid hex character: %d", d); showline(logline, 1); extgiveup(7); return -1; } return (c << 4) | d; } } /* stuff for encrypting and decrypting */ unsigned char decryptbyte (unsigned char cipher, unsigned short *crypter) { unsigned char plain; /* plain = (cipher ^ (unsigned char) (*crypter >> 8)); */ plain = (unsigned char) ((cipher ^ (unsigned char) (*crypter >> 8))); /* *crypter = (cipher + *crypter) * CRYPT_MUL + CRYPT_ADD; */ *crypter = (unsigned short) ((cipher + *crypter) * CRYPT_MUL + CRYPT_ADD); return plain; } /* unsigned char encryptbyte (unsigned char plain, unsigned short *crypter) { unsigned char cipher; cipher = (plain ^ (unsigned char) (*crypter >> 8)); *crypter = (cipher + *crypter) * CRYPT_MUL + CRYPT_ADD; return cipher; } */ unsigned char indecrypt(FILE *input) { /* read byte and decrypt */ unsigned char cipher; unsigned char plain; cipher = (unsigned char) nextbytein(input); /* plain = (cipher ^ (unsigned char) (cryptin >> 8)); */ plain = (unsigned char) ((cipher ^ (unsigned char) (cryptin >> 8))); /* cryptin = (cipher + cryptin) * CRYPT_MUL + CRYPT_ADD; */ cryptin = (unsigned short) ((cipher + cryptin) * CRYPT_MUL + CRYPT_ADD); return plain; } // rewritten for efficiency to not use putc but fputs // now accumulates a line of output in logline // assumes we are not using logline for something else... /* stuff for encrypted input and output */ void outencrypt(unsigned char plain, FILE *output) { /* encrypt and write */ int c, d; unsigned char cipher; char *s=logline+clm; /* cipher = (plain ^ (unsigned char) (cryptout >> 8)); */ cipher = (unsigned char) ((plain ^ (unsigned char) (cryptout >> 8))); /* cryptout = (cipher + cryptout) * CRYPT_MUL + CRYPT_ADD; */ cryptout = (unsigned short) ((cipher + cryptout) * CRYPT_MUL + CRYPT_ADD); d = cipher & 15; c = (cipher >> 4) & 15; if (c < 10) { // putc(c + '0', output); // PSputc((char) (c+'0'), output); *s++ = (char) (c+'0'); } else { // putc(c + 'A' - 10, output); // PSputc((char) (c+'A'-10), output); *s++ = (char) (c+'A'-10); } clm++; if (d < 10) { // putc(d + '0', output); // PSputc((char) (d+'0'), output); *s++ = (char) (d+'0'); } else { // putc(d+ 'A' - 10, output); // PSputc((char) (d+'A'-10), output); *s++ = (char) (d+'A'-10); } clm++; if (clm >= columns) { // putc('\n', output); // PSputc('\n', output); *s++ = '\n'; *s++ = '\0'; PSputs(logline, output); clm = 0; } } void flushencrypt (FILE *output) { char *s=logline+clm; if (clm > 0) { *s++ = '\n'; *s++ = '\0'; PSputs(logline, output); clm = 0; } } /* 93/Sep/14 --- avoid using getenline for this in case ^M or ^J */ int getmagic(FILE *input, char *buff) { /* get the magic encrypt start bytes */ char *s=buff; int k=0; for (k = 0; k < 4; k++) *s++ = (char) indecrypt(input); *s++ = '\0'; return 4; } /* There shouldn't be any returns inside the encrypted part, just newlines */ /* But some stupid fonts disobey this rule => turn return into newline */ /* One problem: can't conveniently look ahead in encrypted part */ /* This gets nasty if there are returns FOLLOWED newlines */ /* so be prepared to see an isolated return or newline at start of line */ int getenline(FILE *input, char *buff) { /* read encrypted line */ char *s=buff; /* int c; */ int d, k=0; d = indecrypt(input); /* if (d == '\r') d = indecrypt(input); */ /* bkph - 91/10/1 */ /* step over initial return/newline - remanants or blank lines */ while (d == '\n' || d == '\r') d = indecrypt(input); while (d != '\n') { *s++ = (char) d; k++; if (k >= MAXLINE) { *s = '\0'; showline(" Line: ", 1); showline(buff, 1); showline("\n", 0); sprintf(logline, " too long in encrypted getline (> %d)", MAXLINE); showline(logline, 0); extgiveup(6); return -1; } d = indecrypt(input); if (d == '\r') { /* *s = '\0'; printf("RETURN AFTER: %s\n", buff); */ /* d = indecrypt(input); */ /* bkph 91/10/1 */ d = '\n'; } } *s++ = (char) d; k++; *s++ = '\0'; /* if (traceflag) printf("IN: %s", buff); */ return k; } // need to remember to flush out logline at end also ... /* This version assumes string is null terminated */ void putenline(FILE *output, char *buff) { /* write encrypted line */ int d; while ((d = *buff++) != '\0') { outencrypt((unsigned char) d, output); } } /* This version specifies length rather than null terminated */ void putenlinen(FILE *output, char *buff, int n) { /* write encrypted line */ int d, k; for (k = 0; k < n; k++) { d = *buff++; outencrypt((unsigned char) d, output); } } /* used for reading "/charname n RD" for CharStrings */ /* also used for reading "dup n m RD" for Subrs */ /* normally returns zero, when hit end returns -1 */ /* May want to distinguish Subrs and CharStrings case */ /* because Subrs can end on "readonly def" */ /* but that can occur in CharStrings ... */ /* subrflag != 0 for Subrs reading added 93/Aug/13 */ /* get encrypted tokens */ /* reads until it hits RD, -|, end, ND, |-, noaccess def, readonly def */ /* which may mean it reads past end of line ... */ int getcharline(char *buff, FILE *input, int subrflag) { int d; char *t = buff, *s = buff; d = indecrypt(input); /* skip over initial white space */ /* while (d == '\n' || d == '\r' || d == ' ') */ while (d == '\n' || d == '\r' || d == ' ' || d == '\0') /* 98/Apr/20 */ d = indecrypt(input); for(;;) { /* d = indecrypt(input); */ /* if (d == '\n') { if (verboseflag) printf("Unexpected end of line\n"); continue; } */ *s++ = (char) d; if (d <= ' ') { if(strncmp(t, "RD", 2) == 0 || strncmp(t, "-|", 2) == 0) { /* ready for binary bytes */ *s = '\0'; return 0; /* start of binary section */ } else if ((strncmp(t, "end", 3) == 0) || /* end of CharStrings */ (strncmp(buff, "ND", 2) == 0) || /* or end of Subrs */ (strncmp(buff, "|-", 2) == 0)) { /* or end of Subrs */ *s = '\0'; return -1; /* end of Subrs or CharStrings */ } /* 93 Aug 5 */ /* for Subrs only */ else if (subrflag != 0 && (strncmp(buff, "noaccess def", 12) == 0 || /* 93 Aug 13 */ /* for Subrs only */ strncmp(buff, "readonly def", 12) == 0)) { *s = '\0'; return -1; /* end of Subrs or CharStrings */ } else t = s; /* remember start of next token */ } /* else if (d == '\n') { if (verboseflag) printf("Unexpected end of line: %s\n", t); *s = '\0'; return 1; } */ d = indecrypt(input); } } void flushcharstring(FILE *input, int n) { /* flush rest of CharString */ int k, d; for (k = 0; k < n; k++) (void) indecrypt(input); /* flush binary part */ d = indecrypt(input); while (d != '\n') { d = indecrypt(input); /* flush ND or |- up to nl (or rt)*/ if (d == '\r') d = '\n'; /* bkph 91/10/1 */ } } /* copy CharString or Subr string */ /* the fix may be slightly dicey since it may generate blank line at */ void copycharstring(FILE *output, FILE *input, int n) { int d, k; /* c, e */ for (k = 0; k < n; k++) { /* copy binary CharString itself */ d = indecrypt(input); outencrypt((unsigned char) d, output); } d = indecrypt(input); /* default is to drop space before ND */ /* if (d != ' ') */ if (d != ' ' || keepgap != 0) /* 1993 August 5 */ outencrypt((unsigned char) d, output); while (d != '\n') { /* copy ND or | - up to nl (or rt)*/ d = indecrypt(input); if (d == '\r') d = '\n'; /* bkph 91/10/1 */ outencrypt((unsigned char) d, output); } } /* do we want char with this name ? */ /* return negative if not - and character code if yes */ /* changed */ /* Modified for now to keep on looking */ /* allow for multiple encoding ? */ /* this will slow things down a bit, but be a lot safer ! */ /* make sure charnames[] is cleaned out before encoding is read from font */ /* int wantthisname(char *charname, int k, char wantchrs[]) { */ int wantthisname (char *charname, int k, char *wantchrs) { int i; /* best guess first for speed: */ /* if (strcmp(charnames[k], charname) == 0) { */ /* 95/Oct/28 */ if (k >= 0 && k < MAXCHRS && strcmp(charnames[k], charname) == 0) { if (wantchrs[k] != 0) return k; /* nice and easy ! */ /* else return -1; */ /* no, may occur again ... */ } /* was return wantchrs[k]; */ for (i = 0; i < fontchrs; i++) { if (strcmp(charnames[i], charname) == 0) { if (wantchrs[i] != 0) return i; /* else return -1; */ /* no, may occur again ... */ } /* was return wantchrs[i]; */ } if (wantnotdef != 0 && strcmp(".notdef", charname) == 0) { return NOTDEF; } /* if (traceflag) printf("Character not in encoding: %s (%d)\n", charname, k); */ return -1; } /* Adobe PS interpreters yield `invalidfont' errors when */ /* base or accent of composite character is not in encoding of font */ /* May need to add more characters to basecharacterlist */ /* use `N' command line argument to deactivate this bug work around */ int copysubrs(FILE *output, FILE *input) { int subrnum, nbin; /* char buffer[FNAMELEN]; / /* compromise only for hires Subrs line */ char *s; /* First check whether there are no Subrs ! */ if (strstr(line, "ND") != NULL) return 0; if (strstr(line, "|-") != NULL) return 0; if (strstr(line, "noaccess def") != NULL) return 0; if (strstr(line, "readonly def") != NULL) return 0; while (getcharline(line, input, 1) == 0) { if (sscanf(line, "dup %d %d RD", &subrnum, &nbin) < 2) { /* if (strstr(line, "hires") == NULL) { */ if (hybridflag == 0) { /* the old result follows ... */ sprintf(logline, " Not a Subrs line: %s", line); showline(logline, 1); extgiveup(9); return -1; } else { /* new 1994/July/15 for hybrid font */ /* Note: this `line' (getcharline) contains multiple lines up to dup ... RD */ if ((s = strstr(line, "dup ")) != NULL) { if (sscanf(s, "dup %d %d RD", &subrnum, &nbin) == 2) { /* strncpy(buffer, s, FNAMELEN); *//* save dup ... RD */ *s = '\0'; putenline(output, line); /* strcpy(line, buffer); */ *s = 'd'; strcpy(line, s); } } } } putenline(output, line); /* beginning of subr */ copycharstring(output, input, nbin); } s = line + strlen(line) -1; /* to solve problem with \r\n */ if (*s == '\r') *s = '\n'; /* extra blank line maybe */ putenline(output, line); /* hit the end */ // flushencrypt(output); /* flush out last bit */ return 0; } /* Tries to find encoding vector first in dvi file directory */ /* - then tries default encoding vector directory */ FILE *openvector(char *vector) { FILE *fp_vec; char fn_vec[FNAMELEN]; char *s, *t; /* if vector contains a path, use it directly - no other trials */ if (strpbrk(vector, "\\:/") != NULL) { strncpy(fn_vec, vector, FNAMELEN); extension(fn_vec, "vec"); /* return fopen(fn_vec, "r"); */ fp_vec = fopen(fn_vec, "r"); if (fp_vec != NULL) { if (traceflag) { sprintf(logline, "Using encoding vector %s\n", fn_vec); showline(logline, 0); } return fp_vec; } return NULL; } /* try first in dvi file directory */ if (dvipath != NULL) strcpy(fn_vec, dvipath); else strcpy(fn_vec, ""); makefilename(fn_vec, vector); extension(fn_vec, "vec"); if ((fp_vec = fopen(fn_vec, "r")) != NULL) { if (traceflag) { sprintf(logline, "Using encoding vector %s\n", fn_vec); showline(logline, 0); } return fp_vec; } /* try VECPATH directories */ /* modified for multiple directories 97/Aug/10 */ s = vecpath; for(;;) { if (*s == '\0') break; /* safety valve */ /* strcpy(fn_vec, vecpath); */ strcpy(fn_vec, s); t = strchr(fn_vec, ';'); if (t != NULL) *t = '\0'; /* isolate one directory path */ makefilename(fn_vec, vector); extension(fn_vec, "vec"); if ((fp_vec = fopen(fn_vec, "r")) != NULL) { if (traceflag) { sprintf(logline, "Using encoding vector %s\n", fn_vec); showline(logline, 0); } return fp_vec; } if (t != NULL) s +=(t-fn_vec) + 1; /* step over dir and ; */ else break; } /* then try in SUBDIRECTORY of default directory */ /* 1992/Nov/28 */ strcpy(fn_vec, vecpath); /* strcat(fn_vec, "\\"); strcat(fn_vec, "vec\\"); */ makefilename(fn_vec, "vec\\"); /* subdirectory "vec" */ strcat(fn_vec, vector); extension(fn_vec, "vec"); if ((fp_vec = fopen(fn_vec, "r")) != NULL) { if (traceflag) { sprintf(logline, "Using encoding vector %s\n", fn_vec); showline(logline, 0); } return fp_vec; } /* try in current directory */ /* 1992/Dec/8 */ *fn_vec = '\0'; /* strcpy(fn_vec, ""); */ makefilename(fn_vec, vector); /* */ extension(fn_vec, "vec"); if ((fp_vec = fopen(fn_vec, "r")) != NULL) { if (traceflag) { sprintf(logline, "Using encoding vector %s\n", fn_vec); showline(logline, 0); } return fp_vec; } return NULL; } void cleanencoding (int start, int end) { /* Clear out charnames */ int k; /* strcpy(namestring, ""); */ namestring[0] = '\0'; /* empty string */ stringindex = 1; /* reset index to next space */ for (k = start; k < end; k++) charnames[k] = namestring; /* "" */ } void copyencoding(char *charnames[], char *encoding[], int n) { int k; if (n < 0 || n > 256) { sprintf(logline, " ERROR in copyencoding %d\n", n); showline(logline, 1); return; } for (k = 0; k < n; k++) charnames[k] = encoding[k]; /* if (n < MAXCHRS) for (k = n; k < MAXCHRS; k++) charnames[k] = ""; */ } /* we have duplication here if repeated encoding in vector */ void addencoding (int k, char *charname) { /* 93/Nov/15 */ int n = strlen(charname) + 1; /* space needed */ if (stringindex + n >= STRINGSPACE) { showline(" ERROR: encoding vector too long\n", 1); } else { charnames[k] = namestring + stringindex; /* ptr */ strcpy (namestring + stringindex, charname); /* copy */ stringindex += n; /* step over */ } } /* now return 0 if successful, non-zero if failed */ int readencoding (char *vector) { char charname[FNAMELEN]; /* just to be safe */ FILE *fp_vec; int n; /* not accessed */ int k; /* for (k = 0; k < MAXCHRS; k++) strcpy(charnames[k], ""); */ cleanencoding(0, MAXCHRS); /* 93/Nov/15 */ // if (strcmp(vector, "") == 0) /* rewritten 93/May/19 */ if (vector == NULL) { // showline(" ", 0); showline(" WARNING: No encoding vector specified\n", 1); /* Use `textext' as default if no encoding vector specified */ vector = "textext"; /* for (k = 0; k < TEXCHRS; k++) strcpy(charnames[k], textext[k]); */ copyencoding(charnames, textext, TEXCHRS); /* 93/Nov/15 */ errcount(0); return -1; /* failed */ } if ((fp_vec = openvector(vector)) != NULL) { n = 0; /* count encoding lines ? */ while (getrealline(fp_vec, line) > 0) { if (*line == '%' || *line == ';') continue; /* if (sscanf(line, "%d %s", &k, &charname) < 2) { */ if (sscanf(line, "%d %s", &k, charname) < 2) { showline(" Don't understand encoding line: ", 1); showline(logline, 1); showline(line, 1); } else if (k >= 0 && k < MAXCHRS) { /* assert(strlen(charname) < MAXCHARNAME); */ /* if (strlen(charname) >= MAXCHARNAME) fprintf(errout, " char name %s too long", charname); */ addencoding(k, charname); /* strcpy(charnames[k], charname); */ /* strncpy(charnames[k], charname, MAXCHARNAME); */ } n++; } fclose(fp_vec); } else { /* use `textext' as default if encoding vector not found */ /* for (k = 0; k < TEXCHRS; k++) strcpy(charnames[k], textext[k]); */ copyencoding(charnames, textext, TEXCHRS); /* 93/Nov/15 */ // showline(" ", 0); // ??? sprintf(logline, " WARNING: can't find encoding vector %s ", vector); showline(logline, 1); /* perrormod(fn_vec); */ perrormod(vector); errcount(0); return -1; /* failed */ } return 0; /* succeeded */ } void writevector (FILE *fp_out, char *vector, int n) { int k, knext=0; /* n is MAXCHRS */ int kn; /* char *s, *svector; */ if (vector == NULL) { sprintf(logline, " ERROR in writevector %d\n", n); showline(logline, 1); return; } if (n < 0 || n > 256) { sprintf(logline, " ERROR in writevector %d\n", n); showline(logline, 1); return; } if (strcmp(vector, "textext") == 0) { /* 1992/Nov/19 */ if (textextwritten++ > 0) return; } /* if (strcmp(vector, "ansinew") == 0) { if (ansiwritten++ > 0) return; } */ /* 1993/Sep/30 */ if (strcmp(vector, textencoding) == 0) { /* 1994/Dec/17 */ if (ansiwritten++ > 0) return; } knext = 256; /* 93/Feb/15 */ if (bSuppressPartial == 0 && bForceFullArr == 0) { /* 93/Feb/15 */ for (k = n-1; k >= 0; k--) { /* find last character code used */ if(strcmp(charnames[k], "") != 0) { knext = k+1; break; } } } if (knext == 0) return; /* all empty, nothing to do */ if (stripcomment == 0) { sprintf(logline, "%% %s encoding\n", vector); /* 1992/Nov/17 */ PSputs(logline, fp_out); } /* fprintf(fp_out, "/%s[", vector); */ /* 95/Feb/3 */ sprintf(logline, "/%s[", removepath(vector)); /* strip path */ PSputs(logline, fp_out); for (k = 0; k < knext; k++) { if (k != 0 && k % 8 == 0) { // putc('\n', fp_out); PSputc('\n', fp_out); } if (strcmp(charnames[k], "") != 0) { sprintf(logline, "/%s", charnames[k]); PSputs(logline, fp_out); } /* else fprintf(fp_out, "/.notdef"); */ /* else fprintf(fp_out, " n"); */ /* 1993/Sep/31 */ else { /* 1993/Oct/5 */ kn = k+1; while (kn < knext && strcmp(charnames[kn], "") == 0) kn++; /* if (kn < k + 4) { */ if (kn < k + 5) { /* only more efficient if more than 4 */ for (k=k; k < kn; k++) { PSputs(" n", fp_out); } } else { sprintf(logline, " %d notdef", kn-k); PSputs(logline, fp_out); } /* if (((kn-1 >> 3) != (k >> 3)) && kn % 8 != 0) */ if ((((kn-1) >> 3) != (k >> 3)) && (kn % 8) != 0) { // putc('\n', fp_out); PSputc('\n', fp_out); } k = kn-1; } } // fprintf(fp_out, "]def\n"); PSputs("]def\n", fp_out); } void writedvistart (FILE *fp_out) { // fputs("dvidict begin\n", fp_out); PSputs("dvidict begin\n", fp_out); } void writedviend(FILE *fp_out) { /* 1992/Nov/17 */ // fputs("end", fp_out); PSputs("end", fp_out); if (stripcomment == 0) { // fputs(" % dvidict", fp_out); PSputs(" % dvidict", fp_out); } // putc('\n', fp_out); PSputc('\n', fp_out); } /* Following used to be in preamble: */ /* /dviencoding 256 array def */ /* /dvicodemake{string cvs dup 0 97 put cvn dviencoding 3 1 roll put}bd */ /* 0 1 9{dup 10 add 2 dvicodemake} for */ /* 10 1 99{dup 100 add 3 dvicodemake} for */ /* 100 1 255{dup 1000 add 4 dvicodemake} for */ void writedviencode(FILE *fp_out) { /* 1993/Sep/30 */ int k; char charname[5]; /* space for a255 + zero */ writedvistart(fp_out); cleanencoding(0, MAXCHRS); /* reset string table */ for (k = 0; k < MAXCHRS; k++) { /* fixed 1994/Feb/3 */ sprintf(charname, "a%d", k); addencoding (k, charname); /* charnames[k] = namestring + stringindex; */ /* stringindex = stringindex + strlen (namestring + stringindex) + 1; */ } writevector(fp_out, "dviencode", MAXCHRS); writedviend(fp_out); /* 1993/Sep/30 */ } void writetextext(FILE *fp_out) { /* int k; */ /* not allowed to use `TeX text' encoding if forcing full 256 vector */ /* (no longer a problem, since we extend TeX text vector if needed */ /* if (bForceFullArr == 0) { */ /* 93/Feb/15 */ writedvistart(fp_out); /* for (k = 0; k < TEXCHRS; k++) strcpy(charnames[k], textext[k]); */ copyencoding(charnames, textext, TEXCHRS); /* 93/Nov/15 */ if (bForceFullArr == 0) writevector(fp_out, "textext", TEXCHRS); else { /* 1993/Sep/30 */ /* for (k = TEXCHRS; k < MAXCHRS; k++) strcpy(charnames[k], ""); */ cleanencoding(TEXCHRS, MAXCHRS); /* redundant ? */ writevector(fp_out, "textext", MAXCHRS); } writedviend(fp_out); /* 1992/Nov/17 */ /* } */ } /* Write Windows ANSI encoding or what user defined in ENCODING env var */ /* void writeansicode(FILE *fp_out) { */ /* 1993/Sep/30 */ /* void writeansicode(FILE *fp_out, char *textencoding) { */ /* 1994/Dec/17 */ void writeansicode(FILE *fp_out, char *textenconame) { /* 1995/Feb/3 */ /* int k; */ /* if (ansiwritten > 0) return; */ /* already exists 1992/Nov/19 */ writedvistart(fp_out); /* for (k = 0; k < MAXCHRS; k++) strcpy(charnames[k], ansiencoding[k]); */ copyencoding(charnames, ansiencoding, MAXCHRS); /* 93/Nov/15 */ /* writevector(fp_out, "ansinew", MAXCHRS); */ /* writevector(fp_out, textencoding, MAXCHRS); */ /* 94/Dec/17 */ writevector(fp_out, textenconame, MAXCHRS); /* 95/Feb/3 fix 96/May/28 */ writedviend(fp_out); /* 1993/Sep/30 */ } /* overwrite Windows ANSI encoding hard-wired in here */ /* void writetextencode(FILE *fp_out, char *textencoding) {*//* 94/Dec/17 */ int readtextencode(char *textencoding) { /* 94/Dec/17 */ int k; /* char *dupcharname; */ if (readencoding(textencoding) == 0) { for (k = 0; k < MAXCHRS; k++) { /* dupcharname = _strdup(charnames[k]); if (dupcharname == NULL) { fputs("Unable to allocate memory\n", errout); checkexit(1); } */ ansiencoding[k] = zstrdup(charnames[k]); if (ansiencoding[k] == NULL) { showline("Unable to allocate memory\n", 1); checkexit(1); return -1; } } } /* writeansicode(fp_out); */ return 0; } #define ACCENTCHRS 15 #define BASECHRS (26+26) /* Adjust wantchrs table so base and accent of composites are there */ /* (i) we MUST have the base and accent character CharStrings */ /* (ii) for present Adobe interpreters they must ALSO be in encoding */ /* so its easiest to implement this by adjusting wantchrs */ /* keep track of which accents already dealt with in accenthit */ /* (based on StandardEncoding position of accent - 193) */ /* keep track of which base chars already dealt with in basehit */ /* (based on position of base in string `basecharacters') */ /* returns non-zero if any accented character were found */ int expandaccents (char *wantchrs) { char *testname; char basename[9]; /* dotlessi is max length */ int i, j, k, c, n; int compflag, foundflag; int composedflag=0; /* any composites ? */ char *standname; /* 93/Sep/16 */ /* int accentcomplain[ACCENTCHRS]; */ /* for accents from 193 to 207 */ int accenthit[ACCENTCHRS]; /* for accents from 193 to 207 */ /* int basehit[sizeof(basecharacters)]; /* for 28 base characters */ int basehit[BASECHRS]; /* for 26 + 26 base characters */ /* for (k = 0; k < ACCENTCHRS; k++) accentcomplain[k] = 0; */ /* 93/Sep/16 */ for (k = 0; k < ACCENTCHRS; k++) accenthit[k] = 0; /* 94/Feb/17 */ /* for (k = 0; k < sizeof(basecharacters); k++) basehit[k] = 0; */ for (k = 0; k < BASECHRS; k++) basehit[k] = 0; /* 94/Feb/17 */ /* composedflag = 0; */ for (k = 0; k < MAXCHRS; k++) { if (wantchrs[k] == 0) continue; /* ignore unwanted characters */ testname = charnames[k]; /* potential composite char */ n = strlen(testname); /* This eliminates the bulk of charnames, since they are one char long */ /* if (n < 5 || n > 11) continue; /* aring --- acircumflex */ if (n < 4 || n > 14 || n == 13) continue; /* ldot --- uhungarumlaut */ c = testname[0]; /* potential base character */ /* see if in filter list --- is it worth limiting base chars ? */ /* if (strchr(basecharacters, c) == NULL) continue; */ /* must be base */ /* if ((s = strchr(basecharacters, c)) == NULL) continue; */ /* n = s - basecharacters; */ /* compute offset in array 1994/Feb/17 */ /* if (strchr(notbasecharacters, c) != NULL) continue; */ /* NO */ /* if (c < 'A' || c > 'z' || (c < 'a' && c > 'Z') continue; */ /* NOP ? */ if (c < 'A') continue; else if (c <= 'Z') n = c - 'A'; else if (c < 'a') continue; else if (c <= 'z') n = c - 'a' + 26; else continue; /* have eliminated names that are too long or too short - or bad start */ /* if (traceflag) printf("Testing %s ", testname); */ compflag = 0; /* reset composite char flag */ /* NOTE: we only need to worry about accents in StandardEncoding ! */ for (i = 193; i <= 207; i++) { /* check through accents */ /* note that two of the `accent' positions are actually "" */ /* charname = standardencoding[i]; */ /* if (strcmp(testname + 1, charname) == 0) { */ if (strcmp(testname + 1, standardencoding[i]) == 0) { compflag = 1; break; /* found accent in table */ } } /* What about hungarumlaut => hungar and dotaccent => dot */ if (compflag == 0) { if (strcmp(testname + 1, "dot") == 0) { /* 93/Sep/16 */ i = 199; /* dotaccent */ compflag = 1; } else if (strcmp(testname + 1, "hungar") == 0) { /* 93/Sep/16 */ i = 205; /* hungarumlaut */ compflag = 1; } else if (strcmp(testname + 1, "dblacute") == 0) {/* 94/May/25 */ i = 205; /* hungarumlaut */ compflag = 1; } else if (strcmp(testname + 1, "hacek") == 0) {/* 94/May/25 */ i = 207; /* caron */ compflag = 1; } } if (compflag != 0) { /* So, *is* it a composite character ? */ /* composedflag = 0; */ /* was a bug ! */ composedflag = 1; /* fix 1994/Feb/17 */ /* speed up: 94/Feb/17 keep track of which already inserted - in basehit */ if (basehit[n] == 0) { /* see whether already dealt with */ basehit[n]++; /* note that we have been here */ /* request base character first */ /* basename[0] = (char) c; */ /* basename[1] = '\0'; */ if (c == 'i') { strcpy(basename, "dotlessi"); c = 245; /* standard encoding position for dotlessi */ } else { basename[0] = (char) c; basename[1] = '\0'; } if (strcmp(charnames[c], basename) == 0) { /* fast case */ wantchrs[c] = 1; } else { /* otherwise have to search for it */ foundflag = 0; for (j = 0; j < MAXCHRS; j++) { if (strcmp(charnames[j], basename) == 0) { wantchrs[j] = 1; foundflag = 1; break; } } if (foundflag == 0) { sprintf(logline, " `%s' not in encoding", basename); showline(logline, 1); errcount(0); } } } /* end of if basehit[n] == 0 */ /* then request accent character */ /* speed up: 94/Feb/17 keep track of which already inserted - in accenthit */ if (accenthit[i - 193] == 0) { /* check if already dealt with */ accenthit[i - 193]++; /* mark that we dealt with this */ standname = standardencoding[i]; /* 93/Sep/13 */ /* if (strcmp(charnames[i], testname+1) == 0) */ /* fast case */ if (strcmp(charnames[i], standname) == 0) { /* fast case */ wantchrs[i] = 1; } else { /* otherwise have to search for it */ foundflag = 0; for (j = 0; j < MAXCHRS; j++) { /* if (strcmp(charnames[j], testname+1) == 0) { */ if (strcmp(charnames[j], standname) == 0) { wantchrs[j] = 1; foundflag = 1; break; } } if (foundflag == 0) { /* we don't need this anymore, since we come in here only once accenthit */ /* if (accentcomplain[i - 193] == 0) {*/ /* 93/Sep/16 */ sprintf(logline, " `%s' not in encoding", standname); showline(logline, 1); /* accentcomplain[i- 193]++; */ errcount(0); /* } */ } } } } } return composedflag; } /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */ /* Check whether font calls for characters *not* found in encoding! */ /* 1995/July/15 */ int missingchars (char *wantchrs, char *encoding) { int k, unknowns = 0; for (k = 0; k < fontchrs; k++) { /* if (wantchrs[k] != 0 && strcmp(charnames[k], "") == 0) unknowns++;*/ if (wantchrs[k] != 0 && charnames[k][0] == '\0') unknowns++; /* if (wantchrs[k] != 0) printf("%d\t%s\n", k, charnames[k]); */ } /* Encoding passed in may be just "" if read from PFA file 96/May/26 */ if (unknowns > 0) { /* fprintf(errout, " ERROR: %d character%s used not in `%s'", unknowns, (unknowns == 1) ? "" : "s", encoding); */ sprintf(logline, " ERROR: %d character%s used not in ", unknowns, (unknowns == 1) ? "" : "s"); showline(logline, 1); // if (*encoding != '\0') if (encoding != NULL) { sprintf(logline, "`%s'", encoding); showline(logline, 0); } else showline("encoding", 0); errcount(0); } return unknowns; } /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */ /* could keep a record of which accent we already complained about */ /* end of code for dealing with composite characters encoding */ /* write out encoding - cheaply if possible */ /* worry about remapped fonts ? */ /* POSSIBLE PROBLEM: synthetic font, where /FontName appears after /Encoding */ /* not sure it is really worth worrying about... */ /* Maybe simplify this if StandardEncoding and no remapping ??? */ /* void writeencoding(FILE *output, char wantchrs[], int syntheticflag) { */ /* This also adjusts wantchrs to reflect base and accent characters */ /* why aren't we just doing a return instead of setting `done' */ /* void writeencoding(FILE *output, char *wantchrs, int syntheticflag) {*/ void writeencoding(FILE *output, char *wantchrs, int syntheticflag, char *encoding) { int k, standardok=0, textextok=0, ansiok=0, nullchar=0; /* int done=0; */ /* int i; */ /* char *charname; */ int composedflag=0; /* if composite characters used */ /* syntheticflag = fontproper[i] & C_SYNTHETIC; */ /* for (k = fontchrs-1; k >= 0; k--) if (wantchrs[k] != 0) break; */ /* fprintf(output, "/Encoding %d array\n", k+1); */ /* fprintf(output, "0 1 %d {1 index exch /.notdef put} for\n", k); */ /* if (wantchrs[chr] != 0) fprintf(output, "%s", line); */ /* fprintf(output, "%s", line); */ /* unless 'N' flag used, force in base and accent characters */ if (accentedflag != 0) composedflag = expandaccents(wantchrs); else composedflag = 0; if (strcmp(encoding, "standard") == 0) { /* encoding = "StandardEncoding"; */ /* 94/Oct/25 */ /* fprintf(output, "/Encoding StandardEncoding def\n"); */ // fputs("/Encoding StandardEncoding def\n", output); PSputs("/Encoding StandardEncoding def\n", output); return; /* 94/Oct/25 */ } /* Just refer to encoding by name if permitted to do so */ if (strcmp(encoding, "") != 0) { if (bAllowShortEncode) { /* 94/Oct/25 */ /* fprintf(output, "/Encoding %s def\n", encoding); */ /* get rid of path name when referring to encoding 95/Feb/3 */ sprintf(logline, "/Encoding %s def\n", removepath(encoding)); PSputs(logline, output); return; /* done = 1; */ } else goto writefull; /* need to write out encoding in full! */ } /* do not allow use of dviencoding if accented characters seen */ /* Construct new encoding vector */ /* Check whether numeric vector will do *//* most efficient - if allowed */ /* but we don't like this anymore because of clone problems ... */ /* if (done == 0 && composedflag == 0 && */ if (composedflag == 0 && syntheticflag == 0 && /* do we need to worry about this ? */ busedviencode != 0) { /* && accentedflag == 0 */ /* fprintf(output, "/Encoding dviencoding def\n"); */ // fputs("/Encoding dviencoding def\n", output); PSputs("/Encoding dviencoding def\n", output); return; /* done = 1; */ } /* end of dviencoding test */ /* added bSuppressPartial == 0 reference 1992/Sep/12 */ /* added bForceFullArr == 0 reference 1993/Feb/13 */ /* took out bForceFullArr == 0 reference 1993/Sep/30 by extending textext */ /* check whether textext will do */ /* if (done == 0 && composedflag == 0 && bAllowTexText != 0 && */ if (composedflag == 0 && bAllowTexText != 0 && /* bSuppressPartial == 0 && bForceFullArr == 0) { */ bSuppressPartial == 0) { textextok = 1; /* for (k = 0; k < fontchrs; k++) { */ for (k = fontchrs-1; k >= 0; k--) { /* 93/Oct/2 */ if (wantchrs[k] != 0) { if (k >= TEXCHRS || /* 93/Oct/2 */ charnames[k][0] == '\0' || /* 95/July/15 */ strcmp(charnames[k], textext[k]) != 0) { textextok = 0; break; } } } if (textextok != 0) { /* fairly easy */ /* fprintf(output, "/Encoding textext def\n"); */ // fputs("/Encoding textext def\n", output); PSputs("/Encoding textext def\n", output); return; /* done = 1; */ } } /* end of textext trial */ /* check whether Windows ANSI will do 1993/Sep/30 */ /* if (done == 0 && bWindowsFlag != 0) { */ /* if (bWindowsFlag != 0) { */ if (bWindowsFlag != 0 && bAllowANSI != 0 && /* 94/Oct/25 */ bSuppressPartial == 0) { /* 95/May/23 */ ansiok = 1; /* for (k = 0; k < fontchrs; k++) { */ for (k = fontchrs-1; k >= 0; k--) { /* 93/Oct/2 */ if (wantchrs[k] != 0) { if (charnames[k][0] == '\0' || /* 95/July/15 */ strcmp(charnames[k], ansiencoding[k]) != 0) { ansiok = 0; break; } } } if (ansiok != 0) { /* fairly easy */ /* fprintf(output, "/Encoding ansinew def\n"); */ sprintf(logline, "/Encoding %s def\n", /* textencoding); */ /* 94/Dec/17*/ textenconame); /* 94/Dec/17*/ PSputs(logline, output); return; /* done = 1; */ } } /* check whether StandardEncoding will do */ /* if (done == 0 && bAllowStandard != 0) { */ if (bAllowStandard != 0 && bSuppressPartial == 0) { /* 95/May/23 ??? */ standardok = 1; /* for (k = 0; k < fontchrs; k++) { */ for (k = fontchrs-1; k >= 0; k--) { /* 93/Oct/2 */ if (wantchrs[k] != 0) { if (charnames[k][0] == '\0' || /* 95/July/15 */ strcmp(charnames[k], standardencoding[k]) != 0) { standardok = 0; break; } } } if (standardok != 0) { /* nice and easy ! */ /* fprintf(output, "/Encoding StandardEncoding def\n"); */ // fputs("/Encoding StandardEncoding def\n", output); PSputs("/Encoding StandardEncoding def\n", output); return; /* done = 1; */ } } writefull: /* Couldn't use standard, textext, or Windows ANSI for some reason */ /* if (done == 0) { */ k = fontchrs-1; /* use full if partial suppress */ /* if (bSuppressPartial == 0 || bForceFullArr != 0) { */ if (bSuppressPartial == 0 && bForceFullArr == 0) { /* 1993/Feb/15 */ for (k = fontchrs-1; k >= 0; k--) if (wantchrs[k] != 0) break; } /* printf(" suppress %d force %d k+1 %d\n", bSuppressPartial, bForceFullArr, k+1); */ /* debugging */ sprintf(logline, "/Encoding %d array", k+1); PSputs(logline, output); // putc('\n', output); PSputc('\n', output); sprintf(logline, "0 1 %d {1 index exch /.notdef put} for\n", k); PSputs(logline, output); /* nullchar=0; */ for (k = 0; k < fontchrs; k++) { if (wantchrs[k] != 0 || /* addition 1992/Sep/12 */ /* (bSuppressPartial != 0 && strcmp(charnames[k], "") != 0)) { */ (bSuppressPartial != 0 && charnames[k][0] != 0)) { /* if (strcmp(charnames[k], "") != 0) */ if (charnames[k][0] != '\0') { /* 95/July/15 */ sprintf(logline, "dup %d /%s put\n", k, charnames[k]); PSputs(logline, output); } else { nullchar++; /* fprintf(errout, " Null char name %d", k); */ } } } // fprintf(output, "readonly def\n"); PSputs("readonly def\n", output); if (nullchar > 0) { /* somewhat redundant ... */ if (traceflag) { sprintf(logline, " %d null char names", nullchar); showline(logline, 1); } } return; /* } */ } /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */ /* cm-text-fonts cm (r|bx|tt|sltt|vtt|tex|ss|ssi|ssdc|ssbx|ssqi|dunh|bxsl|b|ti|bxti|csc|tcsc) ([0-9]+) */ /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */ void beginresource (FILE *output, char *filefontname) { if (stripcomment == 0) { /* 1994/Feb/3 */ // fputs("%%BeginResource: ", output); PSputs("%%BeginResource: ", output); // fputs("font ", output); PSputs("font ", output); // fputs(filefontname, output); PSputs(filefontname, output); // putc('\n', output); PSputc('\n', output); } } int endresource (FILE *output) { if (stripcomment == 0) { // fputs("%%EndResource\n", output); PSputs("%%EndResource\n", output); } /* good place to check for output error also ... */ // if (ferror(output) != 0) if (output != NULL && ferror(output)) { showline("\n", 0); // sprintf(logline, " ERROR in output file %s\n", outputfile); showline("ERROR in output file", 1); perrormod((outputfile != NULL) ? outputfile : ""); extgiveup(7); return -1; } return 0; } /* Just copy if we don't recognize the format ... no remapping */ /* --- pretty desperate move ! */ /* don't try to be efficient */ /* int i is font number in case needed for error message */ void copyunknown (FILE *output, FILE *input, int i, char *fontnamek) { int c; if (verboseflag) { showline(fontnamek, 0); /* 1995/Mar/1 */ } else { showline("*", 0); } showline(" WARNING: Font type not recognized!\n", 1); while ((c = getc(input)) != EOF) { // putc(c, output); PSputc(c, output); } /* return 1; */ /* just copied the damn thing ! */ } /* copy ascii section of a compressed file - old version */ /* returns EOF if EOF hit */ int copyascii (FILE *output, FILE *input, long n, int firstline) { int c; c = getc(input); n--; if (c == '\r' && flushcr != 0) { c = getc(input); n--; if (c != '\n') { (void) ungetc(c, input); n++; c = '\n'; } } else if (firstline == 0) { // putc('\n', output); PSputc('\n', output); } while (c != EOF) { if (c == 128 || c == 0) { /* hit start of next section */ (void) ungetc(c, input); n++; break; } if (c == '\n') clm = 0; // putc(c, output); PSputc(c, output); c = getc(input); n--; if (c == '\r' && flushcr != 0) { c = getc(input); n--; if (c != '\n') { (void) ungetc(c, input); n++; c = '\n'; } } } if (c == EOF) { sprintf(logline, " Unexpected EOF (%s)\n", "copyascii"); showline(logline, 1); return EOF; } if (n != 0) { sprintf(logline, " Length discrepancy %ld", n); showline(logline, 1); } return 0; } /* copy ascii section of a compressed file - strip {restore}if */ /* returns EOF if EOF hit */ /* special kludge for wrapped synthetic fonts */ int copystrip (FILE *output, FILE *input, long n, int firstline) { int c; char *s, *t; c = getc(input); n--; if (c == '\r' && flushcr != 0) { c = getc(input); n--; if (c != '\n') { (void) ungetc(c, input); n++; c = '\n'; } } else if (firstline == 0) { // putc('\n', output); PSputc('\n', output); } s = line; /* use line as buffer */ while (c != EOF) { if (c == 128 || c == 0) { /* hit start of next section */ (void) ungetc(c, input); n++; break; } if (c == '\n' || c == '\r') { *s++ = (char) c; *s = '\0'; /* terminate line */ if ((s = strstr(line, "{restore}")) != NULL) { if ((t = strstr(line, "cleartomark")) != NULL) { *s++ = (char) c; *s++ = '\0'; /* cut off after cleartomark */ // fputs(line, output); /* 1992/Aug/20 */ PSputs(line, output); /* 1992/Aug/20 */ } if (stripcomment == 0) { /* 1995/May/14 */ // fputs("% font wrapper removed\n", output); PSputs("% font wrapper removed\n", output); } } else { // fputs(line, output); /* finally output it */ PSputs(line, output); /* finally output it */ } s = line; /* reset line buffer */ clm = 0; } /* putc(c, output); */ else *s++ = (char) c; /* check for line length exceeded ? */ c = getc(input); n--; /* get next character */ if (c == '\r' && flushcr != 0) { c = getc(input); n--; if (c != '\n') { (void) ungetc(c, input); n++; c = '\n'; } } } if (c == EOF) { sprintf(logline, " Unexpected EOF (%s)\n", "copystrip"); showline(logline, 1); return EOF; } if (n != 0) { sprintf(logline, " Length discrepancy %ld", n); showline(logline, 1); } return 0; } /* copy binary section of a compressed file */ int copybinary (FILE *output, FILE *input, long n) { int c, d; long k; for (k = 0; k < n; k++) { c = getc(input); if (c == EOF) { sprintf(logline, " Unexpected EOF (%s)\n", "copybinary"); showline(logline, 1); return -1; } d = c & 15; c = (c >> 4) & 15; if (c > 9) c = c + 'A' - 10; else c = c + '0'; if (d > 9) d = d + 'A' - 10; else d = d + '0'; // putc(c, output); PSputc(c, output); // putc(d, output); PSputc(d, output); if ((clm += 2) >= columns) { // putc('\n', output); PSputc('\n', output); clm = 0; } } return 0; } void copypfa (FILE *output, FILE *input, int stripflag) { int c; char *s, *t; if (stripflag == 0) { /* normal easy case */ while ((c = getc(input)) != EOF) { if (c == '\r' && flushcr != 0) { c = getc(input); if (c != '\n') { (void) ungetc(c, input); c = '\n'; } } // putc(c, output); PSputc(c, output); } } else { /* need to watch for closing wrapper */ while (extgetline (input, line) != EOF) { if ((s = strstr(line, "{restore}")) != NULL) { if ((t = strstr(line, "cleartomark")) != NULL) { *s++ = '\n'; *s++ = '\0'; /* cut off after cleartomark */ // fputs(line, output); /* 1992/Aug/20 */ PSputs(line, output); /* 1992/Aug/20 */ } continue; /* just flush it */ } // fputs(line, output); PSputs(line, output); } } } /* special purpose hack for fonts in PFA format that suck rocks */ /* flush this eventually ... */ void copymtmi (FILE *output, FILE *input, int stripflag) { /* int c; */ char *s, *t; /* char buffer[MAXCHRS]; */ if (stripflag == 0) showline(" no wrapper ", 1); /* debugging */ while (extgetline (input, line) != EOF) { if ((s = strstr(line, "{restore}")) != NULL) { if ((t = strstr(line, "cleartomark")) != NULL) { *s++ = '\n'; *s++ = '\0'; /* cut off after cleartomark */ // fputs(line, output); /* 1992/Aug/20 */ PSputs(line, output); /* 1992/Aug/20 */ } continue; } // fputs(line, output); PSputs(line, output); } } /* This is typically called after already wading into the ASCII section */ /* but only if syntheticflag or mtmiflag non-zero */ /* int i is font number in case needed for error message */ void copyfont (FILE *output, FILE *input, int i, int mtmiflag, int stripflag) { int c, d, firstline = 1; int ascii=1, binary=0; /* section counts */ /* presently not used */ long n; firstline = 0; /* since we already past start of file ! */ c = getc(input); /* skip over initial white space */ while (c == '\n' || c == '\r' || c == ' ') c = getc(input); (void) ungetc(c, input); /* putc('\n', output); */ /* ??? */ clm = 0; if (c == 0) { /* assume MacIntosh format */ /* showline(" MAC ", 0); */ /* debugging */ n = maclength(input); c = getc(input); d = getc(input); /* d should be zero */ while (c != 5) { if (c == 1) { ascii++; if (copyascii(output, input, n - 2, firstline) != 0) break; firstline = 0; } else if (c == 2) { binary++; if (copybinary(output, input, n - 2) != 0) break; } else { sprintf(logline, " Unrecognized section code %d", c); showline(logline, 1); break; } n = maclength(input); c = getc(input); d = getc(input); if (c == EOF) { sprintf(logline, " Unexpected EOF (%s)\n", "copyfont"); showline(logline, 1); break; } } } else if (c == 128) { /* assume PFB format */ /* showline(" PFB ", 0); */ /* debugging */ c = getc(input); d = getc(input); while (d != 3) { n = readlength(input); if (d == 1) { /* ASCII section code */ ascii++; /* printf(" strip %d ascii %d ", stripflag, ascii); *//* debug */ if (stripflag != 0 && ascii > 1) { if (copystrip(output, input, n, firstline) != 0) break; } else { if (copyascii(output, input, n, firstline) != 0) break; } firstline = 0; } else if (d == 2) { /* binary section code */ binary++; if (copybinary(output, input, n) != 0) break; } else { sprintf(logline, " Unrecognized section code %d", d); showline(logline, 1); break; } c = getc(input); d = getc(input); if (c == EOF) { sprintf(logline, " Unexpected EOF (%s)\n", "copyfont"); showline(logline, 1); break; } } } else if ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f')) { /* assume PFA format */ /* showline(" PFA ", 0); */ /* debugging */ if (mtmiflag == 0) copypfa (output, input, stripflag); /* normal PFA */ else copymtmi (output, input, stripflag); /* MTMI */ } else { sprintf(logline, " Don't understand font file format %d", c); showline(logline, 1); errcount(0); } /* following duplicates code at end of extracttype1 */ endresource(output); /* share code */ } /* Use the following more in future to avoid dependency on line breaks ? */ /* grab next white space delimited token in line */ /* read line if needed */ /* assumes pump has been primed, i.e. line read and strtok called once */ char *grabnexttoken(FILE *input, char *line) { char *str=NULL, *s; for (;;) { while ((s = strtok(str, " \t\n\r")) == NULL) { for(;;) { /* need to grab a new line then */ if (extgetrealline(input, line) < 0) return NULL; /* EOF */ /* ignore comments and blank lines - continue round the loop */ if (*line != '%' && *line != '\n' && *line != '\r') break; } str = line; } if (*s != '%') break; /* escape if not comment */ /* following added to strip comments off ends of lines 1992/Sep/17 */ for(;;) { /* need to grab a new line then */ if (extgetrealline(input, line) < 0) return NULL; /* EOF */ /* ignore comments and blank lines - continue round the loop */ if (*line != '%' && *line != '\n' && *line != '\r') break; } str = line; } return s; } int gobbleencoding (FILE *input) { /* new tokenized version follows */ int chr, c, n; int base=10; char *s, *t; /* cleanencoding(0, MAXCHRS); */ /* may want to remove some debugging error message output later ... */ s = strtok(line, " \t\n\r"); /* start the pipeline */ for (;;) { /* exit if hit `readonly' or `def' ??? */ if (strcmp(s, "dup") != 0) { if (strcmp(s, "readonly") == 0 || strcmp(s, "def") == 0) break; /* normal exit */ sprintf(logline, " Expecting %s, not: `%s' ", "`dup'", s); showline(logline, 1); break; } if ((s = grabnexttoken(input, line)) == NULL) break; /* Cater to stupid Adobe Universal Greek font format */ /* 92/Sep/17 */ if (strchr(s, '#') != NULL) { /* stupid encoding vector format */ (void) sscanf(s, "%d#%n", &base, &n); /* try and get base */ s +=n; chr=0; for (;;) { /* more general version 92/Sep/27 */ c = *s++; if (c >= '0' && c <= '9') c = c - '0'; else if (c >= 'A' && c <= 'Z') c = c - 'A' + 10; else if (c >= 'a' && c <= 'z') c = c - 'a' + 10; else { s--; break; } chr = chr * base + c; } /* if (base == 8) { if (sscanf(s, "%d#%o", &base, &chr) < 2) { fputs(line, errout); break; } } else if (base == 16) { if (sscanf(s, "%d#%x", &base, &chr) < 2) { fputs(line, errout); break; } } */ } /* end of radixed number case */ else if (sscanf(s, "%d", &chr) < 1) { sprintf(logline, " Expecting %s, not: `%s' ", "number", s); showline(logline, 1); break; } /* deal with idiotic Fontographer format - no space before /charname */ if ((t = strchr(s, '/')) != NULL) s = t; /* 1992/Aug/21 */ else if ((s = grabnexttoken(input, line)) == NULL) break; if (*s != '/') { sprintf(logline, "Bad char code `%s' ", s); showline(logline, 1); break; // ??? } else s++; /* if (chr >= 0 && chr < fontchrs && strlen(s) < MAXCHARNAME) { */ if (chr >= 0 && chr < fontchrs) { /* 93/Nov/15 */ /* printf("%d: %s ", chr, s); */ /* debugging */ /* strcpy(charnames[chr], s); */ if (strcmp(s, ".notdef") != 0) /* ignore .notdef 97/Jan/7 */ addencoding(chr, s); /* 93/Nov/15 */ } else { sprintf(logline, "Invalid char number %d ", chr); showline(logline, 1); break; // ??? } if ((s = grabnexttoken(input, line)) == NULL) break; if (strcmp(s, "put") != 0) { sprintf(logline, " Expecting %s not: `%s' ", "`put'", s); showline(logline, 1); /* break; */ /* ??? */ } if ((s = grabnexttoken(input, line)) == NULL) break; } /* normally come here because line does not contain `dup' */ /* but does contain `readonly' or `def' */ /* attempt to deal with Fontographer 4.0.4 misfeature 94/Nov/9 */ /* if `readonly' appears on one line and `def' appears on the next */ if (strcmp(s, "readonly") == 0) { if ((s = grabnexttoken(input, line)) != NULL) { if (strcmp(s, "def") != 0) { sprintf(logline, " Expecting %s, not: `%s' ", "`def'", s); showline(logline, 1); // return -1; // ??? } } } /* need to clean out current line at all ? */ return 0; } /* check whether a TeX font - result not really used */ /* used only if resident font names are to be upper cased (-U) */ /* (so maybe the `lowercase' is not needed ?) */ /* or use _strnicmp(...) */ /* May be useful when PostScript FontName same as filename, but uppercase */ int istexfont (char *fname) { if (_strnicmp (fname, "cm", 2) == 0 || /* Computer Modern (visible) */ _strnicmp (fname, "lcm", 3) == 0 || /* SliTeX (visible) */ _strnicmp (fname, "icm", 3) == 0 || /* Computer Modern invisible */ _strnicmp (fname, "ilcm", 4) == 0 || /* SliTeX invisible */ _strnicmp (fname, "msam", 4) == 0 || /* AMS math symbol */ _strnicmp (fname, "msbm", 4) == 0 || /* AMS math symbol */ _strnicmp (fname, "eu", 2) == 0 || /* Euler fonts */ _strnicmp (fname, "wncy", 4) == 0 || /* Washington Cyrillic */ _strnicmp (fname, "logo", 4) == 0 || /* logo fonts - METAFONT */ _strnicmp (fname, "lasy", 4) == 0 || /* LaTeX symbol font */ _strnicmp (fname, "line", 4) == 0 || /* LaTeX line fonts */ _strnicmp (fname, "lcircle", 7) == 0 || /* LaTeX circle fonts */ _strnicmp (fname, "mtmi", 4) == 0 || /* MTMI, MTMIB, MTMIH */ _strnicmp (fname, "mtmu", 4) == 0 || /* , MTMUB, MTMUH */ _strnicmp (fname, "mtms", 4) == 0 || /* MTMS, MTMSB */ _strnicmp (fname, "mtsy", 4) == 0 || /* MTSY, MTSYB, MTSYH, MTSYN */ _strnicmp (fname, "mtex", 4) == 0 || /* MTEX, MTEXB, MTEXH */ _strnicmp (fname, "mtgu", 4) == 0 || /* MTGU, MTMGUB */ _strnicmp (fname, "rmtm", 4) == 0 /* RMTMI, RMTMIB, RMTMIH */ /* , RMTMUB, RMTMUH */ /* _strnicmp (fname, "lm", 2) == 0 || */ /* LucidaMath */ /* _strnicmp (fname, "lbm", 3) == 0 || */ /* LucidaNewMath */ ) return 1; else return 0; } /* separated out 97/Feb/6 */ /* returns 0 if failed */ /* this should also check for /BaseFontName and suppress replacement ? */ /* WARNING: this writes back into second argument ! */ int FindFontPFBaux (FILE *input, char *FontName, int nlen) { char token[] = "/FontName "; int c, k=0; char *s=FontName; while ((c = getc(input)) != EOF) { if (c == '%') /* Try and avoid comment lines ... */ while (c >= ' ') c = getc(input); /* Skip to end of line */ if (c != token[k]) { k = 0; /* no match, reset ... */ continue; } k++; if (k >= 10) { /* completed the match ? */ while ((c = getc(input)) != '/' && c != EOF) { /* up to slash */ if (c > ' ') { /* only white space allowed here 97/June/1 */ k = 0; continue; /* ignore /FontName *not* followed by /xxxxx */ } } k = 0; s = FontName; /* while ((c = getc(input)) > ' ' && k < MAXFONTNAME) */ while ((c = getc(input)) > ' ' && k++ < nlen) /* buffer[k++] = (char) c; */ *s++ = (char) c; /* fclose (input); */ /* if (c != EOF && k < MAXFONTNAME) { */ if (c != EOF && k < nlen) { /* buffer[k] = '\0'; */ *s = '\0'; /* strcpy (FontName, buffer); */ #ifdef DEBUG if (traceflag) { sprintf(logline, "Found /FontName %s in %s\n", FontName, FileName); showline(logline, 0); } #endif return 1; /* success */ } else return 0; /* failed, EOF in FontName or name too long */ } } return 0; /* failed - EOF read the whole file */ } // FILE *OpenFont(char *font, int flag); /* Attempt to find FontName from PFB file when forcereside != 0 */ /* An experiment 1993/Sep/30 */ /* WARNING: this writes back into second argument ! */ int FindFontPFB (char *FileName, char *FontName, int nlen) {/* 1993/Sep/30 */ int flag; FILE *input; if ((input = OpenFont(FileName, 0)) == NULL) { #ifdef DEBUG if (traceflag) { sprintf(logline, "Unable to find font file for %s\n", FileName); /* debug ? */ showline(logline, 0); } #endif return 0; } flag = FindFontPFBaux(input, FontName, nlen); fclose (input); if (flag == 0) { sprintf(logline, "Unable to find FontName in %s\n", FileName); showline(logline, 1); } return flag; } /* finding PS FontName from PFM file */ // FILE *openpfm (char *font); /* WARNING: this writes back into second argument ! */ int FindFontPFM (char *FileName, char *FontName, int nlen) { /* 1997/June/1 */ FILE *input; int flag; if (traceflag) { sprintf(logline, "FindFontPFM nlen %d\n", nlen); showline(logline, 0); } if ((input = openpfm(FileName)) == NULL) { #ifdef DEBUG if (traceflag) { sprintf(logline, "Unable to find font file for %s\n", FileName); /* debug ? */ showline(logline, 0); } #endif return 0; } flag = NamesFromPFM(input, NULL, 0, FontName, nlen, FileName); fclose (input); /* printf("FontName %s for FileName %s\n", FontName, FileName); */ return flag; } /* Try and find font name in PFB / PFA file or in PFM file */ /* WARNING: this writes back into second argument ! */ int FindFontName (char *FileName, char *FontName, int nlen) {/* 1993/Sep/30 */ if (traceflag) { sprintf(logline, " FindFontName `%s' %d\n", FileName, nlen); showline(logline, 0); // debugging only } if (FindFontPFB (FileName, FontName, nlen) == 0) { if (FindFontPFM(FileName, FontName, nlen) == 0) return 0; } return 1; } /* Split out 1992/Oct/8 - avoid assumption FontName occurs before Encoding */ /* Now use even earlier - avoid assumption FontName comes after FontInfo */ /* returns non-zero if font appears to be synthetic font */ /* drops real PostScript FontName in realfontname if found */ int parseline(char *line, FILE *output, int syntheticflag, int mtmiflag) { double m11, m12, m21, m22, m31, m32; int ftp, k, n; char *s; /* Try and pick out FontType */ if ((s = strstr(line, "/FontType")) != NULL) { if(sscanf(s, "/FontType %d", &ftp) == 1) { if (ftp != 1) { sprintf(logline, " Not a Type 1 font: %s", line); showline(logline, 1); errcount(0); } } // fputs(line, output); PSputs(line, output); } /* Try and pick out FontName */ else if ((s = strstr(line, "/FontName")) != NULL) { /* if (sscanf(s, "/FontName /%s", realfontname) > 0) { */ s += 9; /* step over `/FontName' */ while (*s != '/' && *s != '\0') s++; /* 1993/Aug/15 */ /* Verify that the FontName we got from %! line is correct 97/Jan/30 */ if (bAddBaseName && *realfontname != '\0') { if (*s == '/') { /* fix 1997/June/1 */ n = strlen(realfontname); if (strncmp(s+1, realfontname, n) != 0) { sprintf(logline, " ERROR: %s != ", realfontname); showline(logline, 1); if (sscanf(s, "/%s", realfontname) > 0) { sprintf(logline, "%s ", realfontname); } else { sprintf(logline, "%s ", s); } showline(logline, 0); } } } if (sscanf(s, "/%s", realfontname) > 0) { /* if (verboseflag) fputs(realfontname, stdout); */ /* Don't trust `Oblique' (and `Narrow') fonts */ /* Helvetica and Courier may be the only common cases of such fonts ??? */ /* Helvetica, Helvetica-Light, Helvetica-Black, Helvetica-Narrow */ /* Maybe also `Slanted' and `Narrow' and `Condensed' and `Expanded' ??? */ /* Inverted order of tests for efficiency -- 1993/Nov/4 */ if (syntheticsafe != 0) { if (strstr(s, "Oblique") != NULL || strstr(s, "BoldObl") != NULL || /* 1994/Feb/3 */ strstr(s, "Narrow") != NULL) { /* 1993/June/14 */ for (k = 0; k < 16; k++) { if (strcmp("", syntheticfonts[k]) == 0) break; if (strstr(s, syntheticfonts[k]) != NULL) { syntheticflag = 1; if (verboseflag) { showline(" assumed synthetic", 0); /* debugging */ } break; } } } } /* lowercase(realfontname, realfontname); */ /* removed 95/Aug/22 */ } /* check whether TeX font */ /* result not used much ... */ texfont = 0; /* 1992/Dec/22 */ if (istexfont(realfontname) != 0) { /* also check if actually one of 75 TeX fonts (what about LATEX, SliTeX) ? */ texfont = 1; standard = 0; } /* Should we replace /FontName or not ? *//* Presently hard wired to do this */ /* May need to be more careful here - assuming one line */ /* if (bSubRealName == 0) { */ /* 1995/Aug/22 */ if (bSubRealName == 0 || mmflag != 0) { /* 1997/June/1 */ /* we don't normally come here these days ... */ /* copy realfontname to subfontname[k] ? */ /* strcpy(subfontname + k * MAXFONTNAME, realfontname); */ // if (strcmp(fontprefix, "") == 0) { if (fontprefix != NULL) { *s = '\0'; /* s points at / */ // fputs(line, output); PSputs(line, output); *s = '/'; // putc('/', output); PSputc('/', output); /* possibly modify if bRandomPrefix is set ??? */ // fputs(fontprefix, output); PSputs(fontprefix, output); // fputs(s+1, output); PSputs(s+1, output); } else { // fputs(line, output); /* no prefix, just copy over */ PSputs(line, output); /* no prefix, just copy over */ } } /* Don't mess with FontName of old MTMI */ else if (mtmiflag != 0) { // fputs(line, output); /* 1992/Aug/22 */ PSputs(line, output); /* 1992/Aug/22 */ } /* Don't mess with FontName of MM base font ? old method */ /* 1994/Dec/6 */ /* else if (bMMNewFlag == 0 && mmflag != 0) fputs(line, output); */ /* Don't touch: 2 copy exch /FontName exch put */ /* 95/May/14 */ else if (strstr(line, "/FontName exch") != NULL) { // fputs(line, output); PSputs(line, output); } else { /* 1992/Oct/31 */ // fputs("/FontName /", output); PSputs("/FontName /", output); /* don't need to check here whether its resident or not ! */ // if (strcmp(fontprefix, "") != 0) if (fontprefix != NULL) { /* possibly modify if bRandomPrefix is set ??? */ // fputs(fontprefix, output); PSputs(fontprefix, output); } /* following inserted 1992/Dec/22 - for new `U' flag */ /* if (uppercaseflag != 0 && istexfont(filefontname) != 0) */ if (uppercaseflag != 0 && texfont != 0) uppercase(filefontname, filefontname); /* if(_stricmp(filefontname, realfontname) == 0) strcpy(filefontname, realfontname); */ /* ??? */ // fputs(filefontname, output); PSputs(filefontname, output); // fputs(" def\n", output); PSputs(" def\n", output); } } /* Try and pick out FontMatrix */ /* Following usually doesn't get triggered because FontName seen first */ /* Can't be more selective here, since don't know FontName ... */ else if ((s = strstr(line, "/FontMatrix")) != NULL) { if (sscanf(s, "/FontMatrix[%lg %lg %lg %lg %lg %lg]", &m11, &m12, &m21, &m22, &m31, &m32) == 6) { if (syntheticsafe != 0 && syntheticflag == 0) { if (m11 != m22 || m21 != 0.0 || m12 != 0.0) { showline(" WARNING: use *synthetic* in sub file", 1); /* errcount(0); */ /* 1994/Jan/7 */ syntheticflag = 1; } } } // fputs(line, output); PSputs(line, output); } else { // fputs(line, output); PSputs(line, output); } return syntheticflag; } /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */ unsigned long checkdefault = 0x59265920; /* default signature */ /* Takes first six letters of encoding vector name and compresses */ /* into four bytes using base 40 coding */ /* 40^6 < s^32 */ /* Treats lower case and upper case the same, ignores non alphanumerics */ /* Except handles -, &, and _ */ unsigned long codefourty(char *codingvector) { unsigned long result=0; int c, k; char *s=codingvector; if (strcmp(codingvector, "") == 0) { codingvector = "native"; /* if not specified ... */ return checkdefault; /* use default signature */ } for (k = 0; k < 6; k++) { for (;;) { c = *s++; if (c >= 'A' && c <= 'Z') c = c - 'A'; else if (c >= 'a' && c <= 'z') c = c - 'a'; else if (c >= '0' && c <= '9') c = (c - '0') + ('Z' - 'A') + 1; else if (c == '-') c = 36; else if (c == '&') c = 37; else if (c == '_') c = 38; else c = 39; /* none of the above */ /* else continue; */ /* not alphanumeric character */ /* result = result * 36 + c; */ result = result * 40 + c; break; } } return result; } int decodefourty(unsigned long checksum, char *codingvector) { int c; int k; /* char codingvector[6+1]; */ /* if (checksum == checkdefault) { */ if (checksum == 0) { strcpy(codingvector, "unknown"); return 1; } else if ((checksum >> 8) == (checkdefault >> 8)) { /* last byte random */ strcpy (codingvector, "native"); /* if not specified ... */ return 1; /* no info available */ } else { for (k = 0; k < 6; k++) { /* c = (int) (checksum % 36); */ c = (int) (checksum % 40); /* checksum = checksum / 36; */ checksum = checksum / 40; if (c <= 'z' - 'a' ) c = c + 'a'; else if (c < 36) c = (c + '0') - ('z' - 'a') - 1; else if (c == 36) c = '-'; else if (c == 37) c = '&'; else if (c == 38) c = '_'; else c = '.'; /* unknown */ codingvector[5-k] = (char) c; } codingvector[6] = '\0'; } return 0; /* encoding info returned */ } int checkencoding(int k) { char checksumvector[8]; /* 6 chars + null */ if (fc[k] == nCheckSum) return 0; /* correct encoding */ if (decodefourty(fc[k], checksumvector) != 0) return 0; /* if (_strnicmp(checksumvector, textencoding, 6) != 0) */ /* 95/Feb/3 */ if (_strnicmp(checksumvector, textenconame, 6) == 0) return 0; // showline(" ", 0); showline(" WARNING: encoding mismatch ", 1); sprintf(logline, "TFM: `%s..' versus PFB: `%s'", /* checksumvector, textencoding); */ checksumvector, textenconame); /* 95/Feb/3 */ showline(logline, 1); return 1; /* failed */ } int checkremapencode(int k, char *fontnamek) { /* 1995/July/15 */ char checksumvector[8]; /* 6 chars + null */ if (decodefourty(fc[k], checksumvector) != 0) return 0; // if (_strnicmp(checksumvector, fontvector + k * MAXVECNAME, 6) == 0) if (fontvector[k] != NULL && _strnicmp(checksumvector, fontvector[k], 6) == 0) return 0; showline(" WARNING: encoding mismatch ", 1); sprintf(logline, " in %s ", fontnamek); /* 95/July/30 */ showline(logline, 1); sprintf(logline, "TFM: `%s..' versus vector: `%s'\n", checksumvector, fontvector[k] != NULL ? fontvector[k] : ""); // checksumvector, fontvector + k * MAXVECNAME); showline(logline, 1); return 1; } /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */ /* share some code between extracttype1 and extracttype3 ??? */ /* e.g. for BeginResource and EndResource ? OK, that has been done */ /* actually, appears to be some divergence now ... */ /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */ /* decompress a Type 1 font file and send it to specified output */ /* int extracttype1(FILE *output, FILE *input, int i) { */ /* int extracttype1(FILE *output, FILE *input, int fn) { */ int extracttype1 (FILE *output, FILE *input, int fn, char *fontnamek) { int nvec, ns, ne, c, d, k, nbin, n, nchrs, flag; /* int chr, nfdict; */ int count, property, syntheticflag, mtmiflag; /* int hybridflag; */ /* 1993/Aug/5 */ /* made global 1994/July/15 */ /* int ftp; */ int stripflag=0; /* int oldcount; */ /* int m; */ /* debug only */ int l; /* 1994/Jan/30 for `unseen' repeat appearance */ int guess; /* 1995/Oct/25 */ char *s, *t, *vector; char charname[FNAMELEN]; /* just to be safe */ // char subfontnamek[MAXFONTNAME]; char subfontnamek[FNAMELEN]; char *wantchrs; hybridflag=0; binaryin = 0; /* macstyle = 0; */ // wantchrs = fontchar + MAXCHRS * fn; wantchrs = fontchar[fn]; if (wantchrs == NULL) showline(" BAD wantchrs", 1); property = fontproper[fn]; // vector = fontvector + fn * MAXVECNAME; vector = fontvector[fn]; syntheticflag = (property & C_SYNTHETIC); mtmiflag = (property & C_MTMI); mmflag = (property & C_MULTIPLE); /* 95/May/13 */ // strcpy(subfontnamek, subfontname + fn * MAXFONTNAME); /* 97/June/1 */ if (subfontname[fn] != NULL) strcpy(subfontnamek, subfontname[fn]); else *subfontnamek = '\0'; if (bSuppressPartial != 0) syntheticflag = 1; /* 1992/Sep/12 */ /* if (syntheticflag != 0) printf(" synthetic font"); */ /* debugging */ if (mtmiflag != 0) showline(" NOT Type 1", 1); count = 0; /* preliminary - may update later with accents */ for (k = 0; k < MAXCHRS; k++) if (wantchrs[k] != 0) count++; /* printf("%d used in ", count, fontnamek); */ /* debug 95/Mar/31 */ /* if (bMMNewFlag == 0 && mmflag != 0) count = MAXCHRS;*//* 94/Dec/6 */ if (count == 0) { /* strcpy(charname, fontname + fn * MAXTEXNAME); */ /* fprintf(errout, " No characters used in font %s (%d)", charname, fn); */ /* 1995/Jan/5 */ if (traceflag) showline(" No characters used in font", 1); /* else if (verboseflag) putc('*', stdout); */ /* 1995/Feb/1 */ fontproper[fn] |= C_UNUSED; /* 1995/Feb/1 */ /* strcpy(charname, fontname + fn * MAXTEXNAME); */ /* printf("Font %s (%d) marked C_UNUSED\n", charname, fn); */ return -1; /* shouldn't ever happen ? unless page sub range ... */ } else if (verboseflag) { showline(fontnamek, 0); } else { showline("*", 0); } /* if (syntheticflag != 0) count = MAXCHRS; */ /* 1992/Aug/22 */ /* Now actually start looking at the file! */ if (bAddBaseName) { /* try and get /FontName 97/Feb/6 */ bBaseNameDone = 1; *realfontname = '\0'; if (FindFontPFBaux (input, realfontname, sizeof(realfontname))) /* FNAMELEN */ bBaseNameDone = 0; /* found it, so use it */ rewind(input); } c = getc(input); (void) ungetc(c, input); if (c == 0) { /* check if this is a Mac style font file */ /* macstyle = 1; */ /* try and position at start of ASCII length field */ /* need to figure out where we are in Mac file */ /* could be (a) at start of MacBinary header */ /* (b) at start of resource fork (128 byte later) */ /* (c) at start of actual resource (256 byter after that) */ binaryin = 1; (void) getc(input); /* first byte (0) again */ if ((c = getc(input)) != 0) { /* start of MacBinary ? */ for (k = 2; k < 384; k++) (void) getc(input); /* yes */ c = getc(input); (void) ungetc(c, input); if (c != 0) { /* try and verify format */ showline(" ERROR: Not a valid PC (or Mac) style font file ", 1); errcount(0); return 0; /* errcount ? */ } } else { /* now try and check whether at start of resource fork, */ /* which starts with (0, 0, 1, 0) = 256 length */ c = getc(input); d = getc(input); if (c == 1 && d == 0) { /* then skip over resource fork section */ for (k = 4; k < 256; k++) (void) getc(input); c = getc(input); (void) ungetc(c, input); if (c != 0) { /* try and verify format */ showline(" ERROR: Not a valid PC (or Mac) style font file ",1 ); errcount(0); return 0; /* errcount ? */ } } else { /* try and imagine we are right there actually */ /* rewind(input); */ /* back to start of length code */ (void) getc(input); (void) getc(input); /* skip length */ } } } /* end of first byte is zero in file case */ chrs = -1; task = "copying heading line"; k = extgetline(input, line); /* get first line of font */ if (*line != '%' || *(line + 1) != '!') { showline(" Nonstandard font file start: ", 1); showline(line, 1); errcount(0); } if (strstr(line, "Type3") != NULL || strstr(line, "Font-3") != NULL) { type3flag = 1; /* well, maybe lets try Type 3 then ! */ rewind(input); return 0; /* indicate lack of success ! */ } if (stripcomment == 0) { if (mmflag) beginresource(output, subfontnamek); /* 97/June/1 */ else beginresource(output, filefontname); /* share code */ /* fprintf(output, "%s", line); */ /* copy %! heading line ??? */ // fputs(line, output); PSputs(line, output); if (wantcreation != 0) { k = extgetline(input, line); /* check second line of font */ /* if (*line != '%' || strncmp(line, "%%CreationDate", 14) == 0) */ if (strncmp(line, "%%CreationDate", 14) == 0) /* 1995/April/12 */ /* fprintf(output, "%s", line); */ // fputs(line, output); PSputs(line, output); /* this line gets output below anyway, unless its a comment */ } } task = "looking for FontInfo"; /* strcpy(realfontname, ""); */ /* 95/Aug/22 */ /* removed 97/Jan/30 */ while (strstr(line, "/FontInfo") == NULL && k >= 0) { /* Try and strip out that `font wrapper' stuff checking for existing font ! */ /* ===> NOTE: this is in outer level <=== */ /* Used in Courier, Helvetica for example */ /* Also junk in Fontographer style fonts - up to three lines long */ /* if (stripchecking != 0 && syntheticflag == 0) { */ if (stripchecking != 0) { if (strstr(line, "FontDirectory") != NULL) { stripflag++; k = extgetline(input, line); if (strstr(line, "/FontType") != NULL) { k = extgetline(input, line); } if (strstr(line, "{save true}") != NULL) { /* 1992/Aug/21 */ k = extgetline(input, line); } /* search up to line containing `{false}ifelse' ? */ /* search up to ` dict begin' ? */ while (strstr(line, "dict") == NULL) { /* 1992/Oct/22 */ k = extgetline(input, line); if (k == EOF) break; } if (stripcomment == 0) { // fputs("% font wrapper removed\n", output); PSputs("% font wrapper removed\n", output); } /* putc('\n', output); */ /* at least leave some space */ } /* end of strstr(line, "FontDirectory") != NULL */ } /* end of stripchecking != 0 */ /* ignore comment lines OTHER than copyright or trademark line */ if (*line == '%') { if (strstr(line, "opyright") != NULL || strstr(line, "rademark") != NULL || strstr(line, "(c)") != NULL) // fputs(line, output); PSputs(line, output); } /* Ignore blank lines */ else if (*line != '\n') { /* fputs(line, output); */ /* 1992/July/18 */ /* 95/April/12 */ /* Check for FontName even this early - added 95/April/12 */ syntheticflag = parseline(line, output, syntheticflag, mtmiflag); /* parseline outputs the line itself (or modified version) */ } k = extgetline(input, line); /* getrealline(input, line); */ } /* Should now have /FontInfo line */ /* increase dictionary allocation */ if (bAddBaseName && !bBaseNameDone) { flag = 0; if ((s = strstr(line, "/FontInfo")) != NULL) { s +=10; if (sscanf(s, "%d%n dict", &k, &n) == 1) { char buffer[FNAMELEN]; /* long enough ? */ strcpy(buffer, s+n); sprintf(s, "%d", k+1); strcat(s, buffer); /* printf(line); */ /* debugging */ flag++; } } if (flag == 0) { showline(" ERROR: unable to extend FontInfo dictionary\n", 1); bBaseNameDone++; } } task = "stripping out FontInfo"; /* Now strip info ONLY if busedviencode is set --- 1992/July/18 */ /* It would be dangerous to retain /Notice in /FontInfo directory only, */ /* since /Notice may be multiline --- changes 1992/July/18 */ /* This has a somewhat flakey termination test ... */ /* usually the end is `end readonly def' */ while (strstr(line, "end ") == NULL && k >= 0) { if (stripinfo == 0 || busedviencode == 0) { // fputs(line, output); PSputs(line, output); } else if ((s = strstr(line, "/Notice")) != NULL) { sprintf(logline, "%% %s", s); /* s+1 ? */ PSputs(logline, output); } /* Try and put it after the /FullName in /FontInfo dictionary ? */ if (strstr(line, "/BaseFontName ") != NULL) bBaseNameDone++; /* In this case however the FontInfo dict is now one entry too large */ /* if (strstr(line, "/FullName") != NULL) { if (bAddBaseName && !bBaseNameDone) { fprintf(output, "/BaseFontName (%s) def\n", realfontname); bBaseNameDone++; } } */ k = extgetrealline(input, line); } /* If haven't placed BaseFontName yet, do it here */ /* 97/Jan/30 */ if (bAddBaseName && !bBaseNameDone) { sprintf(logline, "/BaseFontName (%s) def\n", realfontname); PSputs(logline, output); bBaseNameDone++; } if (stripinfo == 0 || busedviencode == 0) { /* terminating line FontInfo */ // fputs(line, output); PSputs(line, output); } /* does this assume FontName comes before Encoding ? YES, ugh */ task = "looking for Encoding & FontName"; k = extgetrealline(input, line); /* look for encoding */ while (strstr(line, "/Encoding") == NULL && k >= 0) { syntheticflag = parseline(line, output, syntheticflag, mtmiflag); k = extgetrealline(input, line); } /* special case hack when "def" is on line *after* StandardEncoding 98/Oct/8 */ if (strstr(line, "StandardEncoding") != NULL) { if (strstr(line, "def") == NULL) { s = line + strlen(line); *(s-1) = ' '; /* turn line termination into space */ k = extgetrealline(input, s); /* printf("LINE: %s", line); */ } } /* Now we have hit the encoding vector --- /Encoding in line */ if (mtmiflag != 0) { /* don't mess with vector if font sucks rocks */ // fputs(line, output); /* 1992/Aug/22 */ PSputs(line, output); /* 1992/Aug/22 */ } #ifdef IGNORED else if ((property & C_MULTIPLE) != 0) { /* don't mess with MM base */ // fputs(line, output); /* 1997/June/1 */ PSputs(line, output); /* 1997/June/1 */ } #endif /* test 97/Nov/30 */ /* else if (bMMNewFlag == 0 && mmflag != 0) fputs(line, output); */ else if ((property & C_REMAPIT) == 0) { /* if font is not remapped */ if (strstr(line, "StandardEncoding") != NULL) { /* easy case! */ standard = 1; texfont = 0; fontchrs = MAXCHRS; if (bWindowsFlag != 0) { if (verboseflag) { // putc('~', stdout); // if (logfileflag) putc('~', logfile); showline("~", 0); } /* for (k = 0; k < fontchrs; k++) strcpy(charnames[k], ansiencoding[k]); */ /* ansi encoding may have been changed if env var ENCODING is set ??? */ copyencoding(charnames, ansiencoding, fontchrs); /* 93/Nov/15*/ /* writeencoding(output, wantchrs, syntheticflag, "ansinew"); */ /* writeencoding(output, wantchrs, syntheticflag, textencoding); */ missingchars(wantchrs, textenconame); /* TEST 95/July/15 */ writeencoding(output, wantchrs, syntheticflag, textenconame); if (bCheckEncoding) (void) checkencoding(fn); /* 95/Jan/10 */ nansified++; /* count how many we did this way */ } /* if (bWindowsFlag != 0) */ else { /* for (k = 0; k < fontchrs; k++) strcpy(charnames[k], standardencoding[k]); */ copyencoding(charnames, standardencoding, fontchrs); /* 93/Nov/15*/ missingchars(wantchrs, "standard"); /* TEST 95/July/15 */ writeencoding(output, wantchrs, syntheticflag, "standard"); } /* writeencoding(output, wantchrs, syntheticflag); */ /* ??? */ } /* end of StandardEncoding case (unremapped) */ else { /* font was not using StandardEncoding (unremapped) */ standard = 0; if(sscanf(line, "/Encoding %d array", &nvec) < 1) { sprintf(logline, " Don't understand encoding vector: %s", line); showline(logline, 1); extgiveup(9); return -1; } /* fontchrs = nvec; */ /* can we trust this ? NO better not */ /* task = "reading Encoding"; */ k = extgetrealline(input, line); /* have to ignore "0 1 255 {1 index exch /.notdef put} for" line */ if (sscanf(line, "%d 1 %d {", &ns, &ne) < 2) { /* maybe no need to complain ? */ showline(" No /.notdef line", 1); } else k = extgetrealline(input, line); /* 92/02/04 */ /* grabbed next line (or hung onto this, if NOT /.notdef line) */ /* clear out charnames - background of blanks */ /* for (k = 0; k < MAXCHRS; k++) strcpy(charnames[k], ""); */ /* for (k = 0; k < MAXCHRS; k++) *charnames[k] = '\0';*//* 92/02/04 */ cleanencoding(0, MAXCHRS); /* 93/Nov/15 */ task = "reading Encoding"; /* k = extgetrealline(input, line); */ /* 92/02/04 now done above */ /* while (strstr(line, " def") == NULL) */ /* scan encoding - ends on "readonly def" usually */ /* new tokenized version follows */ gobbleencoding(input); /* writeencoding(output, wantchrs, syntheticflag); */ /* ??? */ missingchars(wantchrs, ""); /* NEW TEST 95/July/15 */ writeencoding(output, wantchrs, syntheticflag, ""); } /* Finished with NOT StandardEncoding case */ } /* finish with non-remapped font case */ else { /* now for what to do if non-resident font remapped C_REMAPIT */ if (verboseflag) { // putc('^', stdout); // if (logfileflag) putc('^', logfile); showline("^", 0); } /* first flush old encoding vector */ if (strstr(line, "StandardEncoding") == NULL) { /* scan encoding - ends on "readonly def" usually */ /* has to ignore "0 1 255 {1 index exch /.notdef put} for" line */ /* skip over encoding in font - ignore it totally */ /* Encoding ends with token `def' or `readonly' */ /* and token `def' and `readonly should not occur in Encoding */ while ((strstr(line, "def") == NULL || strstr(line, "put") != NULL) && k >= 0) { /* NEW 1991/11/23 */ k = extgetrealline(input,line); } } readencoding(vector); /* read desired encoding */ /* writeencoding(output, wantchrs, syntheticflag); */ missingchars(wantchrs, vector); /* NEW TEST 95/July/15 */ writeencoding(output, wantchrs, syntheticflag, ""); } /* end of dealing with encoding vector */ /* if (traceflag) showencoding(stdout); */ task = "copying font dict up to eexec"; k = extgetrealline(input, line); while (strstr(line, "eexec") == NULL && k >= 0) { /* copy up to eexec */ syntheticflag = parseline(line, output, syntheticflag, mtmiflag); k = extgetrealline(input, line); } // fputs(line, output); /* 1992/July/18 */ PSputs(line, output); /* 1992/July/18 */ if (bSubRealName == 0) { /* 95/Aug/22 */ /* we don't normally come here these days ... */ // strcpy(subfontname + fn * MAXFONTNAME, realfontname); if (subfontname[fn] != NULL) free(subfontname[fn]); subfontname[fn] = zstrdup(realfontname); /* if we are going to use the PS FontName here we'll need it later */ } if (k == EOF) { /* NEW */ showline(" Premature EOF", 1); showline(" in font file", 1); errcount(0); return -1; /* NEW --- shouldn't happen ! */ } /* Problem: what if syntheticflag set, but stripflag also set !!! */ if (syntheticflag != 0 || mtmiflag != 0) { /* pretty much just expand PFB to PFA */ /* copyfont(output, input, i, mtmiflag, stripflag); */ copyfont(output, input, fn, mtmiflag, stripflag); return 1; } cryptin = REEXEC; cryptout = REEXEC; clm = 0; // important for outencrypt task = "entering encrypted section"; c = getc(input); while (c <= ' ' && c > 0) c = getc(input); /* skip over white space */ if (c == 128) { /* see whether .pfb input format */ binaryin = 1; c = getc(input); if (c != 2) { sprintf(logline, " Expecting %s, not %d", "binary section code", c); showline(logline, 1); extgiveup(5); return -1; } len = readlength(input); } else if (c == 0) { /* see whether Mac binary input format */ binaryin = 1; (void) ungetc(c, input); len = maclength(input); c = getc(input); if (c != 2) { sprintf(logline, " Expecting %s, not %d", "Mac binary section code", c); showline(logline, 1); /* shownext(input); */ extgiveup(5); return -1; } c = getc(input); if (c != 0) { sprintf(logline, " Invalid Mac Binary section code %d", c); showline(logline, 1); extgiveup(5); return -1; } len = len -2; } else if (c > 128) { /* see whether raw binary - totally flakey ! */ binaryin = 1; len = (1U << 31); /* conversion to unsigned long ... */ (void) ungetc(c, input); } else (void) ungetc(c, input); /* copying across the four random encoding bytes at start also */ n = getmagic(input, line); /* 1993/Sep/14 */ putenlinen(output, line, n); /* 1993/Sep/14 */ task = "looking for CharString dict"; n = getenline(input, line); while ((s = strstr(line, "/CharStrings")) == NULL) { /* Omit UniqueID if font remapped AND dviencoding in use */ if ((property & C_REMAPIT) != 0) { if (busedviencode != 0 && strstr(line, "/UniqueID") != NULL) { /* if (verboseflag) printf(" Stripping UniqueID"); */ n = getenline(input, line); continue; } } putenlinen(output, line, n); if (strstr(line, "/Subrs") != NULL) { copysubrs(output, input); /* may want to inject a spurious newline here ... */ /* printf("Old line %s", line); */ /* |- */ /* n = getenline(input, line); */ /* printf("New line %s", line); */ /* end noaccess put */ if (abortflag) return -1; } /* else */ n = getenline(input, line); /* check on possibility of Synthetic Font */ /* possibly suppress discarding of unwanted characters ? */ /* Synthetic fonts won't work when remapped ? */ /* ===> NOTE: this is in encrypted level <=== */ /* possibly have to deal differently with the ending ? */ /* need to transfer the rest of the font just as is because of byte count */ if (strstr(line, "FontDirectory") != NULL) { /* 1992/Aug/24 */ /* don't complain if already noted that it was synthetic ... */ if (syntheticsafe != 0 && syntheticflag == 0) { showline(" ERROR: use *synthetic* in sub file", 1); errcount(0); syntheticflag = -1; /* is it safe to do this now ? */ } /* else if (verboseflag) printf(" synthetic"); */ } if (strstr(line, "hires") != NULL) { /* 1993/Jan/17 */ if (hybridflag == 0) showline(" hybrid", 0); /* first time */ hybridflag++; } /* if (traceflag) printf("LINE: %s", line); */ } if (strncmp(line, "2 index", 7) == 0) fontform = 2; /* new form */ else if (strncmp(line, "dup", 3) == 0) fontform = 1; /* old form */ else fontform=0; /* not recognized */ if (sscanf(s, "/CharStrings %d%n", &nchrs, &n) < 1) { putenline(output, line); /* 1993 Aug 5 - allow line split */ n = getenline(input, line); s = line; if (strstr(line, "dict dup") == NULL || sscanf(s, "%d%n", &nchrs, &n) < 1) { sprintf(logline, " Don't understand CharStrings line: %s", line); showline(logline, 1); extgiveup(2); return -1; } } else { /* normal case: /CharString dict dup on line */ *(s+13) = '\0'; /* terminate after `/CharStrings' */ putenline(output, line); /* start of modified /CharString line */ } /* *s = '\0'; */ /* terminate before /CharStrings */ /* putenline(output, line); */ /* start of modified /CharString line */ charagain: /* 1993 Aug 5 - hybrid font loop */ if (accentedflag != 0) { /* need to redo the count */ count = 0; /* if accented characters allowed */ for (k = 0; k < MAXCHRS; k++) if (wantchrs[k] != 0) count++; } if (wantnotdef != 0) count++; /* if (count > MAXCHRS) count = MAXCHRS; */ /* notdef ??? */ if (syntheticflag != 0) count = nchrs; /* 1992/Aug/22 */ nchrs = count; /* count of desired characters */ /* nchrs=0; */ /* for (k=0; k < fontchrs; k++) if (wantchrs[k] != 0) nchrs++; */ /* if (wantnotdef != 0) nchrs++; */ /* sprintf(line, "/CharStrings %d", nchrs); */ sprintf(line, "%d", nchrs); /* 1993 Aug 5 */ putenline(output, line); /* middle of modified /CharString line */ *(s+n) = ' '; /* fix up, in case it became `\0' */ putenline(output, s + n); /* end of modified /CharString line */ task = "scanning CharStrings"; chrs = 0; /* not used ? 95/Oct/28 */ /* for (k = 0; k < MAXCHRS; k++); charseen[k] = 0; *//* do earlier ??? */ for (k = 0; k < MAXCHRS+1; k++) charseen[k] = 0; /* fix 1992/Aug/21 */ for(;;) { if (getcharline(line, input, 0) != 0) break; /* the token "end" indicates the end of the CharString section */ if (sscanf(line, "/%s %d %n", charname, &nbin, &n) < 2) { sprintf(logline, " Not a CharString line: %s", line); showline(logline, 1); /* fprintf(errout, " charname %s, nbin %d, n %d", charname, nbin, n); n = sscanf(line, "/%s %d %n", &charname, &nbin, &n); fprintf(errout, " found only %d items in %d chars, first %d ! ", n, strlen(line), (int) *line); */ if (getcharline(line, input, 0) != 0) break; errcount(0); /* a little risky going on here ? */ /* extgiveup(9); */ /* or, just flush THIS file ? */ } /* assert(strlen(charname) < MAXCHARNAME); */ /* if (strlen(charname) >= MAXCHARNAME) fprintf(errout, " char name %s too long", charname); */ /* flushed 93/Nov/15 */ /* possibly check here whether syntheticflag is set ??? */ /* in that case just transfer all characters */ /* 1992/Aug/22 */ /* shouldn't this depend on whether we used StandardEncoding ? */ /* k = wantthisname(charname, chrs, wantchrs); */ guess = -1; /* single character charnames equal their char code 95/Oct/28 */ if (*(charname+1) == '\0') guess = *charname; k = wantthisname(charname, guess, wantchrs); if (k >= 0 || syntheticflag != 0) { /* 1992/Aug/22 */ /* if (k < 0 || k >= MAXCHRS) fprintf(errout, "Way out of range k %d ", k); else */ /* charseen[k] = 1; */ /* new - so can tell which missing */ if (syntheticflag != 0) k = NOTDEF; /* prevent error */ else charseen[k]++; /* new - so can tell which missing */ /* debugging only */ /* for dviencoding, change name to numeric code, unless its .notdef */ if (busedviencode != 0 && k != NOTDEF) { /* change charname */ if (strstr(line + n, "RD") != NULL) /* overwrite */ sprintf(line, "/a%d %d RD ", k, nbin); else sprintf(line, "/a%d %d -| ", k, nbin); } /* above assumes using either RD or -| ??? */ putenline(output, line); /* beginning of character */ copycharstring(output, input, nbin); /* printf("%d ", k); */ /* debugging */ /* this may not be accurate if repeated encoding and both char codes used .. */ count--; /* how many we extracted so far */ /* debugging only */ /* if (count == 0 && breakearly != 0 && fontform != 0) break; */ } else flushcharstring(input, nbin); chrs++; /* not used ? 95/Oct/28 */ if (bAbort) abortjob(); /* 1992/Nov/24 */ if (abortflag) return -1; } /* believe that count should be zero here ! */ if (count > 0) { /* 1994/Jan/30 */ /* first check whether `missing' characters appear twice in encoding */ /* this is important now that we use TEXANSI and extend encoding at bottom */ /* can only be equal to character lower in code, so don't start at zero */ for (k = 1; k < MAXCHRS; k++) { /* check the suspects */ if ((wantchrs[k] != 0) && (charseen[k] == 0)) { /* don't play with characters that have no names ! 96/May/26 */ if (strcmp(charnames[k], "") == 0) continue; for (l = 0; l < k; l++) { /* does it appear earlier */ /* don't play with characters that have no names ! 96/May/26 */ if (strcmp(charnames[l], "") == 0) continue; if (strcmp(charnames[k], charnames[l]) == 0) { charseen[k]++; count--; break; } } } } } if (count > 0) { /* fprintf(errout, " %d characters (out of %d) not found: ", count, nchrs); */ sprintf(logline, " %d character%s (out of %d) not found: ", count, (count == 1) ? "" : "s", nchrs); showline(logline, 1); /* fprintf(errout, "fontchrs: %d ", fontchrs); */ for (k = 0; k < MAXCHRS; k++) { /* list the bad ones */ if ((wantchrs[k] != 0) && (charseen[k] == 0)) { /* characters may have no names if not in encoding 96/May/26 */ /* fprintf(errout, " %s (%d)", charnames[k], k); */ if (strcmp(charnames[k], "") != 0) sprintf(logline, " %s (%d)", charnames[k], k); else sprintf(logline, " (%d)", k); /* 96/May/26 ? */ showline(logline, 1); } /* debugging only */ /* if ((wantchrs[k] != 0) && (charseen[k] != 0)) { fprintf(errout, " %s [%d]", charnames[k], k); } */ } errcount(0); /* ??? */ } chrs = -1; task = "copying end of CharString dict def"; putenline(output, line); /* copy beginning of end line */ n = getenline(input, line); /* copy rest of line */ putenline(output, line); /* 1993 August 5 - deal with `hybrid' font - second set of CharStrings */ /* if (strncmp(line, "hires", 5) == 0) { */ if (strstr(line, "hires") != NULL) { /* 1994/July/15 */ n = getenline(input, line); /* get potential dict dup line */ s = line; if (strstr(line, "dict dup") != NULL && sscanf(s, "%d%n", &nchrs, &n) == 1) goto charagain; if ((s = strstr(line, "dict dup")) != NULL) { /* 1994/July/15 */ while (s > line && *(s-1) == ' ') s--; while (s > line && *(s-1) > ' ') s--; /* Try and step back */ if (sscanf(s, "%d%n", &nchrs, &n) == 1) { /* printf("CHARSTRING: %s", s); */ /* debugging */ *s = '\0'; /* terminate after `/CharStrings' */ putenline(output, line); /* start modified /CharString line */ goto charagain; } } } else n = getenline(input, line); /* copy /FontName line */ /* if by mistake we wade into second /CharStrings of hybrid font, following */ /* goes wrong because it copies binary stuff and treats 0 char as end string */ task = "copying end of font dict def"; /* n = getenline(input, line); */ /* copy /FontName line */ while (strstr(line, "closefile") == NULL) { putenline(output, line); n = getenline(input, line); } putenline(output, line); flushencrypt(output); // ??? /* A problem here if the font has junk at the end of binary section ... */ /* Will this `fix' screw up treatment of Mac fonts ? */ #ifdef IGNORED if (stripbadend) { c = getc(input); /* eat spurious zeros if needed */ while (c == 0) c = getc(input); /* 95/Mar/1 */ (void) ungetc(c, input); /* turn these into ASCII zeros ? */ } #endif /* 96/Feb/22 deal with junk at end of encrypted section */ /* Looking for M-@C-A (ASCII section heading) for PFB */ /* Looking for EOL for PFA */ /* Looking for C-@C-B for Mac */ if (bStripBadEnd) { long current = ftell(input); c = getc(input); while (c != 128 && c != '0' && c != 0 && c >= ' ') { sprintf(logline, " JUNK %d (%c) at byte %ld", c, c, current); showline(logline, 1); current = ftell(input); c = getc(input); } /* putc(c, output); */ /* ??? */ ungetc(c, input); /* ??? */ } /* task = "adding zeros & cleartomark"; */ task = "copying ASCII section at end"; /* putzeros(output, nestedflag); */ /* add zeros at end */ c = getc(input); if (c != '\n') (void) ungetc(c, input); /* ??? */ // putc('\n', output); /* for PFB not for PFA ? */ PSputc('\n', output); /* for PFB not for PFA ? */ while (extgetline(input, line) != EOF) { /* new way to finish off */ /* fputs(line, output); */ /* Try and strip out that old Adobe crap checking for existing font ! */ /* Also junk in Fontographer style fonts */ /* 1992/Aug/21 */ /* Used in Courier, Helvetica for example */ /* if (stripchecking != 0 && syntheticflag == 0) { */ if (stripchecking != 0) { if ((s = strstr(line, "{restore}")) != NULL) { stripflag--; if ((t = strstr(line, "cleartomark")) != NULL) { *s++ = '\n'; *s++ = '\0'; /* cut off after cleartomark */ // fputs(line, output); /* 1992/Aug/20 */ PSputs(line, output); /* 1992/Aug/20 */ } if (stripcomment == 0) { /* 1995/May/14 */ // fputs("% font wrapper removed\n", output); PSputs("% font wrapper removed\n", output); } continue; } } // fputs(line, output); PSputs(line, output); } endresource(output); /* share some code */ if (stripflag != 0) showline(" WARNING: broken wrapper ", 1); /* 1992/Oct/7 */ return 1; /* indicate success */ } /* This is very specific for output from PKTOPS */ /* Does not provide for encoding vector */ /* Does not provide for remapping */ /* First cues on `cleartomark' after encrypted stuff */ /* (OR: cues on second line that starts with "}def" if unencrypted */ /* Then cues on `definefont' at end of font */ /* returns 0 if failed right away */ /* int extracttype3(FILE *output, FILE *input, int i) { */ int extracttype3 (FILE *output, FILE *input, int i, char *fontnamek) { int nchar, copyflag, endflag, count; char *s; char *wantchrs; if (verboseflag) { /* printf("%s", fontnamek); */ /* 1995/Mar/1 */ showline(fontnamek, 0); } else { /* putc('*', stdout); */ /* 1995/Mar/1 */ showline("*", 0); } // wantchrs = fontchar + MAXCHRS * i; wantchrs = fontchar[i]; if (wantchrs == NULL) showline(" BAD wantchrs", 1); /* property = fontproper[i]; */ /* vector = fontvector[i]; */ (void) getline(input, line); if (*line != '%' || *(line + 1) != '!') { showline(" Nonstandard font file start: ", 1); showline(line, 1); errcount(0); } if (strstr(line, "Type1") != NULL || strstr(line, "Font-1") != NULL) { type3flag = 0; /* well, maybe let try Type 1 then ! */ rewind(input); return 0; /* indicate lack of success */ } if (verboseflag) showline(" BITMAP", 0); if (stripcomment == 0) { beginresource(output, filefontname); /* share code */ // fputs(line, output); PSputs(line, output); if (wantcreation != 0) { (void) getline(input, line); if (*line != '%' || strncmp(line, "%%CreationDate", 14) == 0) // fputs(line, output); PSputs(line, output); } } /* fprintf(output, "%s", line); */ count = 0; /* number of lines starting with "}def" seen so far */ for(;;) { if (getrealline(input, line) == 0) { sprintf(logline, " Unexpected EOF (%s)\n", "extracttype3"); showline(logline, 1); errcount(0); break; /* was: return -1; */ } if (strstr(line, "serverdict") == NULL) { /* omit serverdict line ! */ // fputs(line, output); PSputs(line, output); } if (strstr(line, "cleartomark") != NULL) break; /* end preamble ? */ if (strncmp(line, "}def", 4) == 0) { /* end preamble ? */ if (count++ >= 1) break; } } /* now copy across character bitmaps */ for (;;) { endflag = 0; /* set when `definefont' seen ... */ for (;;) { if (getrealline(input, line) == 0) { /* EOF */ endflag = 1; break; } if (*line == '/') { /* replace fontname ??? */ if ((s = strstr(line, "/FontName")) != NULL) { /* if (sscanf(s, "/FontName /%s", realfontname) > 0) */ s += 9; /* step over `/FontName' */ while (*s != '/' && *s != '\0') s++; /* 1993/Aug/15 */ if (sscanf(s, "/%s", realfontname) > 0) { lowercase(realfontname, realfontname); /* why ? */ } /* check whether TeX font */ /* code inserted 1996/May/20 */ texfont = 0; /* 1992/Dec/22 */ if (istexfont(realfontname) != 0) { /* also check if actually one of 75 TeX fonts (what about LATEX, SliTeX) ? */ texfont = 1; standard = 0; } if (bSubRealName != 0) { /* we normally do this these days ... */ /* replaced following single line by code for prefix 96/May/20 ... */ /* sprintf(line, "/FontName /%s def\n", filefontname); */ strcpy(line, "/FontName /"); /* look at fontprefix here also */ // if (strcmp(fontprefix, "") != 0) if (fontprefix != NULL) strcat(line, fontprefix); if (uppercaseflag != 0 && texfont != 0) uppercase(filefontname, filefontname); /* if(_stricmp(filefontname, realfontname) == 0) strcpy(filefontname, realfontname); */ /* ??? */ strcat(line, filefontname); strcat(line, " def\n"); /* down to here */ } } else break; } /* else break; */ // fputs(line, output); PSputs(line, output); if (strstr(line, "definefont") != NULL) { /* end of font */ endflag = 1; break; } } if (endflag != 0) { /* printf(" found definefont"); /* debugging */ break; } /* presently assuming simple numeric code - no encoding vector */ if (sscanf(line, "/a%d ", &nchar) == 1) { copyflag = wantchrs[nchar]; /* printf(" (%d %d)", nch