1 /* Copyright 1990,1991,1992,1993,1994,1995,1996,1997,1998,1999 Y&Y, Inc.
2 Copyright 2007 TeX Users Group
3 Copyright 2014 Clerk Ma
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 /**********************************************************************
22 * Program for decompressing and extracting font files in PFA & PFB format
24 **********************************************************************/
28 #define ZEROS 512 /* 512 zeros required at end of eexec section */
29 #define ZEROSPERLINE 64 /* 64 zeros per line for safety */
30 #define NOTDEF 256 /* special code for .notdef = MAXCHRS */
32 #define COORDINATE "+" /* prefix for reencoded font 97/June/1 */
33 /* this has apparently not been finsihed */
35 unsigned short int cryptin; /* current seed for input decryption */
36 unsigned short int cryptout; /* current seed for output encryption */
38 char charseen[MAXCHRS + 1]; /* new - which CharStrings unpacked + NOTDEF */
40 int clm; /* current output column */
42 int binaryin = 0; /* non-zero => input binary, not hex */
44 int wantcreation=1; /* copy creation date through to output */
46 int aliasesexist=0; /* if *alias* found in font substitution file */
47 int syntheticsexist=0; /* if *synthetic* in font substitution file */
48 /* normally not set to avoid need to check table */
50 int type3flag = 0; /* non-zero => font file is PKTOPS output */
51 /* zero => font file is Adobe Type 1 style */
52 int mmflag=0; /* non-zero => Multiple Master Font 94/Dec/6 */
54 int pssflag = 0; /* non-zero => `font' file is PSS stub 94/Dec/6 */
55 int instanceflag = 0; /* non-zero => MM instanced via PFM 97/June/1 */
57 int fontform = 0; /* 0 => unrecog, 1 => old form, 2 => new form */
58 /* used only if breakearly is on - NOT USED */
59 int standard = 0; /* non-zero => StandardEncoding --- NOT USED */
60 int texfont = 0; /* non-zero => Tex font --- NOT USED */
62 int fontchrs = MAXCHRS; /* actual number of characters in font */
64 int hybridflag; /* 1993/Aug/5 */ /* made global 1994/July/15 */
66 int bBaseNameDone = 1; /* if zero, need not add BaseFontName anymore */
68 /* int stripbadend=0; */ /* for now 95/Mar/1 */
70 // static char filefontname[MAXFONTNAME]=""; /* from file name */
71 static char filefontname[FNAMELEN]=""; /* from file name */
72 static char realfontname[FNAMELEN]=""; /* from /FontName */
73 /* but first guess from %!PS line */
75 int chrs = -1; /* current character working on */
76 unsigned long len; /* counter of bytes in binary input */
78 /* Fonts, that --- in Oblique or Narrow form --- are synthetic: */
80 char *syntheticfonts[] =
89 "EuroStyle", /* added 97/Oct/23 */
90 "TektonMM", /* added 99/Apr/12 */
94 /* char *basecharacters="aceinousyzACEINOUSYZ"; *//* just basic 58 - Latin 1 */
96 /* char *basecharacters="aceinousyzACEINOUSYZdlrtDLRT";*/ /* ISO Latin 1 + 2 */
98 /* char *notbasecharacters="bfmpqvxBFMPQVX"; */ /* ??? */
100 /* font substitution table - obtained from file */
101 /* fontsubprop small enough to keep in near space - rest banished to far */
103 /* static int fontsubprop[MAXSUBSTITUTE]; *//* resident/forced/remapped/alias */
105 int fontsubprop[MAXSUBSTITUTE]; /* resident/forced/remapped/alias */
107 /* 1993/Nov/15 switches from fixed array to pointers into `namestring' */
109 /* static char charnames[MAXCHRS][MAXCHARNAME]; */ /* names read from encoding */
111 #define STRINGSPACE (MAXCHRS * MAXCHARNAME / 2)
113 /* The above comes to 4096 bytes - textext = 650, SE = 945, ANSI = 1528 */
115 char *charnames[MAXCHRS]; /* encoding vector 1993/Nov/15 */
117 char namestring[STRINGSPACE]; /* for encoding vector 1993/Nov/15 */
119 int stringindex; /* index into above space */
121 /* various encoding vectors needed */
123 /* is the following really needed ? YES, if font file Encoding is standard */
125 static char *standardencoding[] = {
126 "", "", "", "", "", "", "", "",
127 "", "", "", "", "", "", "", "",
128 "", "", "", "", "", "", "", "",
129 "", "", "", "", "", "", "", "",
130 "space", "exclam", "quotedbl", "numbersign", "dollar", "percent", "ampersand", "quoteright",
131 "parenleft", "parenright", "asterisk", "plus", "comma", "hyphen", "period", "slash",
132 "zero", "one", "two", "three", "four", "five", "six", "seven",
133 "eight", "nine", "colon", "semicolon", "less", "equal", "greater", "question",
134 "at", "A", "B", "C", "D", "E", "F", "G",
135 "H", "I", "J", "K", "L", "M", "N", "O",
136 "P", "Q", "R", "S", "T", "U", "V", "W",
137 "X", "Y", "Z", "bracketleft", "backslash", "bracketright", "asciicircum", "underscore",
138 "quoteleft", "a", "b", "c", "d", "e", "f", "g",
139 "h", "i", "j", "k", "l", "m", "n", "o",
140 "p", "q", "r", "s", "t", "u", "v", "w",
141 "x", "y", "z", "braceleft", "bar", "braceright", "asciitilde", "",
142 "", "", "", "", "", "", "", "",
143 "", "", "", "", "", "", "", "",
144 "", "", "", "", "", "", "", "",
145 "", "", "", "", "", "", "", "",
146 "nbspace", "exclamdown", "cent", "sterling", "fraction", "yen", "florin", "section",
147 "currency", "quotesingle", "quotedblleft", "guillemotleft", "guilsinglleft", "guilsinglright", "fi", "fl",
148 "", "endash", "dagger", "daggerdbl", "periodcentered", "", "paragraph", "bullet",
149 "quotesinglbase", "quotedblbase", "quotedblright", "guillemotright", "ellipsis", "perthousand", "", "questiondown",
150 "", "grave", "acute", "circumflex", "tilde", "macron", "breve", "dotaccent",
151 "dieresis", "", "ring", "cedilla", "", "hungarumlaut", "ogonek", "caron",
152 "emdash", "", "", "", "", "", "", "",
153 "", "", "", "", "", "", "", "",
154 "", "AE", "", "ordfeminine", "", "", "", "",
155 "Lslash", "Oslash", "OE", "ordmasculine", "", "", "", "",
156 "", "ae", "", "", "", "dotlessi", "", "",
157 "lslash", "oslash", "oe", "germandbls", "", "", "", "",
160 /* TeX text encoding vector - is this needed ? Yes, if can't find file */
162 /* If sharing character names, copy upper part from StandardEncoding */
165 static char *textext[TEXCHRS] =
167 "Gamma", "Delta", "Theta", "Lambda", "Xi", "Pi", "Sigma", "Upsilon",
168 "Phi", "Psi", "Omega", "ff", "fi", "fl", "ffi", "ffl",
169 "dotlessi", "dotlessj", "grave", "acute", "caron", "breve", "macron", "ring",
170 "cedilla", "germandbls", "ae", "oe", "oslash", "AE", "OE", "Oslash",
174 static char *textext[TEXCHRS] =
176 "Gamma", "Delta", "Theta", "Lambda", "Xi", "Pi", "Sigma", "Upsilon",
177 "Phi", "Psi", "Omega", "ff", "fi", "fl", "ffi", "ffl",
178 "dotlessi", "dotlessj", "grave", "acute", "caron", "breve", "macron", "ring",
179 "cedilla", "germandbls", "ae", "oe", "oslash", "AE", "OE", "Oslash",
180 "suppress", "exclam", "quotedblright", "numbersign", "dollar", "percent", "ampersand", "quoteright",
181 "parenleft", "parenright", "asterisk", "plus", "comma", "hyphen", "period", "slash",
182 "zero", "one", "two", "three", "four", "five", "six", "seven",
183 "eight", "nine", "colon", "semicolon", "exclamdown", "equal", "questiondown", "question",
184 "at", "A", "B", "C", "D", "E", "F", "G",
185 "H", "I", "J", "K", "L", "M", "N", "O",
186 "P", "Q", "R", "S", "T", "U", "V", "W",
187 "X", "Y", "Z", "bracketleft", "quotedblleft", "bracketright", "circumflex", "dotaccent",
188 "quoteleft", "a", "b", "c", "d", "e", "f", "g",
189 "h", "i", "j", "k", "l", "m", "n", "o",
190 "p", "q", "r", "s", "t", "u", "v", "w",
191 "x", "y", "z", "endash", "emdash", "hungarumlaut", "tilde", "dieresis"
195 /* "grave", "acute", "circumflex", "tilde", */
196 /* "macron", "breve", "dotaccent", "dieresis", */
197 /* "ring", "cedilla", "hungarumlaut", "ogonek", */
198 /* "caron", "dotlessi", "", "" */
200 /* If sharing character names, copy lower part from StandardEncoding */
202 /* NOTE: has non-standard added positions `dotlessi' 157 `caron' 141 */
204 /* NOTE: if env var ENCODING set then *that* vector is used instead */
205 /* it is read in and overrides this Windows ANSI encoding */
207 /* SHAREENCODING means we copy over some pointers to save memory */
208 /* We might consider reading this one in from disk if needed */
209 /* Now that we may not be using it if ENCODING env var is set */
212 static char *ansiencoding[256] =
214 "", "", "", "", "", "", "", "",
215 "", "", "", "", "", "", "", "",
216 "", "", "", "", "", "", "", "",
217 "", "", "", "", "", "", "", "",
218 "", "", "", "", "", "", "", "",
219 "", "", "", "", "", "", "", "",
220 "", "", "", "", "", "", "", "",
221 "", "", "", "", "", "", "", "",
222 "", "", "", "", "", "", "", "",
223 "", "", "", "", "", "", "", "",
224 "", "", "", "", "", "", "", "",
225 "", "", "", "", "", "", "", "",
226 "", "", "", "", "", "", "", "",
227 "", "", "", "", "", "", "", "",
228 "", "", "", "", "", "", "", "",
229 "", "", "", "", "", "", "", "",
230 "", "", "quotesinglbase", "florin", "quotedblbase", "ellipsis", "dagger", "daggerdbl",
231 "circumflex", "perthousand", "Scaron", "guilsinglleft", "OE", "caron", "", "",
232 "", "quoteleft", "quoteright", "quotedblleft", "quotedblright", "bullet", "endash", "emdash",
233 "tilde", "trademark", "scaron", "guilsinglright", "oe", "dotlessi", "", "Ydieresis",
234 "nbspace", "exclamdown", "cent", "sterling", "currency", "yen", "brokenbar", "section",
235 "dieresis", "copyright", "ordfeminine", "guillemotleft", "logicalnot", "hyphen", "registered", "macron",
236 "degree", "plusminus", "twosuperior", "threesuperior", "acute", "mu", "paragraph", "periodcentered",
237 "cedilla", "onesuperior", "ordmasculine", "guillemotright", "onequarter", "onehalf", "threequarters", "questiondown",
238 "Agrave", "Aacute", "Acircumflex", "Atilde", "Adieresis", "Aring", "AE", "Ccedilla",
239 "Egrave", "Eacute", "Ecircumflex", "Edieresis", "Igrave", "Iacute", "Icircumflex", "Idieresis",
240 "Eth", "Ntilde", "Ograve", "Oacute", "Ocircumflex", "Otilde", "Odieresis", "multiply",
241 "Oslash", "Ugrave", "Uacute", "Ucircumflex", "Udieresis", "Yacute", "Thorn", "germandbls",
242 "agrave", "aacute", "acircumflex", "atilde", "adieresis", "aring", "ae", "ccedilla",
243 "egrave", "eacute", "ecircumflex", "edieresis", "igrave", "iacute", "icircumflex", "idieresis",
244 "eth", "ntilde", "ograve", "oacute", "ocircumflex", "otilde", "odieresis", "divide",
245 "oslash", "ugrave", "uacute", "ucircumflex", "udieresis", "yacute", "thorn", "ydieresis"
248 static char *ansiencoding[] =
250 "", "", "", "", "", "", "", "",
251 "", "", "", "", "", "", "", "",
252 "", "", "", "", "", "", "", "",
253 "", "", "", "", "", "", "", "",
254 "space", "exclam", "quotedbl", "numbersign", "dollar", "percent", "ampersand", "quotesingle",
255 "parenleft", "parenright", "asterisk", "plus", "comma", "hyphen", "period", "slash",
256 "zero", "one", "two", "three", "four", "five", "six", "seven",
257 "eight", "nine", "colon", "semicolon", "less", "equal", "greater", "question",
258 "at", "A", "B", "C", "D", "E", "F", "G",
259 "H", "I", "J", "K", "L", "M", "N", "O",
260 "P", "Q", "R", "S", "T", "U", "V", "W",
261 "X", "Y", "Z", "bracketleft", "backslash", "bracketright", "asciicircum", "underscore",
262 "grave", "a", "b", "c", "d", "e", "f", "g",
263 "h", "i", "j", "k", "l", "m", "n", "o",
264 "p", "q", "r", "s", "t", "u", "v", "w",
265 "x", "y", "z", "braceleft", "bar", "braceright", "asciitilde", "",
266 "", "", "quotesinglbase", "florin", "quotedblbase", "ellipsis", "dagger", "daggerdbl",
267 "circumflex", "perthousand", "Scaron", "guilsinglleft", "OE", "caron", "", "",
268 "", "quoteleft", "quoteright", "quotedblleft", "quotedblright", "bullet", "endash", "emdash",
269 "tilde", "trademark", "scaron", "guilsinglright", "oe", "dotlessi", "", "Ydieresis",
270 "nbspace", "exclamdown", "cent", "sterling", "currency", "yen", "brokenbar", "section",
271 "dieresis", "copyright", "ordfeminine", "guillemotleft", "logicalnot", "hyphen", "registered", "macron",
272 "degree", "plusminus", "twosuperior", "threesuperior", "acute", "mu", "paragraph", "periodcentered",
273 "cedilla", "onesuperior", "ordmasculine", "guillemotright", "onequarter", "onehalf", "threequarters", "questiondown",
274 "Agrave", "Aacute", "Acircumflex", "Atilde", "Adieresis", "Aring", "AE", "Ccedilla",
275 "Egrave", "Eacute", "Ecircumflex", "Edieresis", "Igrave", "Iacute", "Icircumflex", "Idieresis",
276 "Eth", "Ntilde", "Ograve", "Oacute", "Ocircumflex", "Otilde", "Odieresis", "multiply",
277 "Oslash", "Ugrave", "Uacute", "Ucircumflex", "Udieresis", "Yacute", "Thorn", "germandbls",
278 "agrave", "aacute", "acircumflex", "atilde", "adieresis", "aring", "ae", "ccedilla",
279 "egrave", "eacute", "ecircumflex", "edieresis", "igrave", "iacute", "icircumflex", "idieresis",
280 "eth", "ntilde", "ograve", "oacute", "ocircumflex", "otilde", "odieresis", "divide",
281 "oslash", "ugrave", "uacute", "ucircumflex", "udieresis", "yacute", "thorn", "ydieresis"
285 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
287 int mmcount; /* how many MM base fonts added */
289 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
291 /* Stuff for initializing resident encoding vectors - to save memory */
293 void initializeencoding(int ansitexflag)
297 for (k = 33; k < 123; k++)
298 textext[k] = standardencoding[k];
299 /* now for the fixups */
300 /* textext[32] = "suppress"; */
301 textext[34] = standardencoding[186]; /* "quotedblright" */
302 textext[60] = standardencoding[161]; /* "exclamdown" */
303 textext[62] = standardencoding[191]; /* "questiondown" */
304 textext[92] = standardencoding[170]; /* "quotedblleft" */
305 textext[94] = standardencoding[195]; /* "circumflex" */
306 textext[95] = standardencoding[199]; /* "dotaccent" */
307 textext[123] = standardencoding[177]; /* "endash" */
308 textext[124] = standardencoding[208]; /* "emdash" */
309 textext[125] = standardencoding[205]; /* "hungarumlaut" */
310 textext[126] = standardencoding[196]; /* "tilde" */
311 textext[127] = standardencoding[200]; /* "dieresis" */
312 for (k = 32; k < 128; k++) ansiencoding[k] = standardencoding[k];
313 ansiencoding[39] = standardencoding[169]; /* "quotesingle" */
314 ansiencoding[96] = standardencoding[193]; /* "grave" */
315 /* copy over accents for Adobe Level 1 PS interpreter bug as in PSCRIPT */
316 /* for (k = 0; k < 15; k++) ansiencoding[k] = standardencoding[k+193]; */
317 /* ansiencoding[15] = standardencoding[245]; *//* dotlessi*/
319 /* copy over accents for Adobe Level 1 PS interpreter bug as in PSCRIPT */
320 /* actually, mostly we just need `caron', `dotlessi' and maybe `ring' ... */
323 for (k = 0; k < 15; k++) ansiencoding[k] = standardencoding[k+193];
324 ansiencoding[15] = standardencoding[245]; /* dotlessi*/
326 if (ansitexflag) { /* or do this in PostScript later ??? 93/Dec/18 */
327 /* this had a bug that was fixed 93/Dec/28 */
328 /* strcpy(ansiencoding[0], ""); */ /* avoid grave repeat */
329 /* strcpy(ansiencoding[1], ""); */ /* avoid acute repeat */
330 /* strcpy(ansiencoding[4], ""); */ /* avoid macron repeat */
331 /* strcpy(ansiencoding[5], ""); */ /* avoid breve repeat */
332 /* strcpy(ansiencoding[9], ""); */ /* avoid ring repeat */
333 /* strcpy(ansiencoding[10], ""); */ /* avoid cedilla repeat */
334 /* strcpy(ansiencoding[14], ""); */ /* avoid caron repeat */
335 /* 0 - 10 Greek - not in ANSI */
336 /* 11 - 15 f ligatures - not in ANSI */
337 /* 16 - 17 dotlessi dotlessj - not ANSI */
338 /* 16 - 24 dotlessi, dotlessj, grave, acute, caron, breve, macron, ring, cedilla */
339 /* 25 - 31 germandbls, ae, oe, oslash, AE, OE, Oslash */
340 /* actually: dotlessj, caron, breve, - and ring - missing in ANSI */
341 for (k = 16; k < 32; k++) ansiencoding[k] = textext[k];
342 ansiencoding[17] = ""; /* flush `dotlessj' */
343 ansiencoding[21] = ""; /* flush `breve' */
344 /* but keep `caron' and `ring' for PS interpreter bug fix (not in ANSI) */
345 /* potential problem with some characters now being repeated higher up ? */
349 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
351 /* stuff for reading in AFM/TFM files and extracting metric information */
352 /* provides alternate of reading AFM file instead */
353 /* if file can't be found or read, don't adjust metric information */
355 /* graceful exit with suitable error message */
356 /* graceful exit with meaningful error message */
357 void extgiveup(int code)
363 sprintf(s, " while %s", task);
369 sprintf(s, " for character %d ", chrs);
373 if (*filefontname != '\0')
375 sprintf(s, " in font %s", filefontname);
379 strcat(logline, "\n");
380 showline(logline, 1);
382 checkexit(code); /* 1995/Oct/28 */
385 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
386 /* read four byte length code */
387 unsigned long readlength(FILE* input)
390 unsigned long n = 0L;
392 for (k=0; k < 4; k++)
395 n = n >> 8; n = n | ((unsigned long) c << 24);
399 /* read four byte length code */
400 unsigned long maclength(FILE *input)
403 unsigned long n = 0L;
405 for (k = 0; k < 4; k++) n = (n << 8) | getc(input);
409 int getnextnon(FILE *input)
413 if (c == '\r' && flushcr != 0)
418 (void) ungetc(c, input);
425 /* read a line up to newline (or return) */ /* returns EOF if at end of file */
427 int extgetline(FILE *input, char *buff)
432 c = getnextnon(input);
433 /* if (flushcr != 0) while (c == '\r') c = getc(input); */
435 if (c == EOF) return EOF;
436 if (c == 128) { /* flush over ASCII section headers */
439 if (c == 3) return EOF;
442 " Expecting %s, not %d", "ASCII section code", c);
443 showline(logline, 1);
447 len = readlength(input); /* read and ignore ! */
448 c = getnextnon(input);
449 if (c == EOF) return EOF; /* never */
450 if (c == '\n') break;
452 else if (c == 0) { /* Presumably Mac Style ASCII section code */
453 sprintf(logline, " AT BYTE %ld ", ftell(input)); /* debugging */
454 showline(logline, 0);
456 (void) ungetc(c, input);
457 len = maclength(input);
459 if (c == 5) return EOF;
461 sprintf(logline, " Expecting %s, not %d",
462 "Mac ASCII section code", c);
463 showline(logline, 1);
469 sprintf(logline, " Invalid Mac ASCII section code %d", c);
470 showline(logline, 1);
475 c = getnextnon(input);
476 if (c == EOF) return EOF; /* never */
477 /* if (c == '\r') c = '\n'; */
478 if (c == '\n') break;
480 *s++ = (char) c; k++;
482 showline(" Line too long in dviextra getline", 1);
483 /* extgiveup(6); */ /* flushed */
484 *(s-1) = '\0'; /* terminate the junk at least */
485 if (verboseflag) { /* 93/Aug/13 */
490 /* read to end of line (or EOF) before going on ? */
491 while ((c = getnextnon(input)) != '\n') {
492 if (c == EOF) return EOF;
494 errcount(0); /* 93/Aug/13 */
495 *buff = '\0'; /* flush this crap ! */
498 c = getnextnon(input); /* flush any returns */
500 *s++ = (char) c; k++; /* terminating '\n' */
505 /* hmm, return value of extgetrealline used to be never used ... */
506 /* get non-comment, non-blank */
507 int extgetrealline(FILE *input, char *buff)
510 k = extgetline(input, buff);
511 while ((*buff == '%' || *buff == '\n') && k >= 0)
512 k = extgetline(input, buff);
516 //////////////////////////////////////////////////////////////////////////////
518 int ksubst=0; // number of entries in substitution table
520 char *makespace (char *s, int ndes, int nact)
524 // for (k = nact; k < ndes; k++) putc(' ', output);
525 for (k = nact; k < ndes; k++) *s++ = ' ';
530 char *showproper (char *s, int proper)
532 if (proper == 0) return s;
533 if ((proper & C_RESIDENT) != 0) sprintf(s, "%s ", RESIDENT);
534 if ((proper & C_FORCESUB) != 0) sprintf(s, "%s ", FORCESUB);
535 /* if ((proper & C_REMAPIT) != 0) sprintf(s, "%s ", REMAPIT); */
536 if ((proper & C_ALIASED) != 0) sprintf(s, "%s ", ALIASED);
537 if ((proper & C_MISSING) != 0) sprintf(s, "*missing* ");
538 if ((proper & C_UNUSED) != 0) sprintf(s, "*unused* ");
539 /* if ((proper & C_DEPENDENT) != 0) sprintf(s, "*new-size* "); */
540 /* if ((proper & C_COMPOUND) != 0) sprintf(s, "%s ", COMPOUND); */
541 if ((proper & C_SYNTHETIC) != 0) sprintf(s, "%s ", SYNTHETIC);
542 if ((proper & C_MTMI) != 0) sprintf(s, "%s ", MTMI);
543 if ((proper & C_EPSF) != 0) sprintf(s, "%s ", EPSF); /* 94/Aug/15 */
544 if ((proper & C_DEPENDENT) != 0) sprintf(s, "*new-size* ");
545 if ((proper & C_REMAPIT) != 0) sprintf(s, "%s ", REMAPIT);
546 /* if ((proper & C_CONTROL) != 0) sprintf(s, "%s ", CONTROL); */
547 if ((proper & C_NOTBASE) != 0) sprintf(s, "*not-base* ");
548 return s + strlen(s);
552 void showsubtable(void)
556 // char oldname[MAXTEXNAME];
557 char oldname[FNAMELEN];
558 // char newname[MAXFONTNAME];
559 char newname[FNAMELEN];
560 // char vecname[MAXVECNAME]; /* 1994/Feb/4 */
561 char vecname[FNAMELEN];
563 showline("Font Substitution Table:\n", 0);
564 for (k = 0; k < ksubst; k++) {
565 // strcpy(oldname, fontsubfrom + k * MAXTEXNAME);
566 if (fontsubfrom[k] != NULL) strcpy(oldname, fontsubfrom[k]);
567 else *oldname = '\0';
568 // strcpy(newname, fontsubto + k * MAXFONTNAME);
569 if (fontsubto[k] != NULL) strcpy(newname, fontsubto[k]);
570 else *newname = '\0';
571 // strcpy(vecname, fontsubvec + k * MAXVECNAME);
572 if (fontsubvec[k] != NULL) strcpy(vecname, fontsubvec[k]);
573 else *vecname = '\0';
575 sprintf(s, "%3d %s ", k, oldname);
577 s = makespace(s, 10, strlen(oldname)); /* MAXTEXNAME ? */
578 sprintf(s, "=> %s ", newname);
580 s = makespace(s, 16, strlen(newname)); /* MAXFONTNAME ? */
581 s = showproper(s, fontsubprop[k]);
582 /* if (strcmp(fontsubvec[k], "") != 0)
583 fprintf(output, "vec: %s", fontsubvec[k]); */
584 if (strcmp(vecname, "") != 0) {
585 sprintf(s, "vec: %s", vecname);
588 // putc('\n', output);
590 showline(logline, 0);
592 // putc('\n', output);
596 /* recover TeX internal font number */
600 for (m = 0; m < MAXFONTNUMBERS; m++)
602 if (finx[m] == (short) k) return m;
603 // if (finx[m] == k) return m;
609 void showfonttable (void)
611 int k, flag, originalfont;
614 // char oldname[MAXTEXNAME];
615 char oldname[FNAMELEN];
616 // char newname[MAXFONTNAME];
617 char newname[FNAMELEN];
620 // fprintf(output, "Font Table:");
621 strcpy(s, "Font Table:");
624 sprintf(s, " (Magnification %lg)", (double) mag / 1000);
626 showline(logline, 0);
628 /* if (traceflag) printf("mmbase %d fnext %d\n", mmbase, fnext); */
629 for (k = 0; k < fnext; k++)
632 proper = fontproper[k];
633 /* do only if fontsubflag >= 0 ? */
634 /* do only if (proper & C_DEPENDENT) != 0 ? */
635 /* don't bother to list if unused */
636 /* if (proper & C_UNUSED) != 0) continue; *//* remove 94/Oct/6 */
637 sprintf(s, "%3d ", k);
639 originalfont = original(k); /* original TeX font number */
640 if (originalfont >= 0) sprintf(s, "(%3d) ", originalfont);
641 else s = makespace(s, 6, 0);
642 // strcpy(oldname, fontname + k * MAXTEXNAME);
643 if (fontname[k] != NULL) strcpy(oldname, fontname[k]);
644 else *oldname = '\0';
645 if (subfontname[k] != NULL) strcpy(newname, subfontname[k]);
646 else *newname = '\0';
647 // strcpy(newname, subfontname + k * MAXFONTNAME);
648 sprintf(s, "%s ", oldname);
650 s = makespace(s, 10, strlen(oldname));
651 if (strcmp(newname, "") != 0 && strcmp(oldname, newname) != 0) {
652 sprintf(s, "=> %s ", newname);
654 s = makespace(s, 16, strlen(newname));
656 atsize = (double) fs[k] * num / den * 72.27 / 254000;
657 /* possibly also * mag / 1000 ? NO */
658 /* if (atsize != 0.0) fprintf(output, "at:%6.6lg pt ", atsize); */
659 if (atsize != 0.0) sprintf(s, "at:%6.5lg pt ", atsize);
660 /* else if (originalfont < 0) fprintf(output, "base for remapped font "); */
661 /* else if (k >= mmbase) fprintf(output, "MM base font "); */
662 else if (proper & C_MULTIPLE) sprintf(s, "MM base font ");
663 else if (proper & C_INSTANCE) sprintf(s, "MM instance ");
664 else if (originalfont < 0) sprintf(s, "base for substitution ");
665 /* or Multiple Master base font 94/Dec/6 */
666 else s = makespace(s, 13, 0);
668 flag = fontsubflag[k];
669 if (flag >= 0) { /* follow substitution pointer */
670 sprintf(s, "base: %2d ", flag);
672 originalfont = original(flag);
673 if (originalfont >= 0) sprintf(s, "(%3d) ", originalfont);
674 else s = makespace(s, 6, 0);
677 s = showproper(s, proper); /* show properties */
680 // if (strcmp(fontvector[k], "") != 0)
681 // if (*(fontvector + k * MAXVECNAME) != '\0') {
682 if (fontvector[k] != NULL)
684 /* fprintf(output, "vec: %s", fontvector[k]); */
685 /* fprintf(output, "%s", fontvector[k]); */
686 // fputs(fontvector[k], output); /* 1992/July/18 */
687 strcat(s, fontvector[k]);
690 // putc('\n', output);
692 showline(logline, 0);
697 /* void showencoding (FILE *output) {
699 for (i = 0; i < fontchrs; i++)
700 fprintf(output, "%d: %s\n", i, charnames[i]);
701 } */ /* debugging only */
703 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
705 /* moved to dvipslog.c to avoid compiler bug ! 1995/May/25 */
707 /* int readtfm(char *, FILE *, long widths[]); */
708 /* int readafm(char *, FILE *, long widths[]); */
709 /* int readpfm(char *, FILE *, long widths[]); */
711 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
713 /* New common routine 1992/Nov/28 */
714 /* does not use backslash if beginning is blank or already ends on : \ or / */
716 void makefilename (char filepath[], char *fontname)
719 if (strcmp(filepath, "") != 0) { /* 1992/Oct/30 */
720 s = filepath + strlen(filepath) - 1;
721 if (*s != ':' && *s != '\\' && *s != '/') strcat(filepath, "\\");
723 strcat(filepath, fontname);
724 /* extension(filepath, ext); */
727 /* returns -1 if name was changed - returns 0 if name was not changed */
729 /* convert font file name to Adobe style */
730 int underscore (char *filename)
735 s = removepath(filename);
737 if ((t = strchr(s, '.')) == NULL) t = s + strlen(s);
741 /* printf("NO CHANGE IN %s\n", filename); */ /* debugging */
742 return 0; /* no change 95/May/28 */
744 memmove(s + 8, t, (unsigned int) (n - m + 1));
745 for (k = m; k < 8; k++) s[k] = '_';
749 /* removes underscores at end, assumes there is no file extension ... */
750 /* returns 0 if there were no underscores to remove - returns -1 otherwise */
752 /* remove Adobe style underscores */
753 int removeunder (char *filename)
756 s = filename + strlen(filename) - 1;
757 if (*s != '_') return 0; /* 95/May/28 */
758 while (*s == '_') s--;
759 *(s + 1) = '\0'; /* overwrite first underscore in seq */
763 /* Consolidated code for TFM, AFM, and PFM in one place 95/Mar/31 */
765 FILE *lookformetrics (char *font, char *extension, char *path)
767 char fn_met[FNAMELEN];
775 sprintf(logline, " Trying %s", path); /* debug 95/Mar/31 */
776 showline(logline, 0);
780 strcpy(fn_met, font);
781 forceexten(fn_met, extension);
782 fp_met = findandopen(fn_met, path, NULL, "rb", currentfirst);
783 if (fp_met == NULL && tryunderscore != 0)
785 /* underscore (fn_met); */
786 /* fp_met = findandopen(fn_met, path, NULL, "rb", currentfirst); */
787 if (underscore(fn_met)) /* 95/May/28 */
788 fp_met = findandopen(fn_met, path, NULL, "rb", currentfirst);
793 if ((searchpath=nextpathname(fn_met, searchpath)) == NULL) break;
794 makefilename(fn_met, font); /* 1992/Nov/28 */
795 forceexten(fn_met, extension);
796 if ((fp_met = fopen(fn_met, "rb")) == NULL) {
797 if (tryunderscore == 0) continue;
799 /* underscore(fn_met);
800 if ((fp_met = fopen(fn_met, "rb")) == NULL) continue;
801 else break; */ /* 1994/Aug/18 */
802 if (underscore(fn_met)) { /* 1995/May/28 */
803 if ((fp_met = fopen(fn_met, "rb")) != NULL) break;
808 else break; /* 1994/Aug/18 */
811 if (traceflag) { /* 1995/Mar/31 */
813 sprintf(logline, " Using %s", fn_met);
814 showline(logline, 0);
820 /* get character widths from .tfm or .afm or .pfm files - for substitution */
821 /* tfm is searched first because it is compact - hence fast */
822 /* pfm is searched last because widths are restricted to being integers */
823 /* returns max numeric code of character in metric info */
825 int readwidths (char *font, long widths[])
828 /* char fn_met[FNAMELEN]; */
831 /* char *searchpath; */
834 task = "looking for font metrics";
838 fp_met = lookformetrics(font, "tfm", tfmpath);
841 k = readtfm(font, fp_met, widths);
847 if (texfonts != NULL)
849 fp_met = lookformetrics(font, "tfm", texfonts);
852 k = readtfm(font, fp_met, widths);
860 fp_met = lookformetrics(font, "afm", afmpath);
863 k = readafm(font, fp_met, widths);
871 fp_met = lookformetrics(font, "pfm", pfmpath);
874 k = readpfm(font, fp_met, widths);
880 sprintf(logline, " WARNING: metrics not found for %s", font);
881 showline(logline, 1);
886 /* for remapping and substituting font names */
888 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
890 /* stuff for dealing with font file itself */
891 /* get next byte from input */
892 int nextbytein(FILE *input)
901 if (c != 0 && c != 128)
903 sprintf(logline, " Expecting %s, not %d", "binary length code", c);
904 showline(logline, 1);
908 if (c == 128) { /* PC .pfb file */
910 if (c == 1) { /* somewhat unexpected, but... */
911 len = readlength(input);
913 return nextbytein(input); /* try reading in ASCII */
916 sprintf(logline, " Expecting %s, not %d", "binary section code", c);
917 showline(logline, 1);
921 len = readlength(input);
922 /* if (traceflag) printf("Binary Section %lu\n", len); */
924 else { /* Mac style binary file c == 0 */
925 (void) ungetc(c, input);
926 len = maclength(input);
928 if (c == 1) { /* somewhat unexpected, but... */
930 return nextbytein(input); /* try reading in ASCII */
934 " Expecting %s, not %d", "Mac binary section code", c);
935 showline(logline, 1);
941 sprintf(logline, " Invalid Mac style binary record %d", c);
942 showline(logline, 1);
949 /* c = getc(input); */
950 if ((c = getc(input)) == EOF)
952 sprintf(logline, " Unexpected EOF (%s)\n", "nextbytein");
953 showline(logline, 1);
960 else { /* ASCII input */
962 while (c <= ' ' && c != EOF) c = getc(input);
964 sprintf(logline, " Unexpected EOF (%s)\n", "nextbytein");
965 showline(logline, 1);
969 if (c >= '0' && c <= '9') c = c - '0'; /* use table ? */
970 else if (c >= 'A' && c <= 'F') c = c - 'A' + 10;
971 else if (c >= 'a' && c <= 'f') c = c - 'a' + 10;
973 sprintf(logline, " Invalid hex character: %d", c);
974 showline(logline, 1);
979 while (d <= ' ' && d != EOF) d = getc(input);
981 sprintf(logline, " Unexpected EOF (%s)\n", "nextbytein");
982 showline(logline, 1);
986 if (d >= '0' && d <= '9') d = d - '0'; /* use table ? */
987 else if (d >= 'A' && d <= 'F') d = d - 'A' + 10;
988 else if (d >= 'a' && d <= 'f') d = d - 'a' + 10;
990 sprintf(logline, " Invalid hex character: %d", d);
991 showline(logline, 1);
999 /* stuff for encrypting and decrypting */
1001 unsigned char decryptbyte (unsigned char cipher, unsigned short *crypter)
1003 unsigned char plain;
1005 plain = (unsigned char) ((cipher ^ (unsigned char) (*crypter >> 8)));
1006 *crypter = (unsigned short) ((cipher + *crypter) * CRYPT_MUL + CRYPT_ADD);
1011 /* read byte and decrypt */
1012 unsigned char indecrypt(FILE *input)
1014 unsigned char cipher;
1015 unsigned char plain;
1017 cipher = (unsigned char) nextbytein(input);
1018 plain = (unsigned char) ((cipher ^ (unsigned char) (cryptin >> 8)));
1019 cryptin = (unsigned short) ((cipher + cryptin) * CRYPT_MUL + CRYPT_ADD);
1024 // rewritten for efficiency to not use putc but fputs
1025 // now accumulates a line of output in logline
1026 // assumes we are not using logline for something else...
1028 /* stuff for encrypted input and output */
1030 /* encrypt and write */
1031 void outencrypt(unsigned char plain, FILE *output)
1034 unsigned char cipher;
1035 char *s=logline+clm;
1037 /* cipher = (plain ^ (unsigned char) (cryptout >> 8)); */
1038 cipher = (unsigned char) ((plain ^ (unsigned char) (cryptout >> 8)));
1039 /* cryptout = (cipher + cryptout) * CRYPT_MUL + CRYPT_ADD; */
1040 cryptout = (unsigned short) ((cipher + cryptout) * CRYPT_MUL + CRYPT_ADD);
1043 c = (cipher >> 4) & 15;
1045 // putc(c + '0', output);
1046 // PSputc((char) (c+'0'), output);
1047 *s++ = (char) (c+'0');
1050 // putc(c + 'A' - 10, output);
1051 // PSputc((char) (c+'A'-10), output);
1052 *s++ = (char) (c+'A'-10);
1056 // putc(d + '0', output);
1057 // PSputc((char) (d+'0'), output);
1058 *s++ = (char) (d+'0');
1061 // putc(d+ 'A' - 10, output);
1062 // PSputc((char) (d+'A'-10), output);
1063 *s++ = (char) (d+'A'-10);
1066 if (clm >= columns) {
1067 // putc('\n', output);
1068 // PSputc('\n', output);
1071 PSputs(logline, output);
1076 void flushencrypt (FILE *output)
1078 char *s=logline+clm;
1082 PSputs(logline, output);
1087 /* 93/Sep/14 --- avoid using getenline for this in case ^M or ^J */
1088 /* get the magic encrypt start bytes */
1089 int getmagic(FILE *input, char *buff)
1093 for (k = 0; k < 4; k++) *s++ = (char) indecrypt(input);
1098 /* There shouldn't be any returns inside the encrypted part, just newlines */
1099 /* But some stupid fonts disobey this rule => turn return into newline */
1100 /* One problem: can't conveniently look ahead in encrypted part */
1101 /* This gets nasty if there are returns FOLLOWED newlines */
1102 /* so be prepared to see an isolated return or newline at start of line */
1104 /* read encrypted line */
1105 int getenline(FILE *input, char *buff)
1111 d = indecrypt(input);
1112 /* if (d == '\r') d = indecrypt(input); */ /* bkph - 91/10/1 */
1113 /* step over initial return/newline - remanants or blank lines */
1114 while (d == '\n' || d == '\r') d = indecrypt(input);
1116 *s++ = (char) d; k++;
1119 showline(" Line: ", 1);
1122 sprintf(logline, " too long in encrypted getline (> %d)", MAXLINE);
1123 showline(logline, 0);
1127 d = indecrypt(input);
1131 printf("RETURN AFTER: %s\n", buff); */
1132 /* d = indecrypt(input); */ /* bkph 91/10/1 */
1136 *s++ = (char) d; k++;
1138 /* if (traceflag) printf("IN: %s", buff); */
1142 // need to remember to flush out logline at end also ...
1144 /* This version assumes string is null terminated */
1145 /* write encrypted line */
1146 void putenline(FILE *output, char *buff)
1150 while ((d = *buff++) != '\0') {
1151 outencrypt((unsigned char) d, output);
1155 /* This version specifies length rather than null terminated */
1156 /* write encrypted line */
1157 void putenlinen(FILE *output, char *buff, int n)
1161 for (k = 0; k < n; k++) {
1163 outencrypt((unsigned char) d, output);
1167 /* used for reading "/charname n RD" for CharStrings */
1168 /* also used for reading "dup n m RD" for Subrs */
1169 /* normally returns zero, when hit end returns -1 */
1171 /* May want to distinguish Subrs and CharStrings case */
1172 /* because Subrs can end on "readonly def" */
1173 /* but that can occur in CharStrings ... */
1175 /* subrflag != 0 for Subrs reading added 93/Aug/13 */
1176 /* get encrypted tokens */
1178 /* reads until it hits RD, -|, end, ND, |-, noaccess def, readonly def */
1179 /* which may mean it reads past end of line ... */
1181 int getcharline(char *buff, FILE *input, int subrflag)
1184 char *t = buff, *s = buff;
1186 d = indecrypt(input); /* skip over initial white space */
1187 /* while (d == '\n' || d == '\r' || d == ' ') */
1188 while (d == '\n' || d == '\r' || d == ' ' || d == '\0') /* 98/Apr/20 */
1189 d = indecrypt(input);
1191 /* d = indecrypt(input); */
1193 if (verboseflag) printf("Unexpected end of line\n");
1198 if(strncmp(t, "RD", 2) == 0 ||
1199 strncmp(t, "-|", 2) == 0) { /* ready for binary bytes */
1201 return 0; /* start of binary section */
1203 else if ((strncmp(t, "end", 3) == 0) || /* end of CharStrings */
1204 (strncmp(buff, "ND", 2) == 0) || /* or end of Subrs */
1205 (strncmp(buff, "|-", 2) == 0)) { /* or end of Subrs */
1207 return -1; /* end of Subrs or CharStrings */
1209 /* 93 Aug 5 */ /* for Subrs only */
1210 else if (subrflag != 0 &&
1211 (strncmp(buff, "noaccess def", 12) == 0 ||
1212 /* 93 Aug 13 */ /* for Subrs only */
1213 strncmp(buff, "readonly def", 12) == 0)) {
1215 return -1; /* end of Subrs or CharStrings */
1217 else t = s; /* remember start of next token */
1219 /* else if (d == '\n') {
1220 if (verboseflag) printf("Unexpected end of line: %s\n", t);
1224 d = indecrypt(input);
1228 /* flush rest of CharString */
1229 void flushcharstring(FILE *input, int n)
1233 for (k = 0; k < n; k++) (void) indecrypt(input); /* flush binary part */
1234 d = indecrypt(input);
1236 d = indecrypt(input); /* flush ND or |- up to nl (or rt)*/
1237 if (d == '\r') d = '\n'; /* bkph 91/10/1 */
1241 /* copy CharString or Subr string */
1242 /* the fix may be slightly dicey since it may generate blank line at */
1244 void copycharstring(FILE *output, FILE *input, int n)
1246 int d, k; /* c, e */
1247 for (k = 0; k < n; k++) { /* copy binary CharString itself */
1248 d = indecrypt(input);
1249 outencrypt((unsigned char) d, output);
1251 d = indecrypt(input); /* default is to drop space before ND */
1253 if (d != ' ' || keepgap != 0) /* 1993 August 5 */
1254 outencrypt((unsigned char) d, output);
1256 while (d != '\n') { /* copy ND or | - up to nl (or rt)*/
1257 d = indecrypt(input);
1258 if (d == '\r') d = '\n'; /* bkph 91/10/1 */
1259 outencrypt((unsigned char) d, output);
1263 /* do we want char with this name ? */
1264 /* return negative if not - and character code if yes */ /* changed */
1266 /* Modified for now to keep on looking */ /* allow for multiple encoding ? */
1267 /* this will slow things down a bit, but be a lot safer ! */
1268 /* make sure charnames[] is cleaned out before encoding is read from font */
1270 /* int wantthisname(char *charname, int k, char wantchrs[]) { */
1271 int wantthisname (char *charname, int k, char *wantchrs)
1274 /* best guess first for speed: */
1275 /* if (strcmp(charnames[k], charname) == 0) { */ /* 95/Oct/28 */
1276 if (k >= 0 && k < MAXCHRS && strcmp(charnames[k], charname) == 0) {
1277 if (wantchrs[k] != 0) return k; /* nice and easy ! */
1278 /* else return -1; */ /* no, may occur again ... */
1279 } /* was return wantchrs[k]; */
1280 for (i = 0; i < fontchrs; i++) {
1281 if (strcmp(charnames[i], charname) == 0) {
1282 if (wantchrs[i] != 0) return i;
1283 /* else return -1; */ /* no, may occur again ... */
1284 } /* was return wantchrs[i]; */
1286 if (wantnotdef != 0 && strcmp(".notdef", charname) == 0) {
1290 printf("Character not in encoding: %s (%d)\n", charname, k); */
1294 /* Adobe PS interpreters yield `invalidfont' errors when */
1295 /* base or accent of composite character is not in encoding of font */
1296 /* May need to add more characters to basecharacterlist */
1297 /* use `N' command line argument to deactivate this bug work around */
1299 int copysubrs(FILE *output, FILE *input)
1302 /* char buffer[FNAMELEN]; */ /* compromise only for hires Subrs line */
1305 /* First check whether there are no Subrs ! */
1306 if (strstr(line, "ND") != NULL) return 0;
1307 if (strstr(line, "|-") != NULL) return 0;
1308 if (strstr(line, "noaccess def") != NULL) return 0;
1309 if (strstr(line, "readonly def") != NULL) return 0;
1310 while (getcharline(line, input, 1) == 0) {
1311 if (sscanf(line, "dup %d %d RD", &subrnum, &nbin) < 2) {
1312 /* if (strstr(line, "hires") == NULL) { */
1313 if (hybridflag == 0) { /* the old result follows ... */
1314 sprintf(logline, " Not a Subrs line: %s", line);
1315 showline(logline, 1);
1319 else { /* new 1994/July/15 for hybrid font */
1320 /* Note: this `line' (getcharline) contains multiple lines up to dup ... RD */
1321 if ((s = strstr(line, "dup ")) != NULL) {
1322 if (sscanf(s, "dup %d %d RD", &subrnum, &nbin) == 2) {
1323 /* strncpy(buffer, s, FNAMELEN); *//* save dup ... RD */
1325 putenline(output, line);
1326 /* strcpy(line, buffer); */
1333 putenline(output, line); /* beginning of subr */
1334 copycharstring(output, input, nbin);
1336 s = line + strlen(line) -1; /* to solve problem with \r\n */
1337 if (*s == '\r') *s = '\n'; /* extra blank line maybe */
1338 putenline(output, line); /* hit the end */
1339 // flushencrypt(output); /* flush out last bit */
1343 /* Tries to find encoding vector first in dvi file directory */
1344 /* - then tries default encoding vector directory */
1346 FILE *openvector(char *vector)
1349 char fn_vec[FNAMELEN];
1352 /* if vector contains a path, use it directly - no other trials */
1353 if (strpbrk(vector, "\\:/") != NULL) {
1354 strncpy(fn_vec, vector, FNAMELEN);
1355 extension(fn_vec, "vec");
1356 /* return fopen(fn_vec, "r"); */
1357 fp_vec = fopen(fn_vec, "r");
1358 if (fp_vec != NULL) {
1360 sprintf(logline, "Using encoding vector %s\n", fn_vec);
1361 showline(logline, 0);
1368 /* try first in dvi file directory */
1369 if (dvipath != NULL) strcpy(fn_vec, dvipath);
1370 else strcpy(fn_vec, "");
1371 makefilename(fn_vec, vector);
1372 extension(fn_vec, "vec");
1373 if ((fp_vec = fopen(fn_vec, "r")) != NULL) {
1375 sprintf(logline, "Using encoding vector %s\n", fn_vec);
1376 showline(logline, 0);
1381 /* try VECPATH directories */ /* modified for multiple directories 97/Aug/10 */
1384 if (*s == '\0') break; /* safety valve */
1385 /* strcpy(fn_vec, vecpath); */
1387 t = strchr(fn_vec, ';');
1388 if (t != NULL) *t = '\0'; /* isolate one directory path */
1389 makefilename(fn_vec, vector);
1390 extension(fn_vec, "vec");
1391 if ((fp_vec = fopen(fn_vec, "r")) != NULL) {
1393 sprintf(logline, "Using encoding vector %s\n", fn_vec);
1394 showline(logline, 0);
1398 if (t != NULL) s +=(t-fn_vec) + 1; /* step over dir and ; */
1402 /* then try in SUBDIRECTORY of default directory */ /* 1992/Nov/28 */
1403 strcpy(fn_vec, vecpath);
1404 /* strcat(fn_vec, "\\");
1405 strcat(fn_vec, "vec\\"); */
1406 makefilename(fn_vec, "vec\\"); /* subdirectory "vec" */
1407 strcat(fn_vec, vector);
1408 extension(fn_vec, "vec");
1409 if ((fp_vec = fopen(fn_vec, "r")) != NULL) {
1411 sprintf(logline, "Using encoding vector %s\n", fn_vec);
1412 showline(logline, 0);
1417 /* try in current directory */ /* 1992/Dec/8 */
1418 *fn_vec = '\0'; /* strcpy(fn_vec, ""); */
1419 makefilename(fn_vec, vector); /* */
1420 extension(fn_vec, "vec");
1421 if ((fp_vec = fopen(fn_vec, "r")) != NULL) {
1423 sprintf(logline, "Using encoding vector %s\n", fn_vec);
1424 showline(logline, 0);
1432 /* Clear out charnames */
1433 void cleanencoding (int start, int end)
1436 /* strcpy(namestring, ""); */
1437 namestring[0] = '\0'; /* empty string */
1438 stringindex = 1; /* reset index to next space */
1439 for (k = start; k < end; k++) charnames[k] = namestring; /* "" */
1442 void copyencoding(char *charnames[], char *encoding[], int n)
1445 if (n < 0 || n > 256)
1447 sprintf(logline, " ERROR in copyencoding %d\n", n);
1448 showline(logline, 1);
1451 for (k = 0; k < n; k++) charnames[k] = encoding[k];
1453 for (k = n; k < MAXCHRS; k++) charnames[k] = ""; */
1456 /* we have duplication here if repeated encoding in vector */
1458 void addencoding (int k, char *charname) /* 93/Nov/15 */
1460 int n = strlen(charname) + 1; /* space needed */
1461 if (stringindex + n >= STRINGSPACE) {
1462 showline(" ERROR: encoding vector too long\n", 1);
1465 charnames[k] = namestring + stringindex; /* ptr */
1466 strcpy (namestring + stringindex, charname); /* copy */
1467 stringindex += n; /* step over */
1471 /* now return 0 if successful, non-zero if failed */
1473 int readencoding (char *vector)
1475 char charname[FNAMELEN]; /* just to be safe */
1478 int n; /* not accessed */
1481 /* for (k = 0; k < MAXCHRS; k++) strcpy(charnames[k], ""); */
1482 cleanencoding(0, MAXCHRS); /* 93/Nov/15 */
1484 // if (strcmp(vector, "") == 0) /* rewritten 93/May/19 */
1485 if (vector == NULL) {
1486 // showline(" ", 0);
1487 showline(" WARNING: No encoding vector specified\n", 1);
1488 /* Use `textext' as default if no encoding vector specified */
1490 /* for (k = 0; k < TEXCHRS; k++) strcpy(charnames[k], textext[k]); */
1491 copyencoding(charnames, textext, TEXCHRS); /* 93/Nov/15 */
1493 return -1; /* failed */
1496 if ((fp_vec = openvector(vector)) != NULL) {
1497 n = 0; /* count encoding lines ? */
1498 while (getrealline(fp_vec, line) > 0) {
1499 if (*line == '%' || *line == ';') continue;
1500 /* if (sscanf(line, "%d %s", &k, &charname) < 2) { */
1501 if (sscanf(line, "%d %s", &k, charname) < 2) {
1502 showline(" Don't understand encoding line: ", 1);
1503 showline(logline, 1);
1506 else if (k >= 0 && k < MAXCHRS) {
1507 /* assert(strlen(charname) < MAXCHARNAME); */
1508 /* if (strlen(charname) >= MAXCHARNAME)
1509 fprintf(errout, " char name %s too long", charname); */
1510 addencoding(k, charname);
1511 /* strcpy(charnames[k], charname); */
1512 /* strncpy(charnames[k], charname, MAXCHARNAME); */
1518 else { /* use `textext' as default if encoding vector not found */
1519 /* for (k = 0; k < TEXCHRS; k++) strcpy(charnames[k], textext[k]); */
1520 copyencoding(charnames, textext, TEXCHRS); /* 93/Nov/15 */
1521 // showline(" ", 0); // ???
1522 sprintf(logline, " WARNING: can't find encoding vector %s ", vector);
1523 showline(logline, 1);
1524 /* perrormod(fn_vec); */
1527 return -1; /* failed */
1529 return 0; /* succeeded */
1532 void writevector (FILE *fp_out, char *vector, int n)
1534 int k, knext=0; /* n is MAXCHRS */
1536 /* char *s, *svector; */
1538 if (vector == NULL) {
1539 sprintf(logline, " ERROR in writevector %d\n", n);
1540 showline(logline, 1);
1543 if (n < 0 || n > 256) {
1544 sprintf(logline, " ERROR in writevector %d\n", n);
1545 showline(logline, 1);
1549 if (strcmp(vector, "textext") == 0) { /* 1992/Nov/19 */
1550 if (textextwritten++ > 0) return;
1552 /* if (strcmp(vector, "ansinew") == 0) {
1553 if (ansiwritten++ > 0) return;
1554 } */ /* 1993/Sep/30 */
1555 if (strcmp(vector, textencoding) == 0) { /* 1994/Dec/17 */
1556 if (ansiwritten++ > 0) return;
1559 knext = 256; /* 93/Feb/15 */
1560 if (bSuppressPartial == 0 && bForceFullArr == 0) { /* 93/Feb/15 */
1561 for (k = n-1; k >= 0; k--) { /* find last character code used */
1562 if(strcmp(charnames[k], "") != 0) {
1567 if (knext == 0) return; /* all empty, nothing to do */
1569 if (stripcomment == 0) {
1570 sprintf(logline, "%% %s encoding\n", vector); /* 1992/Nov/17 */
1571 PSputs(logline, fp_out);
1573 /* fprintf(fp_out, "/%s[", vector); */ /* 95/Feb/3 */
1574 sprintf(logline, "/%s[", removepath(vector)); /* strip path */
1575 PSputs(logline, fp_out);
1576 for (k = 0; k < knext; k++) {
1577 if (k != 0 && k % 8 == 0) {
1578 // putc('\n', fp_out);
1579 PSputc('\n', fp_out);
1581 if (strcmp(charnames[k], "") != 0) {
1582 sprintf(logline, "/%s", charnames[k]);
1583 PSputs(logline, fp_out);
1585 /* else fprintf(fp_out, "/.notdef"); */
1586 /* else fprintf(fp_out, " n"); */ /* 1993/Sep/31 */
1587 else { /* 1993/Oct/5 */
1589 while (kn < knext && strcmp(charnames[kn], "") == 0) kn++;
1590 /* if (kn < k + 4) { */
1591 if (kn < k + 5) { /* only more efficient if more than 4 */
1592 for (k=k; k < kn; k++) {
1593 PSputs(" n", fp_out);
1597 sprintf(logline, " %d notdef", kn-k);
1598 PSputs(logline, fp_out);
1600 /* if (((kn-1 >> 3) != (k >> 3)) && kn % 8 != 0) */
1601 if ((((kn-1) >> 3) != (k >> 3)) && (kn % 8) != 0) {
1602 // putc('\n', fp_out);
1603 PSputc('\n', fp_out);
1608 // fprintf(fp_out, "]def\n");
1609 PSputs("]def\n", fp_out);
1612 void writedvistart (FILE *fp_out)
1614 // fputs("dvidict begin\n", fp_out);
1615 PSputs("dvidict begin\n", fp_out);
1618 void writedviend(FILE *fp_out) /* 1992/Nov/17 */
1620 // fputs("end", fp_out);
1621 PSputs("end", fp_out);
1622 if (stripcomment == 0) {
1623 // fputs(" % dvidict", fp_out);
1624 PSputs(" % dvidict", fp_out);
1626 // putc('\n', fp_out);
1627 PSputc('\n', fp_out);
1630 /* Following used to be in preamble: */
1632 /* /dviencoding 256 array def */
1633 /* /dvicodemake{string cvs dup 0 97 put cvn dviencoding 3 1 roll put}bd */
1634 /* 0 1 9{dup 10 add 2 dvicodemake} for */
1635 /* 10 1 99{dup 100 add 3 dvicodemake} for */
1636 /* 100 1 255{dup 1000 add 4 dvicodemake} for */
1638 void writedviencode(FILE *fp_out) /* 1993/Sep/30 */
1641 char charname[5]; /* space for a255 + zero */
1643 writedvistart(fp_out);
1644 cleanencoding(0, MAXCHRS); /* reset string table */
1645 for (k = 0; k < MAXCHRS; k++) { /* fixed 1994/Feb/3 */
1646 sprintf(charname, "a%d", k);
1647 addencoding (k, charname);
1648 /* charnames[k] = namestring + stringindex; */
1649 /* stringindex = stringindex + strlen (namestring + stringindex) + 1; */
1651 writevector(fp_out, "dviencode", MAXCHRS);
1652 writedviend(fp_out); /* 1993/Sep/30 */
1655 void writetextext(FILE *fp_out)
1659 /* not allowed to use `TeX text' encoding if forcing full 256 vector */
1660 /* (no longer a problem, since we extend TeX text vector if needed */
1661 /* if (bForceFullArr == 0) { */ /* 93/Feb/15 */
1662 writedvistart(fp_out);
1664 /* for (k = 0; k < TEXCHRS; k++) strcpy(charnames[k], textext[k]); */
1665 copyencoding(charnames, textext, TEXCHRS); /* 93/Nov/15 */
1667 if (bForceFullArr == 0) writevector(fp_out, "textext", TEXCHRS);
1668 else { /* 1993/Sep/30 */
1669 /* for (k = TEXCHRS; k < MAXCHRS; k++) strcpy(charnames[k], ""); */
1670 cleanencoding(TEXCHRS, MAXCHRS); /* redundant ? */
1671 writevector(fp_out, "textext", MAXCHRS);
1673 writedviend(fp_out); /* 1992/Nov/17 */
1677 /* Write Windows ANSI encoding or what user defined in ENCODING env var */
1679 /* void writeansicode(FILE *fp_out) { */ /* 1993/Sep/30 */
1680 /* void writeansicode(FILE *fp_out, char *textencoding) { */ /* 1994/Dec/17 */
1681 void writeansicode(FILE *fp_out, char *textenconame) /* 1995/Feb/3 */
1685 /* if (ansiwritten > 0) return; */ /* already exists 1992/Nov/19 */
1687 writedvistart(fp_out);
1688 /* for (k = 0; k < MAXCHRS; k++) strcpy(charnames[k], ansiencoding[k]); */
1689 copyencoding(charnames, ansiencoding, MAXCHRS); /* 93/Nov/15 */
1690 /* writevector(fp_out, "ansinew", MAXCHRS); */
1691 /* writevector(fp_out, textencoding, MAXCHRS); */ /* 94/Dec/17 */
1692 writevector(fp_out, textenconame, MAXCHRS); /* 95/Feb/3 fix 96/May/28 */
1693 writedviend(fp_out); /* 1993/Sep/30 */
1696 /* overwrite Windows ANSI encoding hard-wired in here */
1698 /* void writetextencode(FILE *fp_out, char *textencoding) {*//* 94/Dec/17 */
1699 int readtextencode(char *textencoding) /* 94/Dec/17 */
1702 /* char *dupcharname; */
1704 if (readencoding(textencoding) == 0) {
1705 for (k = 0; k < MAXCHRS; k++) {
1706 /* dupcharname = _strdup(charnames[k]);
1707 if (dupcharname == NULL) {
1708 fputs("Unable to allocate memory\n", errout);
1711 ansiencoding[k] = zstrdup(charnames[k]);
1712 if (ansiencoding[k] == NULL) {
1713 showline("Unable to allocate memory\n", 1);
1719 /* writeansicode(fp_out); */
1723 #define ACCENTCHRS 15
1725 #define BASECHRS (26+26)
1727 /* Adjust wantchrs table so base and accent of composites are there */
1728 /* (i) we MUST have the base and accent character CharStrings */
1729 /* (ii) for present Adobe interpreters they must ALSO be in encoding */
1730 /* so its easiest to implement this by adjusting wantchrs */
1732 /* keep track of which accents already dealt with in accenthit */
1733 /* (based on StandardEncoding position of accent - 193) */
1734 /* keep track of which base chars already dealt with in basehit */
1735 /* (based on position of base in string `basecharacters') */
1737 /* returns non-zero if any accented character were found */
1739 int expandaccents (char *wantchrs)
1742 char basename[9]; /* dotlessi is max length */
1744 int compflag, foundflag;
1745 int composedflag=0; /* any composites ? */
1746 char *standname; /* 93/Sep/16 */
1748 /* int accentcomplain[ACCENTCHRS]; */ /* for accents from 193 to 207 */
1749 int accenthit[ACCENTCHRS]; /* for accents from 193 to 207 */
1750 /* int basehit[sizeof(basecharacters)]; */ /* for 28 base characters */
1751 int basehit[BASECHRS]; /* for 26 + 26 base characters */
1753 /* for (k = 0; k < ACCENTCHRS; k++) accentcomplain[k] = 0; */ /* 93/Sep/16 */
1754 for (k = 0; k < ACCENTCHRS; k++) accenthit[k] = 0; /* 94/Feb/17 */
1755 /* for (k = 0; k < sizeof(basecharacters); k++) basehit[k] = 0; */
1756 for (k = 0; k < BASECHRS; k++) basehit[k] = 0; /* 94/Feb/17 */
1758 /* composedflag = 0; */
1759 for (k = 0; k < MAXCHRS; k++) {
1760 if (wantchrs[k] == 0) continue; /* ignore unwanted characters */
1761 testname = charnames[k]; /* potential composite char */
1762 n = strlen(testname);
1763 /* This eliminates the bulk of charnames, since they are one char long */
1764 /* if (n < 5 || n > 11) continue; */ /* aring --- acircumflex */
1765 if (n < 4 || n > 14 || n == 13) continue; /* ldot --- uhungarumlaut */
1766 c = testname[0]; /* potential base character */
1767 /* see if in filter list --- is it worth limiting base chars ? */
1768 /* if (strchr(basecharacters, c) == NULL) continue; */ /* must be base */
1769 /* if ((s = strchr(basecharacters, c)) == NULL) continue; */
1770 /* n = s - basecharacters; */ /* compute offset in array 1994/Feb/17 */
1771 /* if (strchr(notbasecharacters, c) != NULL) continue; */ /* NO */
1772 /* if (c < 'A' || c > 'z' || (c < 'a' && c > 'Z') continue; */ /* NOP ? */
1773 if (c < 'A') continue;
1774 else if (c <= 'Z') n = c - 'A';
1775 else if (c < 'a') continue;
1776 else if (c <= 'z') n = c - 'a' + 26;
1778 /* have eliminated names that are too long or too short - or bad start */
1779 /* if (traceflag) printf("Testing %s ", testname); */
1780 compflag = 0; /* reset composite char flag */
1781 /* NOTE: we only need to worry about accents in StandardEncoding ! */
1782 for (i = 193; i <= 207; i++) { /* check through accents */
1783 /* note that two of the `accent' positions are actually "" */
1784 /* charname = standardencoding[i]; */
1785 /* if (strcmp(testname + 1, charname) == 0) { */
1786 if (strcmp(testname + 1, standardencoding[i]) == 0) {
1787 compflag = 1; break; /* found accent in table */
1790 /* What about hungarumlaut => hungar and dotaccent => dot */
1791 if (compflag == 0) {
1792 if (strcmp(testname + 1, "dot") == 0) { /* 93/Sep/16 */
1793 i = 199; /* dotaccent */
1796 else if (strcmp(testname + 1, "hungar") == 0) { /* 93/Sep/16 */
1797 i = 205; /* hungarumlaut */
1800 else if (strcmp(testname + 1, "dblacute") == 0) {/* 94/May/25 */
1801 i = 205; /* hungarumlaut */
1804 else if (strcmp(testname + 1, "hacek") == 0) {/* 94/May/25 */
1805 i = 207; /* caron */
1809 if (compflag != 0) { /* So, *is* it a composite character ? */
1810 /* composedflag = 0; */ /* was a bug ! */
1811 composedflag = 1; /* fix 1994/Feb/17 */
1813 /* speed up: 94/Feb/17 keep track of which already inserted - in basehit */
1814 if (basehit[n] == 0) { /* see whether already dealt with */
1815 basehit[n]++; /* note that we have been here */
1816 /* request base character first */
1817 /* basename[0] = (char) c; */
1818 /* basename[1] = '\0'; */
1820 strcpy(basename, "dotlessi");
1821 c = 245; /* standard encoding position for dotlessi */
1824 basename[0] = (char) c;
1827 if (strcmp(charnames[c], basename) == 0) { /* fast case */
1830 else { /* otherwise have to search for it */
1832 for (j = 0; j < MAXCHRS; j++) {
1833 if (strcmp(charnames[j], basename) == 0) {
1839 if (foundflag == 0) {
1840 sprintf(logline, " `%s' not in encoding", basename);
1841 showline(logline, 1);
1845 } /* end of if basehit[n] == 0 */
1847 /* then request accent character */
1848 /* speed up: 94/Feb/17 keep track of which already inserted - in accenthit */
1849 if (accenthit[i - 193] == 0) { /* check if already dealt with */
1850 accenthit[i - 193]++; /* mark that we dealt with this */
1851 standname = standardencoding[i]; /* 93/Sep/13 */
1852 /* if (strcmp(charnames[i], testname+1) == 0) */ /* fast case */
1853 if (strcmp(charnames[i], standname) == 0) { /* fast case */
1856 else { /* otherwise have to search for it */
1858 for (j = 0; j < MAXCHRS; j++) {
1859 /* if (strcmp(charnames[j], testname+1) == 0) { */
1860 if (strcmp(charnames[j], standname) == 0) {
1866 if (foundflag == 0) {
1867 /* we don't need this anymore, since we come in here only once accenthit */
1868 /* if (accentcomplain[i - 193] == 0) {*/ /* 93/Sep/16 */
1869 sprintf(logline, " `%s' not in encoding", standname);
1870 showline(logline, 1);
1871 /* accentcomplain[i- 193]++; */
1879 return composedflag;
1882 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
1884 /* Check whether font calls for characters *not* found in encoding! */
1887 int missingchars (char *wantchrs, char *encoding)
1889 int k, unknowns = 0;
1891 for (k = 0; k < fontchrs; k++) {
1892 /* if (wantchrs[k] != 0 && strcmp(charnames[k], "") == 0) unknowns++;*/
1893 if (wantchrs[k] != 0 && charnames[k][0] == '\0') unknowns++;
1894 /* if (wantchrs[k] != 0) printf("%d\t%s\n", k, charnames[k]); */
1896 /* Encoding passed in may be just "" if read from PFA file 96/May/26 */
1898 /* fprintf(errout, " ERROR: %d character%s used not in `%s'",
1899 unknowns, (unknowns == 1) ? "" : "s", encoding); */
1900 sprintf(logline, " ERROR: %d character%s used not in ",
1901 unknowns, (unknowns == 1) ? "" : "s");
1902 showline(logline, 1);
1903 // if (*encoding != '\0')
1904 if (encoding != NULL) {
1905 sprintf(logline, "`%s'", encoding);
1906 showline(logline, 0);
1908 else showline("encoding", 0);
1914 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
1916 /* could keep a record of which accent we already complained about */
1918 /* end of code for dealing with composite characters encoding */
1920 /* write out encoding - cheaply if possible */
1921 /* worry about remapped fonts ? */
1923 /* POSSIBLE PROBLEM: synthetic font, where /FontName appears after /Encoding */
1924 /* not sure it is really worth worrying about... */
1926 /* Maybe simplify this if StandardEncoding and no remapping ??? */
1928 /* void writeencoding(FILE *output, char wantchrs[], int syntheticflag) { */
1930 /* This also adjusts wantchrs to reflect base and accent characters */
1932 /* why aren't we just doing a return instead of setting `done' */
1934 /* void writeencoding(FILE *output, char *wantchrs, int syntheticflag) {*/
1935 void writeencoding(FILE *output, char *wantchrs, int syntheticflag, char *encoding)
1937 int k, standardok=0, textextok=0, ansiok=0, nullchar=0;
1940 /* char *charname; */
1941 int composedflag=0; /* if composite characters used */
1943 /* syntheticflag = fontproper[i] & C_SYNTHETIC; */
1944 /* for (k = fontchrs-1; k >= 0; k--) if (wantchrs[k] != 0) break; */
1945 /* fprintf(output, "/Encoding %d array\n", k+1); */
1946 /* fprintf(output, "0 1 %d {1 index exch /.notdef put} for\n", k); */
1947 /* if (wantchrs[chr] != 0) fprintf(output, "%s", line); */
1948 /* fprintf(output, "%s", line); */
1950 /* unless 'N' flag used, force in base and accent characters */
1952 if (accentedflag != 0) composedflag = expandaccents(wantchrs);
1953 else composedflag = 0;
1955 if (strcmp(encoding, "standard") == 0) {
1956 /* encoding = "StandardEncoding"; */ /* 94/Oct/25 */
1957 /* fprintf(output, "/Encoding StandardEncoding def\n"); */
1958 // fputs("/Encoding StandardEncoding def\n", output);
1959 PSputs("/Encoding StandardEncoding def\n", output);
1960 return; /* 94/Oct/25 */
1963 /* Just refer to encoding by name if permitted to do so */
1964 if (strcmp(encoding, "") != 0)
1966 if (bAllowShortEncode) { /* 94/Oct/25 */
1967 /* fprintf(output, "/Encoding %s def\n", encoding); */
1968 /* get rid of path name when referring to encoding 95/Feb/3 */
1969 sprintf(logline, "/Encoding %s def\n", removepath(encoding));
1970 PSputs(logline, output);
1971 return; /* done = 1; */
1973 else goto writefull; /* need to write out encoding in full! */
1976 /* do not allow use of dviencoding if accented characters seen */
1978 /* Construct new encoding vector */
1979 /* Check whether numeric vector will do *//* most efficient - if allowed */
1980 /* but we don't like this anymore because of clone problems ... */
1981 /* if (done == 0 && composedflag == 0 && */
1982 if (composedflag == 0 &&
1983 syntheticflag == 0 && /* do we need to worry about this ? */
1984 busedviencode != 0) { /* && accentedflag == 0 */
1985 /* fprintf(output, "/Encoding dviencoding def\n"); */
1986 // fputs("/Encoding dviencoding def\n", output);
1987 PSputs("/Encoding dviencoding def\n", output);
1988 return; /* done = 1; */
1989 } /* end of dviencoding test */
1991 /* added bSuppressPartial == 0 reference 1992/Sep/12 */
1992 /* added bForceFullArr == 0 reference 1993/Feb/13 */
1993 /* took out bForceFullArr == 0 reference 1993/Sep/30 by extending textext */
1995 /* check whether textext will do */
1996 /* if (done == 0 && composedflag == 0 && bAllowTexText != 0 && */
1997 if (composedflag == 0 && bAllowTexText != 0 &&
1998 /* bSuppressPartial == 0 && bForceFullArr == 0) { */
1999 bSuppressPartial == 0) {
2001 /* for (k = 0; k < fontchrs; k++) { */
2002 for (k = fontchrs-1; k >= 0; k--) { /* 93/Oct/2 */
2003 if (wantchrs[k] != 0) {
2004 if (k >= TEXCHRS || /* 93/Oct/2 */
2005 charnames[k][0] == '\0' || /* 95/July/15 */
2006 strcmp(charnames[k], textext[k]) != 0) {
2007 textextok = 0; break;
2011 if (textextok != 0) { /* fairly easy */
2012 /* fprintf(output, "/Encoding textext def\n"); */
2013 // fputs("/Encoding textext def\n", output);
2014 PSputs("/Encoding textext def\n", output);
2015 return; /* done = 1; */
2017 } /* end of textext trial */
2019 /* check whether Windows ANSI will do 1993/Sep/30 */
2021 /* if (done == 0 && bWindowsFlag != 0) { */
2022 /* if (bWindowsFlag != 0) { */
2023 if (bWindowsFlag != 0 && bAllowANSI != 0 && /* 94/Oct/25 */
2024 bSuppressPartial == 0) { /* 95/May/23 */
2027 /* for (k = 0; k < fontchrs; k++) { */
2028 for (k = fontchrs-1; k >= 0; k--) { /* 93/Oct/2 */
2029 if (wantchrs[k] != 0) {
2030 if (charnames[k][0] == '\0' || /* 95/July/15 */
2031 strcmp(charnames[k], ansiencoding[k]) != 0) {
2036 if (ansiok != 0) { /* fairly easy */
2037 /* fprintf(output, "/Encoding ansinew def\n"); */
2038 sprintf(logline, "/Encoding %s def\n",
2039 /* textencoding); */ /* 94/Dec/17*/
2040 textenconame); /* 94/Dec/17*/
2041 PSputs(logline, output);
2042 return; /* done = 1; */
2046 /* check whether StandardEncoding will do */
2047 /* if (done == 0 && bAllowStandard != 0) { */
2048 if (bAllowStandard != 0 &&
2049 bSuppressPartial == 0) { /* 95/May/23 ??? */
2051 /* for (k = 0; k < fontchrs; k++) { */
2052 for (k = fontchrs-1; k >= 0; k--) { /* 93/Oct/2 */
2053 if (wantchrs[k] != 0) {
2054 if (charnames[k][0] == '\0' || /* 95/July/15 */
2055 strcmp(charnames[k], standardencoding[k]) != 0) {
2056 standardok = 0; break;
2060 if (standardok != 0) { /* nice and easy ! */
2061 /* fprintf(output, "/Encoding StandardEncoding def\n"); */
2062 // fputs("/Encoding StandardEncoding def\n", output);
2063 PSputs("/Encoding StandardEncoding def\n", output);
2064 return; /* done = 1; */
2070 /* Couldn't use standard, textext, or Windows ANSI for some reason */
2071 /* if (done == 0) { */
2072 k = fontchrs-1; /* use full if partial suppress */
2073 /* if (bSuppressPartial == 0 || bForceFullArr != 0) { */
2074 if (bSuppressPartial == 0 && bForceFullArr == 0) { /* 1993/Feb/15 */
2075 for (k = fontchrs-1; k >= 0; k--) if (wantchrs[k] != 0) break;
2077 /* printf(" suppress %d force %d k+1 %d\n",
2078 bSuppressPartial, bForceFullArr, k+1); */ /* debugging */
2079 sprintf(logline, "/Encoding %d array", k+1);
2080 PSputs(logline, output);
2081 // putc('\n', output);
2082 PSputc('\n', output);
2083 sprintf(logline, "0 1 %d {1 index exch /.notdef put} for\n", k);
2084 PSputs(logline, output);
2087 for (k = 0; k < fontchrs; k++) {
2088 if (wantchrs[k] != 0 || /* addition 1992/Sep/12 */
2089 /* (bSuppressPartial != 0 && strcmp(charnames[k], "") != 0)) { */
2090 (bSuppressPartial != 0 && charnames[k][0] != 0)) {
2091 /* if (strcmp(charnames[k], "") != 0) */
2092 if (charnames[k][0] != '\0') { /* 95/July/15 */
2093 sprintf(logline, "dup %d /%s put\n", k, charnames[k]);
2094 PSputs(logline, output);
2098 /* fprintf(errout, " Null char name %d", k); */
2102 // fprintf(output, "readonly def\n");
2103 PSputs("readonly def\n", output);
2104 if (nullchar > 0) { /* somewhat redundant ... */
2106 sprintf(logline, " %d null char names", nullchar);
2107 showline(logline, 1);
2114 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
2117 (r|bx|tt|sltt|vtt|tex|ss|ssi|ssdc|ssbx|ssqi|dunh|bxsl|b|ti|bxti|csc|tcsc)
2120 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
2122 void beginresource (FILE *output, char *filefontname)
2124 if (stripcomment == 0) { /* 1994/Feb/3 */
2125 // fputs("%%BeginResource: ", output);
2126 PSputs("%%BeginResource: ", output);
2127 // fputs("font ", output);
2128 PSputs("font ", output);
2129 // fputs(filefontname, output);
2130 PSputs(filefontname, output);
2131 // putc('\n', output);
2132 PSputc('\n', output);
2136 int endresource (FILE *output)
2138 if (stripcomment == 0) {
2139 // fputs("%%EndResource\n", output);
2140 PSputs("%%EndResource\n", output);
2142 /* good place to check for output error also ... */
2143 // if (ferror(output) != 0)
2144 if (output != NULL && ferror(output)) {
2146 // sprintf(logline, " ERROR in output file %s\n", outputfile);
2147 showline("ERROR in output file", 1);
2148 perrormod((outputfile != NULL) ? outputfile : "");
2155 /* Just copy if we don't recognize the format ... no remapping */
2156 /* --- pretty desperate move ! */ /* don't try to be efficient */
2157 /* int i is font number in case needed for error message */
2159 void copyunknown (FILE *output, FILE *input, int i, char *fontnamek)
2163 showline(fontnamek, 0); /* 1995/Mar/1 */
2168 showline(" WARNING: Font type not recognized!\n", 1);
2169 while ((c = getc(input)) != EOF) {
2173 /* return 1; */ /* just copied the damn thing ! */
2176 /* copy ascii section of a compressed file - old version */
2177 /* returns EOF if EOF hit */
2179 int copyascii (FILE *output, FILE *input, long n, int firstline)
2183 c = getc(input); n--;
2184 if (c == '\r' && flushcr != 0) {
2185 c = getc(input); n--;
2187 (void) ungetc(c, input); n++;
2191 else if (firstline == 0) {
2192 // putc('\n', output);
2193 PSputc('\n', output);
2197 if (c == 128 || c == 0) { /* hit start of next section */
2198 (void) ungetc(c, input); n++;
2201 if (c == '\n') clm = 0;
2204 c = getc(input); n--;
2205 if (c == '\r' && flushcr != 0) {
2206 c = getc(input); n--;
2208 (void) ungetc(c, input); n++;
2214 sprintf(logline, " Unexpected EOF (%s)\n", "copyascii");
2215 showline(logline, 1);
2219 sprintf(logline, " Length discrepancy %ld", n);
2220 showline(logline, 1);
2225 /* copy ascii section of a compressed file - strip {restore}if */
2226 /* returns EOF if EOF hit */ /* special kludge for wrapped synthetic fonts */
2228 int copystrip (FILE *output, FILE *input, long n, int firstline)
2233 c = getc(input); n--;
2234 if (c == '\r' && flushcr != 0) {
2235 c = getc(input); n--;
2237 (void) ungetc(c, input); n++;
2241 else if (firstline == 0) {
2242 // putc('\n', output);
2243 PSputc('\n', output);
2246 s = line; /* use line as buffer */
2248 if (c == 128 || c == 0) { /* hit start of next section */
2249 (void) ungetc(c, input); n++;
2252 if (c == '\n' || c == '\r') {
2254 *s = '\0'; /* terminate line */
2255 if ((s = strstr(line, "{restore}")) != NULL) {
2256 if ((t = strstr(line, "cleartomark")) != NULL) {
2258 *s++ = '\0'; /* cut off after cleartomark */
2259 // fputs(line, output); /* 1992/Aug/20 */
2260 PSputs(line, output); /* 1992/Aug/20 */
2262 if (stripcomment == 0) { /* 1995/May/14 */
2263 // fputs("% font wrapper removed\n", output);
2264 PSputs("% font wrapper removed\n", output);
2268 // fputs(line, output); /* finally output it */
2269 PSputs(line, output); /* finally output it */
2271 s = line; /* reset line buffer */
2274 /* putc(c, output); */
2275 else *s++ = (char) c; /* check for line length exceeded ? */
2276 c = getc(input); n--; /* get next character */
2277 if (c == '\r' && flushcr != 0) {
2278 c = getc(input); n--;
2280 (void) ungetc(c, input); n++;
2286 sprintf(logline, " Unexpected EOF (%s)\n", "copystrip");
2287 showline(logline, 1);
2291 sprintf(logline, " Length discrepancy %ld", n);
2292 showline(logline, 1);
2297 /* copy binary section of a compressed file */
2299 int copybinary (FILE *output, FILE *input, long n)
2304 for (k = 0; k < n; k++) {
2307 sprintf(logline, " Unexpected EOF (%s)\n", "copybinary");
2308 showline(logline, 1);
2311 d = c & 15; c = (c >> 4) & 15;
2312 if (c > 9) c = c + 'A' - 10; else c = c + '0';
2313 if (d > 9) d = d + 'A' - 10; else d = d + '0';
2318 if ((clm += 2) >= columns) {
2319 // putc('\n', output);
2320 PSputc('\n', output);
2327 void copypfa (FILE *output, FILE *input, int stripflag)
2332 if (stripflag == 0) { /* normal easy case */
2333 while ((c = getc(input)) != EOF) {
2334 if (c == '\r' && flushcr != 0) {
2337 (void) ungetc(c, input);
2345 else { /* need to watch for closing wrapper */
2346 while (extgetline (input, line) != EOF) {
2347 if ((s = strstr(line, "{restore}")) != NULL) {
2348 if ((t = strstr(line, "cleartomark")) != NULL) {
2350 *s++ = '\0'; /* cut off after cleartomark */
2351 // fputs(line, output); /* 1992/Aug/20 */
2352 PSputs(line, output); /* 1992/Aug/20 */
2354 continue; /* just flush it */
2356 // fputs(line, output);
2357 PSputs(line, output);
2362 /* special purpose hack for fonts in PFA format that suck rocks */
2363 /* flush this eventually ... */
2365 void copymtmi (FILE *output, FILE *input, int stripflag)
2369 /* char buffer[MAXCHRS]; */
2371 if (stripflag == 0) showline(" no wrapper ", 1); /* debugging */
2373 while (extgetline (input, line) != EOF) {
2374 if ((s = strstr(line, "{restore}")) != NULL) {
2375 if ((t = strstr(line, "cleartomark")) != NULL) {
2377 *s++ = '\0'; /* cut off after cleartomark */
2378 // fputs(line, output); /* 1992/Aug/20 */
2379 PSputs(line, output); /* 1992/Aug/20 */
2383 // fputs(line, output);
2384 PSputs(line, output);
2388 /* This is typically called after already wading into the ASCII section */
2389 /* but only if syntheticflag or mtmiflag non-zero */
2390 /* int i is font number in case needed for error message */
2392 void copyfont (FILE *output, FILE *input, int i, int mtmiflag, int stripflag)
2394 int c, d, firstline = 1;
2395 int ascii=1, binary=0; /* section counts */ /* presently not used */
2398 firstline = 0; /* since we already past start of file ! */
2399 c = getc(input); /* skip over initial white space */
2400 while (c == '\n' || c == '\r' || c == ' ') c = getc(input);
2401 (void) ungetc(c, input);
2402 /* putc('\n', output); */ /* ??? */
2404 if (c == 0) { /* assume MacIntosh format */
2405 /* showline(" MAC ", 0); */ /* debugging */
2406 n = maclength(input);
2407 c = getc(input); d = getc(input); /* d should be zero */
2411 if (copyascii(output, input, n - 2, firstline) != 0) break;
2416 if (copybinary(output, input, n - 2) != 0) break;
2419 sprintf(logline, " Unrecognized section code %d", c);
2420 showline(logline, 1);
2423 n = maclength(input);
2424 c = getc(input); d = getc(input);
2426 sprintf(logline, " Unexpected EOF (%s)\n", "copyfont");
2427 showline(logline, 1);
2432 else if (c == 128) { /* assume PFB format */
2433 /* showline(" PFB ", 0); */ /* debugging */
2434 c = getc(input); d = getc(input);
2436 n = readlength(input);
2437 if (d == 1) { /* ASCII section code */
2439 /* printf(" strip %d ascii %d ", stripflag, ascii); *//* debug */
2440 if (stripflag != 0 && ascii > 1) {
2441 if (copystrip(output, input, n, firstline) != 0) break;
2444 if (copyascii(output, input, n, firstline) != 0) break;
2448 else if (d == 2) { /* binary section code */
2450 if (copybinary(output, input, n) != 0) break;
2453 sprintf(logline, " Unrecognized section code %d", d);
2454 showline(logline, 1);
2457 c = getc(input); d = getc(input);
2459 sprintf(logline, " Unexpected EOF (%s)\n", "copyfont");
2460 showline(logline, 1);
2465 else if ((c >= '0' && c <= '9') ||
2466 (c >= 'A' && c <= 'F') ||
2467 (c >= 'a' && c <= 'f')) { /* assume PFA format */
2468 /* showline(" PFA ", 0); */ /* debugging */
2469 if (mtmiflag == 0) copypfa (output, input, stripflag); /* normal PFA */
2470 else copymtmi (output, input, stripflag); /* MTMI */
2473 sprintf(logline, " Don't understand font file format %d", c);
2474 showline(logline, 1);
2477 /* following duplicates code at end of extracttype1 */
2478 endresource(output); /* share code */
2481 /* Use the following more in future to avoid dependency on line breaks ? */
2483 /* grab next white space delimited token in line */ /* read line if needed */
2484 /* assumes pump has been primed, i.e. line read and strtok called once */
2486 char *grabnexttoken(FILE *input, char *line)
2491 while ((s = strtok(str, " \t\n\r")) == NULL) {
2492 for(;;) { /* need to grab a new line then */
2493 if (extgetrealline(input, line) < 0) return NULL; /* EOF */
2494 /* ignore comments and blank lines - continue round the loop */
2495 if (*line != '%' && *line != '\n' && *line != '\r') break;
2499 if (*s != '%') break; /* escape if not comment */
2500 /* following added to strip comments off ends of lines 1992/Sep/17 */
2501 for(;;) { /* need to grab a new line then */
2502 if (extgetrealline(input, line) < 0) return NULL; /* EOF */
2503 /* ignore comments and blank lines - continue round the loop */
2504 if (*line != '%' && *line != '\n' && *line != '\r') break;
2511 /* new tokenized version follows */
2512 int gobbleencoding (FILE *input)
2518 /* cleanencoding(0, MAXCHRS); */
2520 /* may want to remove some debugging error message output later ... */
2521 s = strtok(line, " \t\n\r"); /* start the pipeline */
2522 for (;;) { /* exit if hit `readonly' or `def' ??? */
2523 if (strcmp(s, "dup") != 0) {
2524 if (strcmp(s, "readonly") == 0 ||
2525 strcmp(s, "def") == 0) break; /* normal exit */
2526 sprintf(logline, " Expecting %s, not: `%s' ", "`dup'", s);
2527 showline(logline, 1);
2530 if ((s = grabnexttoken(input, line)) == NULL) break;
2531 /* Cater to stupid Adobe Universal Greek font format */ /* 92/Sep/17 */
2532 if (strchr(s, '#') != NULL) { /* stupid encoding vector format */
2533 (void) sscanf(s, "%d#%n", &base, &n); /* try and get base */
2535 for (;;) { /* more general version 92/Sep/27 */
2537 if (c >= '0' && c <= '9') c = c - '0';
2538 else if (c >= 'A' && c <= 'Z') c = c - 'A' + 10;
2539 else if (c >= 'a' && c <= 'z') c = c - 'a' + 10;
2543 chr = chr * base + c;
2545 } /* end of radixed number case */
2546 else if (sscanf(s, "%d", &chr) < 1) {
2547 sprintf(logline, " Expecting %s, not: `%s' ", "number", s);
2548 showline(logline, 1);
2551 /* deal with idiotic Fontographer format - no space before /charname */
2552 if ((t = strchr(s, '/')) != NULL) s = t; /* 1992/Aug/21 */
2553 else if ((s = grabnexttoken(input, line)) == NULL) break;
2555 sprintf(logline, "Bad char code `%s' ", s);
2556 showline(logline, 1);
2560 /* if (chr >= 0 && chr < fontchrs && strlen(s) < MAXCHARNAME) { */
2561 if (chr >= 0 && chr < fontchrs) { /* 93/Nov/15 */
2562 /* printf("%d: %s ", chr, s); */ /* debugging */
2563 /* strcpy(charnames[chr], s); */
2564 if (strcmp(s, ".notdef") != 0) /* ignore .notdef 97/Jan/7 */
2565 addencoding(chr, s); /* 93/Nov/15 */
2568 sprintf(logline, "Invalid char number %d ", chr);
2569 showline(logline, 1);
2572 if ((s = grabnexttoken(input, line)) == NULL) break;
2573 if (strcmp(s, "put") != 0) {
2574 sprintf(logline, " Expecting %s not: `%s' ", "`put'", s);
2575 showline(logline, 1);
2576 /* break; */ /* ??? */
2578 if ((s = grabnexttoken(input, line)) == NULL) break;
2580 /* normally come here because line does not contain `dup' */
2581 /* but does contain `readonly' or `def' */
2582 /* attempt to deal with Fontographer 4.0.4 misfeature 94/Nov/9 */
2583 /* if `readonly' appears on one line and `def' appears on the next */
2584 if (strcmp(s, "readonly") == 0) {
2585 if ((s = grabnexttoken(input, line)) != NULL) {
2586 if (strcmp(s, "def") != 0) {
2587 sprintf(logline, " Expecting %s, not: `%s' ", "`def'", s);
2588 showline(logline, 1);
2589 // return -1; // ???
2593 /* need to clean out current line at all ? */
2597 /* check whether a TeX font - result not really used */
2598 /* used only if resident font names are to be upper cased (-U) */
2599 /* (so maybe the `lowercase' is not needed ?) */ /* or use _strnicmp(...) */
2600 /* May be useful when PostScript FontName same as filename, but uppercase */
2602 int istexfont (char *fname)
2604 if (_strnicmp (fname, "cm", 2) == 0 || /* Computer Modern (visible) */
2605 _strnicmp (fname, "lcm", 3) == 0 || /* SliTeX (visible) */
2606 _strnicmp (fname, "icm", 3) == 0 || /* Computer Modern invisible */
2607 _strnicmp (fname, "ilcm", 4) == 0 || /* SliTeX invisible */
2608 _strnicmp (fname, "msam", 4) == 0 || /* AMS math symbol */
2609 _strnicmp (fname, "msbm", 4) == 0 || /* AMS math symbol */
2610 _strnicmp (fname, "eu", 2) == 0 || /* Euler fonts */
2611 _strnicmp (fname, "wncy", 4) == 0 || /* Washington Cyrillic */
2612 _strnicmp (fname, "logo", 4) == 0 || /* logo fonts - METAFONT */
2613 _strnicmp (fname, "lasy", 4) == 0 || /* LaTeX symbol font */
2614 _strnicmp (fname, "line", 4) == 0 || /* LaTeX line fonts */
2615 _strnicmp (fname, "lcircle", 7) == 0 || /* LaTeX circle fonts */
2616 _strnicmp (fname, "mtmi", 4) == 0 || /* MTMI, MTMIB, MTMIH */
2617 _strnicmp (fname, "mtmu", 4) == 0 || /* , MTMUB, MTMUH */
2618 _strnicmp (fname, "mtms", 4) == 0 || /* MTMS, MTMSB */
2619 _strnicmp (fname, "mtsy", 4) == 0 || /* MTSY, MTSYB, MTSYH, MTSYN */
2620 _strnicmp (fname, "mtex", 4) == 0 || /* MTEX, MTEXB, MTEXH */
2621 _strnicmp (fname, "mtgu", 4) == 0 || /* MTGU, MTMGUB */
2622 _strnicmp (fname, "rmtm", 4) == 0 /* RMTMI, RMTMIB, RMTMIH */
2623 /* , RMTMUB, RMTMUH */
2624 /* _strnicmp (fname, "lm", 2) == 0 || */ /* LucidaMath */
2625 /* _strnicmp (fname, "lbm", 3) == 0 || */ /* LucidaNewMath */
2630 /* separated out 97/Feb/6 */ /* returns 0 if failed */
2631 /* this should also check for /BaseFontName and suppress replacement ? */
2632 /* WARNING: this writes back into second argument ! */
2634 int FindFontPFBaux (FILE *input, char *FontName, int nlen)
2636 char token[] = "/FontName ";
2640 while ((c = getc(input)) != EOF) {
2641 if (c == '%') /* Try and avoid comment lines ... */
2642 while (c >= ' ') c = getc(input); /* Skip to end of line */
2643 if (c != token[k]) {
2644 k = 0; /* no match, reset ... */
2648 if (k >= 10) { /* completed the match ? */
2649 while ((c = getc(input)) != '/' && c != EOF) { /* up to slash */
2650 if (c > ' ') { /* only white space allowed here 97/June/1 */
2652 continue; /* ignore /FontName *not* followed by /xxxxx */
2657 /* while ((c = getc(input)) > ' ' && k < MAXFONTNAME) */
2658 while ((c = getc(input)) > ' ' && k++ < nlen)
2659 /* buffer[k++] = (char) c; */
2661 /* fclose (input); */
2662 /* if (c != EOF && k < MAXFONTNAME) { */
2663 if (c != EOF && k < nlen) {
2664 /* buffer[k] = '\0'; */
2666 /* strcpy (FontName, buffer); */
2669 sprintf(logline, "Found /FontName %s in %s\n", FontName, FileName);
2670 showline(logline, 0);
2673 return 1; /* success */
2675 else return 0; /* failed, EOF in FontName or name too long */
2678 return 0; /* failed - EOF read the whole file */
2681 // FILE *OpenFont(char *font, int flag);
2683 /* Attempt to find FontName from PFB file when forcereside != 0 */
2684 /* An experiment 1993/Sep/30 */
2685 /* WARNING: this writes back into second argument ! */
2687 int FindFontPFB (char *FileName, char *FontName, int nlen) /* 1993/Sep/30 */
2692 if ((input = OpenFont(FileName, 0)) == NULL) {
2695 sprintf(logline, "Unable to find font file for %s\n", FileName); /* debug ? */
2696 showline(logline, 0);
2702 flag = FindFontPFBaux(input, FontName, nlen);
2706 sprintf(logline, "Unable to find FontName in %s\n", FileName);
2707 showline(logline, 1);
2712 /* finding PS FontName from PFM file */
2714 // FILE *openpfm (char *font);
2716 /* WARNING: this writes back into second argument ! */
2718 int FindFontPFM (char *FileName, char *FontName, int nlen) /* 1997/June/1 */
2724 sprintf(logline, "FindFontPFM nlen %d\n", nlen);
2725 showline(logline, 0);
2727 if ((input = openpfm(FileName)) == NULL) {
2730 sprintf(logline, "Unable to find font file for %s\n", FileName); /* debug ? */
2731 showline(logline, 0);
2736 flag = NamesFromPFM(input, NULL, 0, FontName, nlen, FileName);
2738 /* printf("FontName %s for FileName %s\n", FontName, FileName); */
2742 /* Try and find font name in PFB / PFA file or in PFM file */
2743 /* WARNING: this writes back into second argument ! */
2745 int FindFontName (char *FileName, char *FontName, int nlen) /* 1993/Sep/30 */
2748 sprintf(logline, " FindFontName `%s' %d\n", FileName, nlen);
2749 showline(logline, 0); // debugging only
2751 if (FindFontPFB (FileName, FontName, nlen) == 0) {
2752 if (FindFontPFM(FileName, FontName, nlen) == 0) return 0;
2757 /* Split out 1992/Oct/8 - avoid assumption FontName occurs before Encoding */
2758 /* Now use even earlier - avoid assumption FontName comes after FontInfo */
2759 /* returns non-zero if font appears to be synthetic font */
2761 /* drops real PostScript FontName in realfontname if found */
2763 int parseline(char *line, FILE *output, int syntheticflag, int mtmiflag)
2765 double m11, m12, m21, m22, m31, m32;
2769 /* Try and pick out FontType */
2770 if ((s = strstr(line, "/FontType")) != NULL) {
2771 if(sscanf(s, "/FontType %d", &ftp) == 1) {
2773 sprintf(logline, " Not a Type 1 font: %s", line);
2774 showline(logline, 1);
2778 // fputs(line, output);
2779 PSputs(line, output);
2781 /* Try and pick out FontName */
2782 else if ((s = strstr(line, "/FontName")) != NULL) {
2783 /* if (sscanf(s, "/FontName /%s", realfontname) > 0) { */
2784 s += 9; /* step over `/FontName' */
2785 while (*s != '/' && *s != '\0') s++; /* 1993/Aug/15 */
2786 /* Verify that the FontName we got from %! line is correct 97/Jan/30 */
2787 if (bAddBaseName && *realfontname != '\0') {
2788 if (*s == '/') { /* fix 1997/June/1 */
2789 n = strlen(realfontname);
2790 if (strncmp(s+1, realfontname, n) != 0) {
2791 sprintf(logline, " ERROR: %s != ", realfontname);
2792 showline(logline, 1);
2793 if (sscanf(s, "/%s", realfontname) > 0) {
2794 sprintf(logline, "%s ", realfontname);
2797 sprintf(logline, "%s ", s);
2799 showline(logline, 0);
2803 if (sscanf(s, "/%s", realfontname) > 0) {
2804 /* if (verboseflag) fputs(realfontname, stdout); */
2805 /* Don't trust `Oblique' (and `Narrow') fonts */
2806 /* Helvetica and Courier may be the only common cases of such fonts ??? */
2807 /* Helvetica, Helvetica-Light, Helvetica-Black, Helvetica-Narrow */
2808 /* Maybe also `Slanted' and `Narrow' and `Condensed' and `Expanded' ??? */
2809 /* Inverted order of tests for efficiency -- 1993/Nov/4 */
2810 if (syntheticsafe != 0) {
2811 if (strstr(s, "Oblique") != NULL ||
2812 strstr(s, "BoldObl") != NULL || /* 1994/Feb/3 */
2813 strstr(s, "Narrow") != NULL) { /* 1993/June/14 */
2814 for (k = 0; k < 16; k++) {
2815 if (strcmp("", syntheticfonts[k]) == 0) break;
2816 if (strstr(s, syntheticfonts[k]) != NULL) {
2819 showline(" assumed synthetic", 0); /* debugging */
2826 /* lowercase(realfontname, realfontname); */ /* removed 95/Aug/22 */
2828 /* check whether TeX font */ /* result not used much ... */
2829 texfont = 0; /* 1992/Dec/22 */
2830 if (istexfont(realfontname) != 0) {
2831 /* also check if actually one of 75 TeX fonts (what about LATEX, SliTeX) ? */
2832 texfont = 1; standard = 0;
2834 /* Should we replace /FontName or not ? *//* Presently hard wired to do this */
2835 /* May need to be more careful here - assuming one line */
2836 /* if (bSubRealName == 0) { */ /* 1995/Aug/22 */
2837 if (bSubRealName == 0 || mmflag != 0) { /* 1997/June/1 */
2838 /* we don't normally come here these days ... */
2839 /* copy realfontname to subfontname[k] ? */
2840 /* strcpy(subfontname + k * MAXFONTNAME, realfontname); */
2841 // if (strcmp(fontprefix, "") == 0) {
2842 if (fontprefix != NULL) {
2843 *s = '\0'; /* s points at /<fname> */
2844 // fputs(line, output);
2845 PSputs(line, output);
2847 // putc('/', output);
2848 PSputc('/', output);
2849 /* possibly modify if bRandomPrefix is set ??? */
2850 // fputs(fontprefix, output);
2851 PSputs(fontprefix, output);
2852 // fputs(s+1, output);
2853 PSputs(s+1, output);
2856 // fputs(line, output); /* no prefix, just copy over */
2857 PSputs(line, output); /* no prefix, just copy over */
2860 /* Don't mess with FontName of old MTMI */
2861 else if (mtmiflag != 0) {
2862 // fputs(line, output); /* 1992/Aug/22 */
2863 PSputs(line, output); /* 1992/Aug/22 */
2865 /* Don't mess with FontName of MM base font ? old method */ /* 1994/Dec/6 */
2866 /* else if (bMMNewFlag == 0 && mmflag != 0) fputs(line, output); */
2867 /* Don't touch: 2 copy exch /FontName exch put */ /* 95/May/14 */
2868 else if (strstr(line, "/FontName exch") != NULL) {
2869 // fputs(line, output);
2870 PSputs(line, output);
2872 else { /* 1992/Oct/31 */
2873 // fputs("/FontName /", output);
2874 PSputs("/FontName /", output);
2875 /* don't need to check here whether its resident or not ! */
2876 // if (strcmp(fontprefix, "") != 0)
2877 if (fontprefix != NULL) {
2878 /* possibly modify if bRandomPrefix is set ??? */
2879 // fputs(fontprefix, output);
2880 PSputs(fontprefix, output);
2882 /* following inserted 1992/Dec/22 - for new `U' flag */
2883 /* if (uppercaseflag != 0 && istexfont(filefontname) != 0) */
2884 if (uppercaseflag != 0 && texfont != 0)
2885 uppercase(filefontname, filefontname);
2886 /* if(_stricmp(filefontname, realfontname) == 0)
2887 strcpy(filefontname, realfontname); */ /* ??? */
2888 // fputs(filefontname, output);
2889 PSputs(filefontname, output);
2890 // fputs(" def\n", output);
2891 PSputs(" def\n", output);
2894 /* Try and pick out FontMatrix */
2895 /* Following usually doesn't get triggered because FontName seen first */
2896 /* Can't be more selective here, since don't know FontName ... */
2897 else if ((s = strstr(line, "/FontMatrix")) != NULL) {
2898 if (sscanf(s, "/FontMatrix[%lg %lg %lg %lg %lg %lg]",
2899 &m11, &m12, &m21, &m22, &m31, &m32) == 6) {
2900 if (syntheticsafe != 0 && syntheticflag == 0) {
2901 if (m11 != m22 || m21 != 0.0 || m12 != 0.0) {
2902 showline(" WARNING: use *synthetic* in sub file", 1);
2903 /* errcount(0); */ /* 1994/Jan/7 */
2908 // fputs(line, output);
2909 PSputs(line, output);
2912 // fputs(line, output);
2913 PSputs(line, output);
2915 return syntheticflag;
2918 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
2920 unsigned long checkdefault = 0x59265920; /* default signature */
2922 /* Takes first six letters of encoding vector name and compresses */
2923 /* into four bytes using base 40 coding */ /* 40^6 < s^32 */
2924 /* Treats lower case and upper case the same, ignores non alphanumerics */
2925 /* Except handles -, &, and _ */
2927 unsigned long codefourty(char *codingvector)
2929 unsigned long result=0;
2931 char *s=codingvector;
2933 if (strcmp(codingvector, "") == 0) {
2934 codingvector = "native"; /* if not specified ... */
2935 return checkdefault; /* use default signature */
2937 for (k = 0; k < 6; k++) {
2940 if (c >= 'A' && c <= 'Z') c = c - 'A';
2941 else if (c >= 'a' && c <= 'z') c = c - 'a';
2942 else if (c >= '0' && c <= '9') c = (c - '0') + ('Z' - 'A') + 1;
2943 else if (c == '-') c = 36;
2944 else if (c == '&') c = 37;
2945 else if (c == '_') c = 38;
2946 else c = 39; /* none of the above */
2947 /* else continue; */ /* not alphanumeric character */
2948 /* result = result * 36 + c; */
2949 result = result * 40 + c;
2956 int decodefourty(unsigned long checksum, char *codingvector)
2960 /* char codingvector[6+1]; */
2962 /* if (checksum == checkdefault) { */
2963 if (checksum == 0) {
2964 strcpy(codingvector, "unknown");
2967 else if ((checksum >> 8) == (checkdefault >> 8)) { /* last byte random */
2968 strcpy (codingvector, "native"); /* if not specified ... */
2969 return 1; /* no info available */
2972 for (k = 0; k < 6; k++) {
2973 /* c = (int) (checksum % 36); */
2974 c = (int) (checksum % 40);
2975 /* checksum = checksum / 36; */
2976 checksum = checksum / 40;
2977 if (c <= 'z' - 'a' ) c = c + 'a';
2978 else if (c < 36) c = (c + '0') - ('z' - 'a') - 1;
2979 else if (c == 36) c = '-';
2980 else if (c == 37) c = '&';
2981 else if (c == 38) c = '_';
2982 else c = '.'; /* unknown */
2983 codingvector[5-k] = (char) c;
2985 codingvector[6] = '\0';
2987 return 0; /* encoding info returned */
2990 int checkencoding(int k)
2992 char checksumvector[8]; /* 6 chars + null */
2993 if (fc[k] == nCheckSum) return 0; /* correct encoding */
2994 if (decodefourty(fc[k], checksumvector) != 0) return 0;
2995 /* if (_strnicmp(checksumvector, textencoding, 6) != 0) */ /* 95/Feb/3 */
2996 if (_strnicmp(checksumvector, textenconame, 6) == 0) return 0;
2997 // showline(" ", 0);
2998 showline(" WARNING: encoding mismatch ", 1);
2999 sprintf(logline, "TFM: `%s..' versus PFB: `%s'",
3000 /* checksumvector, textencoding); */
3001 checksumvector, textenconame); /* 95/Feb/3 */
3002 showline(logline, 1);
3003 return 1; /* failed */
3006 int checkremapencode(int k, char *fontnamek) /* 1995/July/15 */
3008 char checksumvector[8]; /* 6 chars + null */
3010 if (decodefourty(fc[k], checksumvector) != 0) return 0;
3011 // if (_strnicmp(checksumvector, fontvector + k * MAXVECNAME, 6) == 0)
3012 if (fontvector[k] != NULL &&
3013 _strnicmp(checksumvector, fontvector[k], 6) == 0)
3015 showline(" WARNING: encoding mismatch ", 1);
3016 sprintf(logline, " in %s ", fontnamek); /* 95/July/30 */
3017 showline(logline, 1);
3018 sprintf(logline, "TFM: `%s..' versus vector: `%s'\n",
3019 checksumvector, fontvector[k] != NULL ? fontvector[k] : "");
3020 // checksumvector, fontvector + k * MAXVECNAME);
3021 showline(logline, 1);
3025 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
3027 /* share some code between extracttype1 and extracttype3 ??? */
3028 /* e.g. for BeginResource and EndResource ? OK, that has been done */
3029 /* actually, appears to be some divergence now ... */
3031 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
3033 /* decompress a Type 1 font file and send it to specified output */
3035 /* int extracttype1(FILE *output, FILE *input, int i) { */
3036 /* int extracttype1(FILE *output, FILE *input, int fn) { */
3037 int extracttype1 (FILE *output, FILE *input, int fn, char *fontnamek)
3039 int nvec, ns, ne, c, d, k, nbin, n, nchrs, flag;
3040 /* int chr, nfdict; */
3041 int count, property, syntheticflag, mtmiflag;
3042 /* int hybridflag; */ /* 1993/Aug/5 */ /* made global 1994/July/15 */
3046 /* int m; */ /* debug only */
3047 int l; /* 1994/Jan/30 for `unseen' repeat appearance */
3048 int guess; /* 1995/Oct/25 */
3049 char *s, *t, *vector;
3050 char charname[FNAMELEN]; /* just to be safe */
3051 // char subfontnamek[MAXFONTNAME];
3052 char subfontnamek[FNAMELEN];
3058 // wantchrs = fontchar + MAXCHRS * fn;
3059 wantchrs = fontchar[fn];
3060 if (wantchrs == NULL) showline(" BAD wantchrs", 1);
3061 property = fontproper[fn];
3062 // vector = fontvector + fn * MAXVECNAME;
3063 vector = fontvector[fn];
3065 syntheticflag = (property & C_SYNTHETIC);
3066 mtmiflag = (property & C_MTMI);
3067 mmflag = (property & C_MULTIPLE); /* 95/May/13 */
3068 // strcpy(subfontnamek, subfontname + fn * MAXFONTNAME); /* 97/June/1 */
3069 if (subfontname[fn] != NULL) strcpy(subfontnamek, subfontname[fn]);
3070 else *subfontnamek = '\0';
3072 if (bSuppressPartial != 0) syntheticflag = 1; /* 1992/Sep/12 */
3074 /* if (syntheticflag != 0) printf(" synthetic font"); */ /* debugging */
3075 if (mtmiflag != 0) showline(" NOT Type 1", 1);
3077 count = 0; /* preliminary - may update later with accents */
3078 for (k = 0; k < MAXCHRS; k++) if (wantchrs[k] != 0) count++;
3079 /* printf("%d used in ", count, fontnamek); */ /* debug 95/Mar/31 */
3080 /* if (bMMNewFlag == 0 && mmflag != 0) count = MAXCHRS;*//* 94/Dec/6 */
3082 /* strcpy(charname, fontname + fn * MAXTEXNAME); */
3083 /* fprintf(errout, " No characters used in font %s (%d)",
3084 charname, fn); */ /* 1995/Jan/5 */
3085 if (traceflag) showline(" No characters used in font", 1);
3086 /* else if (verboseflag) putc('*', stdout); */ /* 1995/Feb/1 */
3087 fontproper[fn] |= C_UNUSED; /* 1995/Feb/1 */
3088 /* strcpy(charname, fontname + fn * MAXTEXNAME); */
3089 /* printf("Font %s (%d) marked C_UNUSED\n", charname, fn); */
3090 return -1; /* shouldn't ever happen ? unless page sub range ... */
3092 else if (verboseflag) {
3093 showline(fontnamek, 0);
3099 /* if (syntheticflag != 0) count = MAXCHRS; */ /* 1992/Aug/22 */
3101 /* Now actually start looking at the file! */
3103 if (bAddBaseName) { /* try and get /FontName 97/Feb/6 */
3105 *realfontname = '\0';
3106 if (FindFontPFBaux (input, realfontname, sizeof(realfontname))) /* FNAMELEN */
3107 bBaseNameDone = 0; /* found it, so use it */
3112 (void) ungetc(c, input);
3113 if (c == 0) { /* check if this is a Mac style font file */
3114 /* macstyle = 1; */ /* try and position at start of ASCII length field */
3115 /* need to figure out where we are in Mac file */
3116 /* could be (a) at start of MacBinary header */
3117 /* (b) at start of resource fork (128 byte later) */
3118 /* (c) at start of actual resource (256 byter after that) */
3120 (void) getc(input); /* first byte (0) again */
3121 if ((c = getc(input)) != 0) { /* start of MacBinary ? */
3122 for (k = 2; k < 384; k++) (void) getc(input); /* yes */
3123 c = getc(input); (void) ungetc(c, input);
3124 if (c != 0) { /* try and verify format */
3125 showline(" ERROR: Not a valid PC (or Mac) style font file ", 1);
3127 return 0; /* errcount ? */
3130 else { /* now try and check whether at start of resource fork, */
3131 /* which starts with (0, 0, 1, 0) = 256 length */
3132 c = getc(input); d = getc(input);
3133 if (c == 1 && d == 0) {
3134 /* then skip over resource fork section */
3135 for (k = 4; k < 256; k++) (void) getc(input);
3136 c = getc(input); (void) ungetc(c, input);
3137 if (c != 0) { /* try and verify format */
3138 showline(" ERROR: Not a valid PC (or Mac) style font file ",1 );
3140 return 0; /* errcount ? */
3143 else { /* try and imagine we are right there actually */
3144 /* rewind(input); */ /* back to start of length code */
3145 (void) getc(input); (void) getc(input); /* skip length */
3148 } /* end of first byte is zero in file case */
3151 task = "copying heading line";
3152 k = extgetline(input, line); /* get first line of font */
3153 if (*line != '%' || *(line + 1) != '!') {
3154 showline(" Nonstandard font file start: ", 1);
3158 if (strstr(line, "Type3") != NULL || strstr(line, "Font-3") != NULL) {
3159 type3flag = 1; /* well, maybe lets try Type 3 then ! */
3161 return 0; /* indicate lack of success ! */
3164 if (stripcomment == 0) {
3165 if (mmflag) beginresource(output, subfontnamek); /* 97/June/1 */
3166 else beginresource(output, filefontname); /* share code */
3167 /* fprintf(output, "%s", line); */ /* copy %! heading line ??? */
3168 // fputs(line, output);
3169 PSputs(line, output);
3170 if (wantcreation != 0) {
3171 k = extgetline(input, line); /* check second line of font */
3172 /* if (*line != '%' || strncmp(line, "%%CreationDate", 14) == 0) */
3173 if (strncmp(line, "%%CreationDate", 14) == 0) /* 1995/April/12 */
3174 /* fprintf(output, "%s", line); */
3175 // fputs(line, output);
3176 PSputs(line, output);
3177 /* this line gets output below anyway, unless its a comment */
3181 task = "looking for FontInfo";
3183 /* strcpy(realfontname, ""); */ /* 95/Aug/22 */ /* removed 97/Jan/30 */
3185 while (strstr(line, "/FontInfo") == NULL && k >= 0) {
3186 /* Try and strip out that `font wrapper' stuff checking for existing font ! */
3187 /* ===> NOTE: this is in outer level <=== */
3188 /* Used in Courier, Helvetica for example */
3189 /* Also junk in Fontographer style fonts - up to three lines long */
3190 /* if (stripchecking != 0 && syntheticflag == 0) { */
3191 if (stripchecking != 0) {
3192 if (strstr(line, "FontDirectory") != NULL) {
3194 k = extgetline(input, line);
3195 if (strstr(line, "/FontType") != NULL) {
3196 k = extgetline(input, line);
3198 if (strstr(line, "{save true}") != NULL) { /* 1992/Aug/21 */
3199 k = extgetline(input, line);
3201 /* search up to line containing `{false}ifelse' ? */
3202 /* search up to `<x> dict begin' ? */
3203 while (strstr(line, "dict") == NULL) { /* 1992/Oct/22 */
3204 k = extgetline(input, line);
3205 if (k == EOF) break;
3207 if (stripcomment == 0) {
3208 // fputs("% font wrapper removed\n", output);
3209 PSputs("% font wrapper removed\n", output);
3211 /* putc('\n', output); */ /* at least leave some space */
3212 } /* end of strstr(line, "FontDirectory") != NULL */
3213 } /* end of stripchecking != 0 */
3215 /* ignore comment lines OTHER than copyright or trademark line */
3217 if (strstr(line, "opyright") != NULL ||
3218 strstr(line, "rademark") != NULL ||
3219 strstr(line, "(c)") != NULL)
3220 // fputs(line, output);
3221 PSputs(line, output);
3223 /* Ignore blank lines */
3224 else if (*line != '\n') {
3225 /* fputs(line, output); */ /* 1992/July/18 */ /* 95/April/12 */
3226 /* Check for FontName even this early - added 95/April/12 */
3227 syntheticflag = parseline(line, output, syntheticflag, mtmiflag);
3228 /* parseline outputs the line itself (or modified version) */
3230 k = extgetline(input, line);
3231 /* getrealline(input, line); */
3234 /* Should now have /FontInfo line */ /* increase dictionary allocation */
3235 if (bAddBaseName && !bBaseNameDone) {
3237 if ((s = strstr(line, "/FontInfo")) != NULL) {
3239 if (sscanf(s, "%d%n dict", &k, &n) == 1) {
3240 char buffer[FNAMELEN]; /* long enough ? */
3241 strcpy(buffer, s+n);
3242 sprintf(s, "%d", k+1);
3244 /* printf(line); */ /* debugging */
3249 showline(" ERROR: unable to extend FontInfo dictionary\n", 1);
3254 task = "stripping out FontInfo";
3255 /* Now strip info ONLY if busedviencode is set --- 1992/July/18 */
3256 /* It would be dangerous to retain /Notice in /FontInfo directory only, */
3257 /* since /Notice may be multiline --- changes 1992/July/18 */
3258 /* This has a somewhat flakey termination test ... */
3259 /* usually the end is `end readonly def' */
3261 while (strstr(line, "end ") == NULL && k >= 0) {
3262 if (stripinfo == 0 || busedviencode == 0) {
3263 // fputs(line, output);
3264 PSputs(line, output);
3266 else if ((s = strstr(line, "/Notice")) != NULL) {
3267 sprintf(logline, "%% %s", s); /* s+1 ? */
3268 PSputs(logline, output);
3270 /* Try and put it after the /FullName in /FontInfo dictionary ? */
3271 if (strstr(line, "/BaseFontName ") != NULL) bBaseNameDone++;
3272 /* In this case however the FontInfo dict is now one entry too large */
3273 /* if (strstr(line, "/FullName") != NULL) {
3274 if (bAddBaseName && !bBaseNameDone) {
3275 fprintf(output, "/BaseFontName (%s) def\n", realfontname);
3279 k = extgetrealline(input, line);
3281 /* If haven't placed BaseFontName yet, do it here */ /* 97/Jan/30 */
3282 if (bAddBaseName && !bBaseNameDone) {
3283 sprintf(logline, "/BaseFontName (%s) def\n", realfontname);
3284 PSputs(logline, output);
3288 if (stripinfo == 0 || busedviencode == 0) { /* terminating line FontInfo */
3289 // fputs(line, output);
3290 PSputs(line, output);
3293 /* does this assume FontName comes before Encoding ? YES, ugh */
3294 task = "looking for Encoding & FontName";
3295 k = extgetrealline(input, line); /* look for encoding */
3296 while (strstr(line, "/Encoding") == NULL && k >= 0) {
3297 syntheticflag = parseline(line, output, syntheticflag, mtmiflag);
3298 k = extgetrealline(input, line);
3301 /* special case hack when "def" is on line *after* StandardEncoding 98/Oct/8 */
3302 if (strstr(line, "StandardEncoding") != NULL) {
3303 if (strstr(line, "def") == NULL) {
3304 s = line + strlen(line);
3305 *(s-1) = ' '; /* turn line termination into space */
3306 k = extgetrealline(input, s);
3307 /* printf("LINE: %s", line); */
3311 /* Now we have hit the encoding vector --- /Encoding in line */
3313 if (mtmiflag != 0) { /* don't mess with vector if font sucks rocks */
3314 // fputs(line, output); /* 1992/Aug/22 */
3315 PSputs(line, output); /* 1992/Aug/22 */
3318 /* else if (bMMNewFlag == 0 && mmflag != 0) fputs(line, output); */
3319 else if ((property & C_REMAPIT) == 0) { /* if font is not remapped */
3320 if (strstr(line, "StandardEncoding") != NULL) { /* easy case! */
3321 standard = 1; texfont = 0; fontchrs = MAXCHRS;
3322 if (bWindowsFlag != 0) {
3324 // putc('~', stdout);
3325 // if (logfileflag) putc('~', logfile);
3328 /* for (k = 0; k < fontchrs; k++)
3329 strcpy(charnames[k], ansiencoding[k]); */
3330 /* ansi encoding may have been changed if env var ENCODING is set ??? */
3331 copyencoding(charnames, ansiencoding, fontchrs); /* 93/Nov/15*/
3332 /* writeencoding(output, wantchrs, syntheticflag, "ansinew"); */
3333 /* writeencoding(output, wantchrs, syntheticflag, textencoding); */
3334 missingchars(wantchrs, textenconame); /* TEST 95/July/15 */
3335 writeencoding(output, wantchrs, syntheticflag, textenconame);
3336 if (bCheckEncoding) (void) checkencoding(fn); /* 95/Jan/10 */
3337 nansified++; /* count how many we did this way */
3338 } /* if (bWindowsFlag != 0) */
3340 /* for (k = 0; k < fontchrs; k++)
3341 strcpy(charnames[k], standardencoding[k]); */
3342 copyencoding(charnames, standardencoding, fontchrs); /* 93/Nov/15*/
3343 missingchars(wantchrs, "standard"); /* TEST 95/July/15 */
3344 writeencoding(output, wantchrs, syntheticflag, "standard");
3346 /* writeencoding(output, wantchrs, syntheticflag); */ /* ??? */
3347 } /* end of StandardEncoding case (unremapped) */
3348 else { /* font was not using StandardEncoding (unremapped) */
3350 if(sscanf(line, "/Encoding %d array", &nvec) < 1) {
3351 sprintf(logline, " Don't understand encoding vector: %s",
3353 showline(logline, 1);
3357 /* fontchrs = nvec; */ /* can we trust this ? NO better not */
3359 /* task = "reading Encoding"; */
3360 k = extgetrealline(input, line);
3361 /* have to ignore "0 1 255 {1 index exch /.notdef put} for" line */
3362 if (sscanf(line, "%d 1 %d {", &ns, &ne) < 2) {
3363 /* maybe no need to complain ? */
3364 showline(" No /.notdef line", 1);
3366 else k = extgetrealline(input, line); /* 92/02/04 */
3367 /* grabbed next line (or hung onto this, if NOT /.notdef line) */
3368 /* clear out charnames - background of blanks */
3369 /* for (k = 0; k < MAXCHRS; k++) strcpy(charnames[k], ""); */
3370 /* for (k = 0; k < MAXCHRS; k++) *charnames[k] = '\0';*//* 92/02/04 */
3371 cleanencoding(0, MAXCHRS); /* 93/Nov/15 */
3373 task = "reading Encoding";
3374 /* k = extgetrealline(input, line); */ /* 92/02/04 now done above */
3375 /* while (strstr(line, " def") == NULL) */
3376 /* scan encoding - ends on "readonly def" usually */
3377 /* new tokenized version follows */
3378 gobbleencoding(input);
3379 /* writeencoding(output, wantchrs, syntheticflag); */ /* ??? */
3380 missingchars(wantchrs, ""); /* NEW TEST 95/July/15 */
3381 writeencoding(output, wantchrs, syntheticflag, "");
3382 } /* Finished with NOT StandardEncoding case */
3383 } /* finish with non-remapped font case */
3385 else { /* now for what to do if non-resident font remapped C_REMAPIT */
3387 // putc('^', stdout);
3388 // if (logfileflag) putc('^', logfile);
3391 /* first flush old encoding vector */
3392 if (strstr(line, "StandardEncoding") == NULL) {
3393 /* scan encoding - ends on "readonly def" usually */
3394 /* has to ignore "0 1 255 {1 index exch /.notdef put} for" line */
3395 /* skip over encoding in font - ignore it totally */
3396 /* Encoding ends with token `def' or `readonly' */
3397 /* and token `def' and `readonly should not occur in Encoding */
3398 while ((strstr(line, "def") == NULL ||
3399 strstr(line, "put") != NULL) && k >= 0) { /* NEW 1991/11/23 */
3400 k = extgetrealline(input,line);
3403 readencoding(vector); /* read desired encoding */
3404 /* writeencoding(output, wantchrs, syntheticflag); */
3405 missingchars(wantchrs, vector); /* NEW TEST 95/July/15 */
3406 writeencoding(output, wantchrs, syntheticflag, "");
3407 } /* end of dealing with encoding vector */
3409 /* if (traceflag) showencoding(stdout); */
3411 task = "copying font dict up to eexec";
3412 k = extgetrealline(input, line);
3413 while (strstr(line, "eexec") == NULL && k >= 0) { /* copy up to eexec */
3414 syntheticflag = parseline(line, output, syntheticflag, mtmiflag);
3415 k = extgetrealline(input, line);
3417 // fputs(line, output); /* 1992/July/18 */
3418 PSputs(line, output); /* 1992/July/18 */
3420 if (bSubRealName == 0) { /* 95/Aug/22 */
3421 /* we don't normally come here these days ... */
3422 // strcpy(subfontname + fn * MAXFONTNAME, realfontname);
3423 if (subfontname[fn] != NULL) free(subfontname[fn]);
3424 subfontname[fn] = zstrdup(realfontname);
3425 /* if we are going to use the PS FontName here we'll need it later */
3428 if (k == EOF) { /* NEW */
3429 showline(" Premature EOF", 1);
3430 showline(" in font file", 1);
3432 return -1; /* NEW --- shouldn't happen ! */
3435 /* Problem: what if syntheticflag set, but stripflag also set !!! */
3436 if (syntheticflag != 0 ||
3437 mtmiflag != 0) { /* pretty much just expand PFB to PFA */
3438 /* copyfont(output, input, i, mtmiflag, stripflag); */
3439 copyfont(output, input, fn, mtmiflag, stripflag);
3445 clm = 0; // important for outencrypt
3447 task = "entering encrypted section";
3450 while (c <= ' ' && c > 0) c = getc(input); /* skip over white space */
3451 if (c == 128) { /* see whether .pfb input format */
3456 " Expecting %s, not %d", "binary section code", c);
3457 showline(logline, 1);
3461 len = readlength(input);
3463 else if (c == 0) { /* see whether Mac binary input format */
3465 (void) ungetc(c, input);
3466 len = maclength(input);
3469 sprintf(logline, " Expecting %s, not %d", "Mac binary section code", c);
3470 showline(logline, 1);
3471 /* shownext(input); */
3477 sprintf(logline, " Invalid Mac Binary section code %d", c);
3478 showline(logline, 1);
3484 else if (c > 128) { /* see whether raw binary - totally flakey ! */
3486 len = (1U << 31); /* conversion to unsigned long ... */
3487 (void) ungetc(c, input);
3489 else (void) ungetc(c, input);
3491 /* copying across the four random encoding bytes at start also */
3493 n = getmagic(input, line); /* 1993/Sep/14 */
3494 putenlinen(output, line, n); /* 1993/Sep/14 */
3496 task = "looking for CharString dict";
3497 n = getenline(input, line);
3498 while ((s = strstr(line, "/CharStrings")) == NULL) {
3499 /* Omit UniqueID if font remapped AND dviencoding in use */
3500 if ((property & C_REMAPIT) != 0) {
3501 if (busedviencode != 0 && strstr(line, "/UniqueID") != NULL) {
3502 /* if (verboseflag) printf(" Stripping UniqueID"); */
3503 n = getenline(input, line); continue;
3506 putenlinen(output, line, n);
3507 if (strstr(line, "/Subrs") != NULL) {
3508 copysubrs(output, input);
3509 /* may want to inject a spurious newline here ... */
3510 /* printf("Old line %s", line); */ /* |- */
3511 /* n = getenline(input, line); */
3512 /* printf("New line %s", line); */ /* end noaccess put */
3513 if (abortflag) return -1;
3516 n = getenline(input, line);
3517 /* check on possibility of Synthetic Font */
3518 /* possibly suppress discarding of unwanted characters ? */
3519 /* Synthetic fonts won't work when remapped ? */
3520 /* ===> NOTE: this is in encrypted level <=== */
3521 /* possibly have to deal differently with the ending ? */
3522 /* need to transfer the rest of the font just as is because of byte count */
3523 if (strstr(line, "FontDirectory") != NULL) { /* 1992/Aug/24 */
3524 /* don't complain if already noted that it was synthetic ... */
3525 if (syntheticsafe != 0 && syntheticflag == 0) {
3526 showline(" ERROR: use *synthetic* in sub file", 1);
3528 syntheticflag = -1; /* is it safe to do this now ? */
3530 /* else if (verboseflag) printf(" synthetic"); */
3532 if (strstr(line, "hires") != NULL) { /* 1993/Jan/17 */
3533 if (hybridflag == 0) showline(" hybrid", 0); /* first time */
3536 /* if (traceflag) printf("LINE: %s", line); */
3538 if (strncmp(line, "2 index", 7) == 0) fontform = 2; /* new form */
3539 else if (strncmp(line, "dup", 3) == 0) fontform = 1; /* old form */
3540 else fontform=0; /* not recognized */
3541 if (sscanf(s, "/CharStrings %d%n", &nchrs, &n) < 1) {
3542 putenline(output, line); /* 1993 Aug 5 - allow line split */
3543 n = getenline(input, line);
3545 if (strstr(line, "dict dup") == NULL ||
3546 sscanf(s, "%d%n", &nchrs, &n) < 1) {
3547 sprintf(logline, " Don't understand CharStrings line: %s", line);
3548 showline(logline, 1);
3553 else { /* normal case: /CharString <n> dict dup on line */
3554 *(s+13) = '\0'; /* terminate after `/CharStrings' */
3555 putenline(output, line); /* start of modified /CharString line */
3557 /* *s = '\0'; */ /* terminate before /CharStrings */
3558 /* putenline(output, line); */ /* start of modified /CharString line */
3560 charagain: /* 1993 Aug 5 - hybrid font loop */
3562 if (accentedflag != 0) { /* need to redo the count */
3563 count = 0; /* if accented characters allowed */
3564 for (k = 0; k < MAXCHRS; k++) if (wantchrs[k] != 0) count++;
3566 if (wantnotdef != 0) count++;
3567 /* if (count > MAXCHRS) count = MAXCHRS; */ /* notdef ??? */
3568 if (syntheticflag != 0) count = nchrs; /* 1992/Aug/22 */
3569 nchrs = count; /* count of desired characters */
3571 /* for (k=0; k < fontchrs; k++) if (wantchrs[k] != 0) nchrs++; */
3572 /* if (wantnotdef != 0) nchrs++; */
3573 /* sprintf(line, "/CharStrings %d", nchrs); */
3574 sprintf(line, "%d", nchrs); /* 1993 Aug 5 */
3575 putenline(output, line); /* middle of modified /CharString line */
3576 *(s+n) = ' '; /* fix up, in case it became `\0' */
3577 putenline(output, s + n); /* end of modified /CharString line */
3579 task = "scanning CharStrings";
3580 chrs = 0; /* not used ? 95/Oct/28 */
3581 /* for (k = 0; k < MAXCHRS; k++); charseen[k] = 0; *//* do earlier ??? */
3582 for (k = 0; k < MAXCHRS+1; k++) charseen[k] = 0; /* fix 1992/Aug/21 */
3584 if (getcharline(line, input, 0) != 0) break;
3585 /* the token "end" indicates the end of the CharString section */
3586 if (sscanf(line, "/%s %d %n", charname, &nbin, &n) < 2) {
3587 sprintf(logline, " Not a CharString line: %s", line);
3588 showline(logline, 1);
3589 /* fprintf(errout, " charname %s, nbin %d, n %d",
3591 n = sscanf(line, "/%s %d %n", &charname, &nbin, &n);
3592 fprintf(errout, " found only %d items in %d chars, first %d ! ",
3593 n, strlen(line), (int) *line); */
3594 if (getcharline(line, input, 0) != 0) break;
3595 errcount(0); /* a little risky going on here ? */
3596 /* extgiveup(9); */ /* or, just flush THIS file ? */
3598 /* assert(strlen(charname) < MAXCHARNAME); */
3599 /* if (strlen(charname) >= MAXCHARNAME)
3600 fprintf(errout, " char name %s too long", charname); */
3601 /* flushed 93/Nov/15 */
3602 /* possibly check here whether syntheticflag is set ??? */
3603 /* in that case just transfer all characters */ /* 1992/Aug/22 */
3604 /* shouldn't this depend on whether we used StandardEncoding ? */
3605 /* k = wantthisname(charname, chrs, wantchrs); */
3607 /* single character charnames equal their char code 95/Oct/28 */
3608 if (*(charname+1) == '\0') guess = *charname;
3609 k = wantthisname(charname, guess, wantchrs);
3610 if (k >= 0 || syntheticflag != 0) { /* 1992/Aug/22 */
3611 /* if (k < 0 || k >= MAXCHRS)
3612 fprintf(errout, "Way out of range k %d ", k); else */
3613 /* charseen[k] = 1; */ /* new - so can tell which missing */
3614 if (syntheticflag != 0) k = NOTDEF; /* prevent error */
3615 else charseen[k]++; /* new - so can tell which missing */
3616 /* debugging only */
3617 /* for dviencoding, change name to numeric code, unless its .notdef */
3618 if (busedviencode != 0 && k != NOTDEF) { /* change charname */
3619 if (strstr(line + n, "RD") != NULL) /* overwrite */
3620 sprintf(line, "/a%d %d RD ", k, nbin);
3621 else sprintf(line, "/a%d %d -| ", k, nbin);
3623 /* above assumes using either RD or -| ??? */
3624 putenline(output, line); /* beginning of character */
3625 copycharstring(output, input, nbin);
3626 /* printf("%d ", k); */ /* debugging */
3627 /* this may not be accurate if repeated encoding and both char codes used .. */
3628 count--; /* how many we extracted so far */
3629 /* debugging only */
3630 /* if (count == 0 && breakearly != 0 && fontform != 0) break; */
3632 else flushcharstring(input, nbin);
3633 chrs++; /* not used ? 95/Oct/28 */
3634 if (bAbort) abortjob(); /* 1992/Nov/24 */
3635 if (abortflag) return -1;
3638 /* believe that count should be zero here ! */
3639 if (count > 0) { /* 1994/Jan/30 */
3640 /* first check whether `missing' characters appear twice in encoding */
3641 /* this is important now that we use TEXANSI and extend encoding at bottom */
3642 /* can only be equal to character lower in code, so don't start at zero */
3643 for (k = 1; k < MAXCHRS; k++) { /* check the suspects */
3644 if ((wantchrs[k] != 0) && (charseen[k] == 0)) {
3645 /* don't play with characters that have no names ! 96/May/26 */
3646 if (strcmp(charnames[k], "") == 0) continue;
3647 for (l = 0; l < k; l++) { /* does it appear earlier */
3648 /* don't play with characters that have no names ! 96/May/26 */
3649 if (strcmp(charnames[l], "") == 0) continue;
3650 if (strcmp(charnames[k], charnames[l]) == 0) {
3660 /* fprintf(errout, " %d characters (out of %d) not found: ",
3662 sprintf(logline, " %d character%s (out of %d) not found: ",
3663 count, (count == 1) ? "" : "s", nchrs);
3664 showline(logline, 1);
3665 /* fprintf(errout, "fontchrs: %d ", fontchrs); */
3666 for (k = 0; k < MAXCHRS; k++) { /* list the bad ones */
3667 if ((wantchrs[k] != 0) && (charseen[k] == 0)) {
3668 /* characters may have no names if not in encoding 96/May/26 */
3669 /* fprintf(errout, " %s (%d)", charnames[k], k); */
3670 if (strcmp(charnames[k], "") != 0)
3671 sprintf(logline, " %s (%d)", charnames[k], k);
3672 else sprintf(logline, " (%d)", k); /* 96/May/26 ? */
3673 showline(logline, 1);
3675 /* debugging only */
3676 /* if ((wantchrs[k] != 0) && (charseen[k] != 0)) {
3677 fprintf(errout, " %s [%d]", charnames[k], k);
3680 errcount(0); /* ??? */
3684 task = "copying end of CharString dict def";
3685 putenline(output, line); /* copy beginning of end line */
3686 n = getenline(input, line); /* copy rest of line */
3687 putenline(output, line);
3689 /* 1993 August 5 - deal with `hybrid' font - second set of CharStrings */
3690 /* if (strncmp(line, "hires", 5) == 0) { */
3691 if (strstr(line, "hires") != NULL) { /* 1994/July/15 */
3692 n = getenline(input, line); /* get potential <n> dict dup line */
3694 if (strstr(line, "dict dup") != NULL &&
3695 sscanf(s, "%d%n", &nchrs, &n) == 1) goto charagain;
3696 if ((s = strstr(line, "dict dup")) != NULL) { /* 1994/July/15 */
3697 while (s > line && *(s-1) == ' ') s--;
3698 while (s > line && *(s-1) > ' ') s--; /* Try and step back */
3699 if (sscanf(s, "%d%n", &nchrs, &n) == 1) {
3700 /* printf("CHARSTRING: %s", s); */ /* debugging */
3701 *s = '\0'; /* terminate after `/CharStrings' */
3702 putenline(output, line); /* start modified /CharString line */
3707 else n = getenline(input, line); /* copy /FontName line */
3709 /* if by mistake we wade into second /CharStrings of hybrid font, following */
3710 /* goes wrong because it copies binary stuff and treats 0 char as end string */
3712 task = "copying end of font dict def";
3713 /* n = getenline(input, line); */ /* copy /FontName line */
3714 while (strstr(line, "closefile") == NULL) {
3715 putenline(output, line);
3716 n = getenline(input, line);
3719 putenline(output, line);
3720 flushencrypt(output); // ???
3722 /* A problem here if the font has junk at the end of binary section ... */
3723 /* Will this `fix' screw up treatment of Mac fonts ? */
3725 /* 96/Feb/22 deal with junk at end of encrypted section */
3726 /* Looking for M-@C-A (ASCII section heading) for PFB */
3727 /* Looking for EOL for PFA */
3728 /* Looking for C-@C-B for Mac */
3730 long current = ftell(input);
3732 while (c != 128 && c != '0' && c != 0 && c >= ' ') {
3733 sprintf(logline, " JUNK %d (%c) at byte %ld", c, c, current);
3734 showline(logline, 1);
3735 current = ftell(input);
3738 /* putc(c, output); */ /* ??? */
3739 ungetc(c, input); /* ??? */
3742 /* task = "adding zeros & cleartomark"; */
3743 task = "copying ASCII section at end";
3745 /* putzeros(output, nestedflag); */ /* add zeros at end */
3747 if (c != '\n') (void) ungetc(c, input); /* ??? */
3748 // putc('\n', output); /* for PFB not for PFA ? */
3749 PSputc('\n', output); /* for PFB not for PFA ? */
3750 while (extgetline(input, line) != EOF) { /* new way to finish off */
3751 /* fputs(line, output); */
3752 /* Try and strip out that old Adobe crap checking for existing font ! */
3753 /* Also junk in Fontographer style fonts */ /* 1992/Aug/21 */
3754 /* Used in Courier, Helvetica for example */
3755 /* if (stripchecking != 0 && syntheticflag == 0) { */
3756 if (stripchecking != 0) {
3757 if ((s = strstr(line, "{restore}")) != NULL) {
3759 if ((t = strstr(line, "cleartomark")) != NULL) {
3761 *s++ = '\0'; /* cut off after cleartomark */
3762 // fputs(line, output); /* 1992/Aug/20 */
3763 PSputs(line, output); /* 1992/Aug/20 */
3765 if (stripcomment == 0) { /* 1995/May/14 */
3766 // fputs("% font wrapper removed\n", output);
3767 PSputs("% font wrapper removed\n", output);
3772 // fputs(line, output);
3773 PSputs(line, output);
3776 endresource(output); /* share some code */
3778 showline(" WARNING: broken wrapper ", 1); /* 1992/Oct/7 */
3779 return 1; /* indicate success */
3782 /* This is very specific for output from PKTOPS */
3783 /* Does not provide for encoding vector */
3784 /* Does not provide for remapping */
3785 /* First cues on `cleartomark' after encrypted stuff */
3786 /* (OR: cues on second line that starts with "}def" if unencrypted */
3787 /* Then cues on `definefont' at end of font */
3789 /* returns 0 if failed right away */
3791 /* int extracttype3(FILE *output, FILE *input, int i) { */
3792 int extracttype3 (FILE *output, FILE *input, int i, char *fontnamek)
3794 int nchar, copyflag, endflag, count;
3799 /* printf("%s", fontnamek); */ /* 1995/Mar/1 */
3800 showline(fontnamek, 0);
3803 /* putc('*', stdout); */ /* 1995/Mar/1 */
3807 // wantchrs = fontchar + MAXCHRS * i;
3808 wantchrs = fontchar[i];
3809 if (wantchrs == NULL) showline(" BAD wantchrs", 1);
3810 /* property = fontproper[i]; */
3811 /* vector = fontvector[i]; */
3813 (void) getline(input, line);
3814 if (*line != '%' || *(line + 1) != '!') {
3815 showline(" Nonstandard font file start: ", 1);
3819 if (strstr(line, "Type1") != NULL || strstr(line, "Font-1") != NULL) {
3820 type3flag = 0; /* well, maybe let try Type 1 then ! */
3822 return 0; /* indicate lack of success */
3824 if (verboseflag) showline(" BITMAP", 0);
3825 if (stripcomment == 0) {
3826 beginresource(output, filefontname); /* share code */
3827 // fputs(line, output);
3828 PSputs(line, output);
3829 if (wantcreation != 0) {
3830 (void) getline(input, line);
3831 if (*line != '%' || strncmp(line, "%%CreationDate", 14) == 0)
3832 // fputs(line, output);
3833 PSputs(line, output);
3836 /* fprintf(output, "%s", line); */
3838 count = 0; /* number of lines starting with "}def" seen so far */
3840 if (getrealline(input, line) == 0) {
3841 sprintf(logline, " Unexpected EOF (%s)\n", "extracttype3");
3842 showline(logline, 1);
3844 break; /* was: return -1; */
3846 if (strstr(line, "serverdict") == NULL) { /* omit serverdict line ! */
3847 // fputs(line, output);
3848 PSputs(line, output);
3850 if (strstr(line, "cleartomark") != NULL) break; /* end preamble ? */
3851 if (strncmp(line, "}def", 4) == 0) { /* end preamble ? */
3852 if (count++ >= 1) break;
3856 /* now copy across character bitmaps */
3858 endflag = 0; /* set when `definefont' seen ... */
3860 if (getrealline(input, line) == 0) { /* EOF */
3863 if (*line == '/') { /* replace fontname ??? */
3864 if ((s = strstr(line, "/FontName")) != NULL) {
3865 /* if (sscanf(s, "/FontName /%s", realfontname) > 0) */
3866 s += 9; /* step over `/FontName' */
3867 while (*s != '/' && *s != '\0') s++; /* 1993/Aug/15 */
3868 if (sscanf(s, "/%s", realfontname) > 0) {
3869 lowercase(realfontname, realfontname); /* why ? */
3871 /* check whether TeX font */ /* code inserted 1996/May/20 */
3872 texfont = 0; /* 1992/Dec/22 */
3873 if (istexfont(realfontname) != 0) {
3874 /* also check if actually one of 75 TeX fonts (what about LATEX, SliTeX) ? */
3875 texfont = 1; standard = 0;
3877 if (bSubRealName != 0) {
3878 /* we normally do this these days ... */
3879 /* replaced following single line by code for prefix 96/May/20 ... */
3880 /* sprintf(line, "/FontName /%s def\n", filefontname); */
3881 strcpy(line, "/FontName /");
3882 /* look at fontprefix here also */
3883 // if (strcmp(fontprefix, "") != 0)
3884 if (fontprefix != NULL)
3885 strcat(line, fontprefix);
3886 if (uppercaseflag != 0 && texfont != 0)
3887 uppercase(filefontname, filefontname);
3888 /* if(_stricmp(filefontname, realfontname) == 0)
3889 strcpy(filefontname, realfontname); */ /* ??? */
3890 strcat(line, filefontname);
3891 strcat(line, " def\n"); /* down to here */
3898 // fputs(line, output);
3899 PSputs(line, output);
3900 if (strstr(line, "definefont") != NULL) { /* end of font */
3906 /* printf(" found definefont"); */ /* debugging */
3910 /* presently assuming simple numeric code - no encoding vector */
3911 if (sscanf(line, "/a%d ", &nchar) == 1)
3913 copyflag = wantchrs[nchar];
3914 /* printf(" (%d %d)", nchar, copyflag); */ /* debugging */
3915 if (copyflag != 0) {
3916 // fputs(line, output);
3917 PSputs(line, output);
3919 /* else putc('@', stdout); */ /* debugging */
3921 if (getrealline(input, line) == 0) {
3922 sprintf(logline, " Unexpected EOF (%s)\n", "extracttype3");
3923 showline(logline, 1);
3924 break; /* was: return -1; */
3926 if (copyflag != 0) {
3927 // fputs(line, output);
3928 PSputs(line, output);
3930 if (*line == '>') break; /* end of this CharDef */
3934 // fputs(line, output);
3935 PSputs(line, output);
3937 if (bAbort) abortjob(); /* 1992/Nov/24 */
3940 endresource(output);
3941 return 1; /* indicate success */
3944 void complainbadfont (int flag) {
3945 sprintf(logline, " Bad Font File %d", flag);
3946 showline(logline, 1);
3948 checkexit(1); /* this is pretty serious ! */
3951 void newcopyascii (FILE *output, FILE *input, unsigned long len)
3955 // unsigned char buffer[MAXLINE];
3956 char buffer[MAXLINE+1];
3959 // m = sizeof(buffer);
3960 m = sizeof(buffer-1); // leave space for null
3961 if (len < m) m = (size_t) len;
3962 while ((n = fread(buffer, 1, m, input)) != 0) {
3963 // for (k = 0; k < n; k++) if (buffer[k] == '\r') buffer[k] = '\n';
3965 // replace return with newlinw:
3966 while ((s = strchr(s, '\r')) != NULL) *s='\n';
3967 // fwrite(buffer, 1, n, output);
3968 buffer[n] = '\0'; // terminate for PSputs
3969 PSputs(buffer, output); // 99/Aug/13
3971 if (len <= 0) break;
3972 if (len < m) m = (size_t) len; // last bit
3973 /* printf(" len %lu n %u m %u", len, n, m); */
3979 void newcopybinary (FILE *output, FILE *input, unsigned long len)
3982 unsigned char inbuffer[COLUMNS / 2];
3983 char outbuffer[COLUMNS + 2]; // space for \n and null
3987 m = sizeof(inbuffer);
3988 if (len < m) m = (size_t) len;
3989 while ((n = fread(inbuffer, 1, m, input)) != 0) {
3991 for (k = 0; k < n; k++) {
3995 if (c > 9) c = c + 'A' - 10;
3997 if (d > 9) d = d + 'A' - 10;
3999 outbuffer[kk++] = (char) c;
4000 outbuffer[kk++] = (char) d;
4002 // fwrite(outbuffer, 2, n, output);
4003 outbuffer[kk++] = '\n';
4004 outbuffer[kk++] = '\0'; // terminate for PSPuts
4005 PSputs(outbuffer, output); // 99/Aug/13
4006 // putc('\n', output);
4007 // PSputc('\n', output);
4009 if (len <= 0) break;
4010 if (len < m) m = (size_t) len; // last bit
4014 /* Needed in dvispeci.c to deal with %%IncludeResource: font & %%IncludeFont */
4015 /* Do the dumbest possible thing - treat only plain PFA & PFB formats */
4016 /* called from dvispeci.c */
4018 int decompressfont (FILE *output, FILE *input, char *FontName)
4025 beginresource(output, FontName);
4028 if (c != 128) { /* we have to assume it is PFA format */
4029 newcopyascii(output, input, 0xFFFFFFFF);
4033 c = getc(input); d = getc(input);
4040 len = readlength(input);
4041 /* printf(" ASCII %lu", len); */
4042 newcopyascii(output, input, len);
4044 case 2: /* Binary */
4045 len = readlength(input);
4046 /* printf(" BINARY %lu", len); */
4047 newcopybinary(output, input, len);
4051 /* printf(" EOF"); */
4060 endresource(output);
4064 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
4065 /* check whether we need any font substitution */
4066 int needsubstitute(void)
4070 for (k = 0; k < fnext; k++)
4072 if (fontsubflag[k] >= 0)
4074 proper = fontproper[k];
4075 if ((proper & C_RESIDENT) != 0) continue;
4076 if ((proper & C_REMAPIT) != 0) continue;
4077 if ((proper & C_DEPENDENT) != 0) continue; /* NEW */
4078 /* if ((proper & C_UNUSED) != 0) continue; */ /* ??? */
4079 /* if (strcmp(fontname[k], subfontname[k]) == 0) continue; */ /* ? */
4080 /* font k occurs at other size already if fontname[k] == subfontname[k] */
4081 /* if ((proper & C_ALIASED) != 0) continue; */
4088 /* check to see if some resident fonts are remapped */
4095 /* return positive if bWindowsFlag != 0 and some residents 93/Oct/4 */
4096 /* returns negative if at least one font needs some other remapping */
4098 for (k=0; k < fnext; k++) {
4099 proper = fontproper[k];
4100 /* if ((fontproper[k] & C_REMAPIT) != 0 &&
4101 (fontproper[k] & C_RESIDENT) != 0) */
4102 if ((proper& C_RESIDENT) != 0) { /* 93/Oct/4 */
4103 if ((proper & C_REMAPIT) != 0) return -1;
4104 /* if (*textencoding != 0) winflag++; else */ /* 94/Dec/17 */
4105 if (bWindowsFlag != 0) winflag++; /* was just this */
4106 /* special case sy = Symbol and zd = ZapfDingbats ? */ /* 94/Feb/3 */
4107 /* if (bWindowsFlag != 0) {
4108 strcpy(font, fontname + k * MAXTEXNAME);
4109 if (strcmp(font, "sy") != 0 &&
4110 strcmp(font, "zd") != 0)
4112 } */ /* resident and not sy or zd */
4117 } /* only if remapped font is also printer resident */
4119 /* returns total number of substitutes so far */
4121 /* read font substitution */
4122 int readsubstitutes (FILE *input)
4124 char oldname[FNAMELEN], newname[FNAMELEN], vector[FNAMELEN];
4125 int n, nlen, nnames, property;
4127 int k=ksubst; /* 1994/Feb/4 */
4132 sprintf(logline, "Reading `%s'\n", fontsubfile); /* debugging */
4133 showline(logline, 0);
4135 while (getrealline(input, line) != 0) {
4136 if (*line == '%' || *line == ';') continue; /* 92/Oct/30 */
4137 property = 0; /* reset resident/forced/remap flag */
4139 /* nnames = sscanf(line, "%s %s%n", oldname, newname, &n); */
4140 s = line; /* 1993/Nov/6 */
4141 while (*s == ' ' || *s == '\t') s++; /* ignore white space */
4142 nnames = sscanf(s, "%s %s%n", oldname, newname, &n);
4143 if (avoidreside != 0 && nnames == 2) { /* 1993/July/15 */
4144 /* not sure this is safe? what if using this for alias ? */
4145 strcpy(newname, oldname); /* replace PS FontName ??? */
4148 /* just one name given */
4149 if (complainflag) { /* eventually flush this error message ? */
4150 sprintf(logline, "No substitute specified: %s", line);
4151 showline(logline, 1);
4153 strcpy(newname, ""); /* ??? */
4154 /* strcpy(newname, oldname); */ /* ??? */
4155 /* property |= (C_FORCESUB | C_RESIDENT); */
4156 property |= C_FORCESUB; /* 1993/May/19 */
4158 else if (strcmp(newname, oldname) == 0) {
4159 /* `old' name same as `new' name */
4160 if (complainflag) { /* eventually flush this error message ? */
4161 sprintf(logline, "Substitute same as original: %s", line);
4162 showline(logline, 1);
4164 /* property |= (C_FORCESUB | C_RESIDENT); */
4165 property |= C_FORCESUB; /* 1993/May/19 */
4167 if (strchr(newname, '*') != NULL) {
4168 /* only one name given */
4169 if (complainflag) { /* eventually flush this error message ? */
4170 sprintf(logline, "No substitute specified: %s", line);
4171 showline(logline, 1);
4173 strcpy(newname, oldname); /* ??? */
4174 n = (int) strlen(oldname); /* step only over first name */
4175 /* property |= (C_FORCESUB | C_RESIDENT); */
4176 property |=C_FORCESUB; /* 1993/MAY/19 */
4177 /* errcount(0); */ /* continue; */
4179 // if ((nlen = strlen(oldname)) >= MAXTEXNAME)
4180 if ((nlen = strlen(oldname)) > sizeof(oldname)-1) { /* FNAMELEN */
4181 sprintf(logline, " Font name too long: %s (%d > %d)",
4182 oldname, nlen, sizeof(oldname)-1);
4183 showline(logline, 1);
4184 // *(oldname + MAXTEXNAME - 1) = '\0';
4185 *(oldname + sizeof(oldname)-1) = '\0';
4186 /* errcount(0); */ /* 1995/July/27 */
4189 // if ((nlen = strlen(newname)) >= MAXFONTNAME) {
4190 if ((nlen = strlen(newname)) > sizeof(newname)-1) { /* FNAMELEN */
4191 sprintf(logline, " Font name too long: %s (%d > %d)",
4192 newname, nlen, sizeof(newname)-1);
4193 showline(logline, 1);
4194 // *(newname + MAXFONTNAME - 1) = '\0';
4195 *(newname + sizeof(newname)-1) = '\0';
4196 /* errcount(0); */ /* 1995/July/27 */
4200 /* try and analyze flags of form *xyz* on substitution line */
4203 s +=n; /* 1993/Nov/6 */
4204 if (*s <= ' ') *s++='\0'; /* isolate start of line */
4207 sd = strtok(s, " \t\n\r"); /* get next token */
4208 while (sd != NULL) {
4209 if (*sd == '%') break; /* 1992/Aug/24 */
4210 if (*sd == ';') break; /* 1995/Mar/5 */
4211 if (strchr(sd, '*') == NULL) {
4213 "Do not recognize `%s' in font substitution for: %s\n",
4215 showline(logline, 1);
4218 else if (strcmp(sd, RESIDENT) == 0) property |= C_RESIDENT;
4219 else if (strcmp(sd, FORCESUB) == 0) property |= C_FORCESUB;
4220 else if (strcmp(sd, ALIASED) == 0) {
4221 property |= C_ALIASED;
4224 /* COMPOUND & HYBRID just for backward compatability ... */
4225 else if (strcmp(sd, SYNTHETIC) == 0 ||
4226 strcmp(sd, COMPOUND) == 0 ||
4227 strcmp(sd, HYBRID) == 0) {
4228 property |= C_SYNTHETIC;
4231 else if (strcmp(sd, MTMI) == 0) property |= C_MTMI;
4232 else if (strcmp(sd, EPSF) == 0) property |= C_EPSF; /* 94/Aug/15 */
4233 /* else if (strcmp(sd, CONTROL) == 0) property |= C_CONTROL; */ /* 95/Oct/15 */
4234 else if (strcmp(sd, REMAPIT) == 0) {
4235 property |= C_REMAPIT; /* remap */
4236 strcpy(vector, "textext"); /* default */
4237 sd = strtok(NULL, " \t\n\r"); /* try and find vector */
4239 /* if no encoding vector given, then use default and go on */
4240 if (strchr(sd, '*') != NULL) continue;
4241 strncpy(vector, sd, 12+1); /* file-name + extension */
4242 /* strip off extension, if any - assumes it is "vec" ... */
4243 if ((u = strchr(vector, '.')) != NULL) *u = '\0';
4244 /* limit to eight characters - otherwise not file name */
4245 if (strlen(vector) > 8) vector[8] = '\0';
4246 /* if (verboseflag) printf("vector is %s\n", vector); */
4249 else if (strncmp(sd, "*user-", 6) == 0) {
4250 /* Paul Anagnostopolous memorial hack to allow user-defined markers */
4254 "Do not recognize `%s' in font substitution for: %s\n",
4256 showline(logline, 1);
4259 sd = strtok(NULL, " \t\n\r"); /* advance to next token */
4262 /* avoid problem when only one font name, or first name equals second name */
4263 if ((property & C_SYNTHETIC) != 0) {
4264 property &= ~C_FORCESUB; /* 1993/Nov/7 */
4267 if (forcereside != 0) {
4268 property |= C_RESIDENT; /* 1992/July/5 */
4269 property |= C_FORCESUB; /* 1992/July/5 */
4272 if (avoidreside != 0) {
4273 property &= ~C_RESIDENT; /* 1993/March/26 */
4274 /* not sure the following makes sense 1993/July/15 */
4275 /* property &= ~C_FORCESUB; */ /* 1993/March/26 */
4278 /* above checks that all items where recognized ??? */
4280 /* *(oldname + MAXTEXNAME - 1) = '\0'; */ /* redundant ? */
4281 /* strncpy(fontsubfrom[k], oldname, MAXTEXNAME); */
4282 /* *(newname + MAXTEXNAME - 1) = '\0'; */ /* redundant ? */
4283 /* strncpy(fontsubto[k], newname, MAXFONTNAME); */
4284 /* strncpy(fontsubvec[k], vector, MAXVECNAME); */
4285 // oldname[MAXTEXNAME-1]='\0'; /* prevent disaster */
4286 *(oldname + sizeof(oldname)-1) = '\0'; /* prevent disaster */
4287 // newname[MAXFONTNAME-1]='\0'; /* prevent disaster */
4288 *(newname + sizeof(newname)-1) = '\0'; /* prevent disaster */
4289 // vector[MAXVECNAME-1]='\0'; /* prevent disaster */
4290 *(vector + sizeof(vector)-1) = '\0'; /* prevent disaster */
4291 // strcpy(fontsubfrom + k * MAXTEXNAME, oldname);
4292 if (fontsubfrom[k] != NULL) free(fontsubfrom[k]);
4293 fontsubfrom[k] = zstrdup(oldname);
4294 // strcpy(fontsubto + k * MAXFONTNAME, newname);
4295 if (fontsubto[k] != NULL) free(fontsubto[k]);
4296 fontsubto[k] = zstrdup(newname);
4297 // strcpy(fontsubvec + k * MAXVECNAME, vector); /* 1994/Feb/2 */
4298 if (fontsubvec[k] != NULL) free(fontsubvec[k]);
4299 fontsubvec[k] = zstrdup(vector);
4300 fontsubprop[k] = property;
4301 /* printf("FROM %s TO %s VECTOR %s ", oldname, newname, vector);
4302 printf("PROPERTY %d\n", property); */
4304 /* if we are being forced to download & no other flags on, ignore */
4305 /* if (avoidreside != 0 && (property & ~C_FORCESUB) == 0) */
4306 /* if no substitution & at most *force* on, then ignore it */
4307 if (strcmp(newname, oldname) == 0 && (property & ~C_FORCESUB) == 0)
4308 continue; /* 1993/July/16 */
4311 count++; /* 1995/July/30 */
4312 if (k >= maxsubstitute-1) {
4313 /* fprintf(errout, " Too many font subs (> %d)", maxsubstitute);*/
4319 if (count >= maxsubstitute-1) { /* moved here 95/July/30 - avoid repeat */
4320 sprintf(logline, " WARNING: Too many font subs (%d > %d)\n",
4321 count, maxsubstitute);
4322 showline(logline, 1);
4325 ksubst = k; /* remember number of entries in substitution table */
4326 /* fclose(input); */ /* 1994/Feb/4 */
4327 /* if (traceflag) showsubtable(stdout); */ /* an experiment */
4331 /* See whether font file can be found */
4333 /* This tries each pathname on the searchpath - for each pathname: */
4334 /* - tries in order .pfb, .pfa, no extension (Mac format), */
4335 /* - then tries underscores: __.pfb, and __.pfa */
4336 /* - then tries .pss (Multiple Master Stub File) 94/Dec/6 */
4337 /* - and last tries .ps - assumed to be font produced by PKTOPS */
4338 /* leaves result bits in instanceflag (MM), pssflag (MM), type3flag */
4342 /* try and open a font */
4343 FILE *OpenFont_Sub (char *font)
4346 static char fn_in[FNAMELEN]; /* preserve ? why ? */
4348 task = "trying to open font file";
4349 if (font == NULL) return NULL;
4350 type3flag = 0; /* start by assuming Type 1 font */
4351 pssflag = 0; /* start by assuming not PSS stub */
4352 instanceflag = 0; /* start by assuming not MM instance via PFM */
4354 if (fontpath == NULL) return NULL;
4355 strcpy(fn_in, font);
4356 forceexten(fn_in, "pfb"); /* Try PFB form */
4357 if ((fp_in = findandopen(fn_in, fontpath, NULL, "rb", currentfirst)) != NULL)
4359 forceexten(fn_in, "pfa"); /* Try PFA form */
4360 if((fp_in = findandopen(fn_in, fontpath, NULL, "rb", currentfirst)) != NULL)
4362 removeexten(fn_in); /* Try Mac form */
4363 if ((fp_in = findandopen(fn_in, fontpath, NULL, "rb", currentfirst)) != NULL)
4365 if (tryunderscore != 0) { /* try with underscores */
4366 /* underscore(fn_in); */
4367 if (underscore(fn_in)) {
4368 forceexten(fn_in, "pfb"); /* Try PFB form */
4369 if((fp_in = findandopen(fn_in, fontpath, NULL, "rb", currentfirst)) != NULL)
4371 forceexten(fn_in, "pfa"); /* Try PFA form */
4372 if((fp_in = findandopen(fn_in, fontpath, NULL, "rb", currentfirst)) != NULL)
4377 /* Now deal with ATM 4.0 way of doing multiple masters 97/June/1 */
4378 removeexten(fn_in); /* remove extension again */
4379 removeunder(fn_in); /* remove underscores again */
4380 forceexten(fn_in, "pfm"); /* MM PFM file 97/June/1 */
4381 /* check in listed directories *and* PFM subdirectories */
4382 if ((fp_in = findandopen(fn_in, fontpath, NULL, "rb", -1)) != NULL) {
4383 /* check whether ordinary PFM or MM instance PFM file */
4385 sprintf(logline, "Found %s\n", fn_in); /* debugging */
4386 showline(logline, 0);
4391 if (tryunderscore != 0) { /* try with underscores */
4392 if (underscore(fn_in)) {
4393 if ((fp_in = findandopen(fn_in, fontpath, NULL, "rb", currentfirst)) != NULL) {
4394 /* check whether ordinary PFM or MM instance PFM file */
4396 sprintf(logline, "Found %s\n", fn_in); /* debugging */
4397 showline(logline, 0);
4405 /* Now deal with older way of doing multiple master fonts */
4406 removeexten(fn_in); /* remove extension again */
4407 removeunder(fn_in); /* remove underscores again */
4408 forceexten(fn_in, "pss"); /* MM PSS stub file 94/Dec/6 */
4409 if ((fp_in = findandopen(fn_in, fontpath, NULL, "rb", currentfirst)) != NULL) {
4410 pssflag = 1; /* make a note */
4414 /* Now deal with old Type 3 PK font files made by PKTOPS */
4415 forceexten(fn_in, "ps"); /* try PKTOPS output format */
4416 if ((fp_in = findandopen(fn_in, fontpath, NULL, "rb", currentfirst)) != NULL) {
4417 type3flag = 1; /* not reliable - test later */
4420 return NULL; /* all variations failed ! */
4424 /* try and open a font */
4425 FILE *OpenFont_Sub (char *font)
4428 char *searchpath, *s;
4429 static char fn_in[FNAMELEN]; /* preserve ? why ? */
4431 task = "trying to open font file";
4432 if (font == NULL) return NULL;
4433 type3flag = 0; /* start by assuming Type 1 font */
4434 if (fontpath == NULL) return NULL;
4435 searchpath = fontpath;
4437 if ((searchpath=nextpathname(fn_in, searchpath)) == NULL) break;
4438 s = fn_in + strlen(fn_in) - 1;
4439 if (*s != ':' && *s != '\\' && *s != '/') strcat(fn_in, "\\");
4440 strcat(fn_in, font); /* use makefilename ??? */
4441 forceexten(fn_in, "pfb"); /* try .pfb first */
4442 if ((fp_in = fopen(fn_in, "rb")) != NULL) return fp_in;
4443 forceexten(fn_in, "pfa"); /* try .pfa next */
4444 if ((fp_in = fopen(fn_in, "rb")) != NULL) return fp_in;
4445 removeexten(fn_in); /* try Mac form next */
4446 if ((fp_in = fopen(fn_in, "rb")) != NULL) return fp_in;
4447 if (tryunderscore != 0) { /* try underscore form ? */
4448 /* underscore(fn_in); */
4449 if (underscore(fn_in)) { /* 95/May/28 */
4450 forceexten(fn_in, "pfb"); /* try .pfb first */
4451 if ((fp_in = fopen(fn_in, "rb")) != NULL) return fp_in;
4452 forceexten(fn_in, "pfa"); /* try .pfa next */
4453 if ((fp_in = fopen(fn_in, "rb")) != NULL) return fp_in;
4456 removeexten(fn_in); /* remove extension again */
4457 removeunder(fn_in); /* remove underscores again */
4458 forceexten(fn_in, "ps"); /* try PKTOPS output format */
4459 if ((fp_in = fopen(fn_in, "rb")) != NULL) { /* "r" ? */
4460 type3flag = 1; return fp_in; /* not reliable - test later */
4463 return NULL; /* all variations failed ! */
4468 typedef struct ATMRegRec {
4469 unsigned char nMMM; // directory path index for MMMName
4470 unsigned char nPFB; // directory path index for PFBName
4471 unsigned char nPFM; // directory path index for PFMName
4472 unsigned char MMMflag; // 0 => TTF, 1 => T1, 2 => MM Master, 4 => MM Instance
4473 char *FontName; // PostScript FontName
4474 char *MMMName; // File Name of PFM (T1 or MMM instance), MMM (for MM master)
4475 char *PFBName; // File Name of PFB (blank for MM instance)
4476 char *PFMName; // File Name of PFM (for MM master), MMM (for MM instance)
4479 extern struct ATMRegRec *ATMFonts;
4483 FILE *OpenFont_Reg (char *font)
4485 static char fn_in[FNAMELEN]; /* preserve ? why ? */
4490 task = "trying to open font file";
4491 if (font == NULL) return NULL;
4492 type3flag = 0; /* Type 1 font */
4496 if (useatmreg == 0) return NULL;
4497 // First look for match between DVI TFM and PFB file name
4498 for (k = 0; k < ATMfontindex; k++) {
4499 strcpy(fn_in, ATMFonts[k].PFBName);
4500 if ((s = strrchr(fn_in, '.')) != NULL) *s = '\0';
4501 if (_strcmpi(font, fn_in) == 0) {
4502 if (ATMFonts[k].MMMflag & 4) instanceflag = 1;
4503 if (! instanceflag) {
4504 strcpy(fn_in, DirPaths[ATMFonts[k].nPFB]);
4505 strcat(fn_in, ATMFonts[k].PFBName); // PFB file name
4508 strcpy(fn_in, DirPaths[ATMFonts[k].nMMM]);
4509 strcat(fn_in, ATMFonts[k].MMMName); // PFM file name
4511 input = fopen(fn_in, "rb");
4512 // sprintf(logline, " font %s match %d %s => %s (%X)\n",
4513 // font, k, ATMFonts[k].PFBName, fn_in,input);
4514 // showline(logline, 0); // debugging only
4518 if (! usepsfontname) return NULL;
4519 // Then allow for (exact) match between DVI TFM and PS FontName
4520 for (k = 0; k < ATMfontindex; k++) {
4521 if (strcmp(font, ATMFonts[k].FontName) == 0) {
4522 if (ATMFonts[k].MMMflag & 4) instanceflag = 1;
4523 if (! instanceflag) {
4524 strcpy(fn_in, DirPaths[ATMFonts[k].nPFB]);
4525 strcat(fn_in, ATMFonts[k].PFBName); // PFB file name
4528 strcpy(fn_in, DirPaths[ATMFonts[k].nMMM]);
4529 strcat(fn_in, ATMFonts[k].MMMName); // PFM file name
4531 input = fopen(fn_in, "rb");
4532 // sprintf(logline, " font %s match %d %s => %s (%X)\n",
4533 // font, k, ATMFonts[k].FontName, fn_in, input);
4534 // showline(logline, 0); // debugging only
4541 /* Rewritten 1994/March/18 to allow use of `texfonts.map' */
4542 /* Note that the name in the font-tables is *not* changed */
4543 /* We only grab a file under a different name and open it */
4544 /* On screen output, replaced PS FontName etc uses the name in the DVI file */
4546 /* try and open a font */
4547 FILE *OpenFont (char *font, int aliasflag)
4552 if (font == NULL) return NULL; /* sanity check */
4553 /* first try name as given */
4554 if (useatmreg) input = OpenFont_Reg(font);
4555 if (input != NULL) return input;
4556 input = OpenFont_Sub(font);
4557 if (input != NULL) return input;
4558 /* if (aliasflag && bTexFontsMap) { */ /* allowed to use texfonts.map? */
4559 /* time for aliases? allowed to use texfonts.map? or have we already used? */
4560 if (aliasflag && bTexFontsMap && ! bForceFontsMap) {
4561 aliasname = alias(font); /* in dvipslog.c */
4562 if (aliasname != NULL) {
4564 sprintf(logline, " font %s alias %s\n", font, aliasname);
4565 showline(logline, 0);
4567 if (useatmreg) input = OpenFont_Reg(font);
4568 if (input != NULL) return input;
4569 input = OpenFont_Sub(aliasname); /* with some luck we find it */
4570 if (input != NULL) return input;
4576 char fn_pfm[FNAMELEN]; /* preserve ? why ? */
4578 /* try and open a PFM file */
4579 FILE *openpfm (char *font)
4582 /* static char fn_in[FNAMELEN]; */ /* preserve ? why ? */
4583 #ifndef SUBDIRSEARCH
4588 if (fontpath == NULL) return NULL;
4591 strcpy(fn_pfm, font);
4592 forceexten(fn_pfm, "pfm"); /* force .pfm */
4593 fp_in = findandopen(fn_pfm, fontpath, NULL, "rb", currentfirst);
4594 if (fp_in != NULL) return fp_in;
4597 /* underscore (fn_pfm); */
4598 if (underscore (fn_pfm)) { /* 95/May/28 */
4599 fp_in = findandopen(fn_pfm, fontpath, NULL, "rb", currentfirst);
4600 if (fp_in != NULL) return fp_in;
4603 strcpy(fn_pfm, "pfm\\");
4604 strcat(fn_pfm, font);
4605 forceexten(fn_pfm, "pfm"); /* force .pfm */
4606 fp_in = findandopen(fn_pfm, fontpath, NULL, "rb", currentfirst);
4607 if (fp_in != NULL) return fp_in;
4610 /* underscore (fn_pfm); */
4611 if (underscore (fn_pfm)) { /* 95/May/28 */
4612 fp_in = findandopen(fn_pfm, fontpath, NULL, "rb", currentfirst);
4613 if (fp_in != NULL) return fp_in;
4617 searchpath = fontpath;
4619 if ((searchpath=nextpathname(fn_pfm, searchpath)) == NULL) break;
4620 s = fn_pfm + strlen(fn_pfm) - 1;
4621 if (*s != ':' && *s != '\\' && *s != '/') strcat(fn_pfm, "\\");
4623 strcat(fn_pfm, font); /* use makefilename ??? */
4624 forceexten(fn_pfm, "pfm"); /* force .pfm */
4625 if ((fp_in = fopen(fn_pfm, "rb")) != NULL) return fp_in;
4626 if (tryunderscore != 0) { /* try underscore form ? */
4627 /* underscore(fn_pfm); */
4628 if (underscore(fn_pfm)) { /* 95/May/28 */
4629 forceexten(fn_pfm, "pfm");
4630 if ((fp_in = fopen(fn_pfm, "rb")) != NULL) return fp_in;
4633 strcpy(t, "pfm\\"); /* try in subdirectory */
4634 strcat(fn_pfm, font); /* use makefilename ??? */
4635 forceexten(fn_pfm, "pfm"); /* force .pfm */
4636 if ((fp_in = fopen(fn_pfm, "rb")) != NULL) return fp_in;
4637 if (tryunderscore != 0) { /* try underscore form ? */
4638 /* underscore(fn_pfm); */
4639 if (underscore(fn_pfm)) { /* 95/May/28 */
4640 forceexten(fn_pfm, "pfm");
4641 if ((fp_in = fopen(fn_pfm, "rb")) != NULL) return fp_in;
4648 sprintf(logline, "Failed to open %s\n", fn_pfm); /* debugging only */
4649 showline(logline, 0);
4651 return NULL; /* all variations failed ! */
4654 /* first look for same font different sizes */
4655 void flagduplicates (void)
4661 for (k = 0; k < fnext; k++) { /* look for duplicate names first ! */
4662 if (fontsubflag[k] >= 0) continue; /* ? */ /* mapped already */
4663 for (i = k + 1; i < fnext; i++) {
4664 // if (strcmp(fontname[k], fontname[i]) == 0)
4665 if (fontname[k] != NULL && fontname[i] != NULL &&
4666 strcmp(fontname[k], fontname[i]) == 0) {
4667 // if (strcmp(fontname + k * MAXTEXNAME,
4668 // fontname + i * MAXTEXNAME) == 0)
4669 /* strcpy(subfontname[i], fontname[k]); */ /* ??? test ??? */
4670 // strcpy(subfontname + i * MAXFONTNAME,
4671 // fontname + k * MAXTEXNAME);
4672 if (subfontname[i] != NULL) free(subfontname[i]);
4673 subfontname[i] = zstrdup(fontname[k]);
4674 fontproper[i] |= C_DEPENDENT; /* NEW */
4675 /* if (fontproper[k] & C_RESIDENT)
4676 fontproper |= C_RESIDENT; */ /* 95/July/5 ??? */
4677 /* flag it as dependent - that is, another size of the same thing */
4678 /* following USED to be the way to test: */
4679 /* font k occurs at other size already if fontname[k] == subfontname[k] */
4680 /* strcpy(subfontname[i], subfontname[k]); */ /* ??? test ??? */
4681 /* fontproper[i] = fontproper[k]; */ /* ??? test ??? */
4682 fontsubflag[i] = k; /* point to substitute */
4683 fromfont = fontchar[i];
4684 // fromfont = fontchar + MAXCHRS * i;
4685 tofont = fontchar[k];
4686 // tofont = fontchar + MAXCHRS * k;
4687 if (fromfont == NULL) {
4688 sprintf(logline, " BAD fromfont %d ", i);
4689 showline(logline, 1);
4691 if (tofont == NULL) {
4692 sprintf(logline, " BAD tofont %d ", k);
4693 showline(logline, 1);
4695 for (j = 0; j < MAXCHRS; j++)
4696 if (fromfont[j] != 0) tofont[j] = 1; /* combine req */
4702 /* look up in substitution table what this font maps to */
4704 /* int fontremapsub (char *font) { */ /* expects lower case fontname */
4705 /* expects lower case fontname */
4706 int fontremapsub (char *font)
4710 if (font == NULL) return -1;
4711 for (k = 0; k < ksubst; k++) {
4712 /* if (strcmp(font, fontsubfrom[k]) == 0) */
4713 // if (strcmp(font, fontsubfrom + k * MAXTEXNAME) == 0)
4714 if (fontsubfrom[k] != NULL &&
4715 strcmp(font, fontsubfrom[k]) == 0)
4718 return -1; /* didn't find a substitute */
4721 /* WARNING: following writes back into argument */
4722 /* NOT ANYMORE IT DOESN'T - now caller needs to pick up fontsubto[k] */
4724 /* expects lower case fontname */
4725 int fontremap (char *font)
4728 // char oldname[MAXFONTNAME];
4729 char oldname[FNAMELEN];
4730 // char newname[MAXFONTNAME];
4731 char newname[FNAMELEN];
4733 if (font == NULL) return -1;
4734 if ((k = fontremapsub(font)) >= 0)
4736 // strcpy(newname, fontsubto + k * MAXFONTNAME);
4737 strcpy(newname, fontsubto[k]);
4738 if (verboseflag && quietflag == 0 &&
4739 /* ((fontsubprop[k] & C_REMAPIT) == 0)) */ /* ??? */
4740 ((fontsubprop[k] & C_RESIDENT) == 0)) {
4741 /* fprintf(stdout, "Substituting %s for %s\n", fontsubto[k], font);*/
4742 strcpy(oldname, font);
4743 sprintf(logline, "Substituting %s for %s\n", newname, oldname);
4744 showline(logline, 1);
4746 /* strcpy(font, fontsubto[k]); */ /* write back into argument */
4747 /* strcpy(font, fontsubto + k * MAXFONTNAME); */ /* back into argument */
4748 // strcpy(font, newname); /* NO! */
4750 return k; /* pointer to substitute */
4753 /* need also copy across fontsubprop[k] to fontproper[.] ? */
4754 /* not announce if its just a remap ? */
4755 /* not announce if its just printer resident ? */
4757 /* see whether this font is being forced to be substituted */
4758 /* expects lower case fontname */
4759 int forcedsubstitute (char *font)
4763 if (font == NULL) return -1;
4764 for (k = 0; k < ksubst; k++)
4766 if ((fontsubprop[k] & C_FORCESUB) != 0 &&
4767 /* if (((fontsubprop[k] & C_FORCESUB) != 0 || */ /* NO */
4768 /* (fontsubprop[k] & C_RESIDENT) != 0) && *//* 1992/July/4 */
4769 /* strcmp(font, fontsubfrom[k]) == 0) { */
4770 // strcmp(font, fontsubfrom + k * MAXTEXNAME) == 0) {
4771 fontsubfrom[k] != NULL &&
4772 strcmp(font, fontsubfrom[k]) == 0) {
4773 /* if (verboseflag && quietflag == 0)
4774 fprintf(stdout, "Forcing substitute %s for %s\n",
4775 fontsubto[k], font) */
4776 /* strcpy(font, fontsubto[k]); */ /* later */
4777 return k; /* pointer to substitute */
4780 return -1; /* didn't find a forcing substitution */
4783 /* is this font synthetic based on substitution table -- 1993/Nov/6 */
4784 /* expects lower case fontname */
4785 int checksynthetic (char *font)
4789 if (font == NULL) return -1;
4790 for (k = 0; k < ksubst; k++) {
4791 if ((fontsubprop[k] & C_SYNTHETIC) != 0 &&
4792 // strcmp(font, fontsubfrom + k * MAXTEXNAME) == 0) {
4793 fontsubfrom[k] != NULL &&
4794 strcmp(font, fontsubfrom[k]) == 0) {
4795 return k; /* pointer to synthetic */
4801 /* see whether font name is being aliased based on font substitution table */
4802 /* replace aliases with real names */
4803 void replacealias (void)
4806 /* need to have these `near' for verboseflag output ... */
4807 // char newname[MAXFONTNAME];
4808 char newname[FNAMELEN];
4809 // char oldname[MAXFONTNAME];
4810 char oldname[FNAMELEN];
4812 task = "looking for aliases";
4814 for (k = 0; k < fnext; k++) {
4815 // strcpy(oldname, fontname + k * MAXTEXNAME);
4816 if (fontname[k] != NULL) strcpy(oldname, fontname[k]);
4818 /* if ((n = fontremapsub(fontname[k])) >= 0 && */
4819 /* n is index into font substitution table --- or -1 if not found */
4820 if ((n = fontremapsub(oldname)) >= 0 &&
4821 (fontsubprop[n] & C_ALIASED) != 0) {
4822 // strcpy(newname, fontsubto + n * MAXFONTNAME);
4823 strcpy(newname, fontsubto[n]);
4824 if (verboseflag && quietflag == 0) {
4825 /* strcpy(oldname, fontname + k * MAXTEXNAME); */
4826 /* printf("Using %s for %s\n", fontsubto[n], fontname[k]); */
4827 sprintf(logline, "Using %s for %s\n", newname, oldname);
4828 showline(logline, 0);
4830 /* strcpy(fontname[k], fontsubto[n]); */ /* copy real name */
4831 // strcpy(fontname + k * MAXTEXNAME, newname); /* copy real name */
4832 /* fontsubto + n * MAXFONTNAME); */ /* copy real name */
4833 if (fontname[k] != NULL) free(fontname[k]);
4834 fontname[k] = zstrdup(newname);
4839 /* see whether font name is being aliased based on texfonts.map 95/Dec/29 */
4840 /* replace aliases with real names */
4841 void replacetexfontsmap (void)
4846 // char newname[MAXFONTNAME];
4847 char newname[FNAMELEN];
4848 // char oldname[MAXFONTNAME];
4849 char oldname[FNAMELEN];
4851 task = "looking for aliases";
4853 for (k = 0; k < fnext; k++) {
4854 // strcpy(oldname, fontname + k * MAXTEXNAME);
4855 if (fontname[k] != NULL) strcpy(oldname, fontname[k]);
4856 else *oldname = '\0';
4857 /* if ((n = fontremapsub(fontname[k])) >= 0 && */
4858 /* if ((n = fontremapsub(oldname)) >= 0 &&
4859 (fontsubprop[n] & C_ALIASED) != 0) */
4860 if ((s = alias(oldname)) != NULL) {
4861 /* strcpy(newname, fontsubto + n * MAXFONTNAME); */
4863 if (verboseflag && quietflag == 0) {
4864 /* strcpy(oldname, fontname + k * MAXTEXNAME); */
4865 /* printf("Using %s for %s\n", fontsubto[n], fontname[k]); */
4866 sprintf(logline, "Using %s for %s\n", newname, oldname);
4867 showline(logline, 0);
4869 /* strcpy(fontname[k], fontsubto[n]); */ /* copy real name */
4870 // strcpy(fontname + k * MAXTEXNAME, newname); /* copy real name */
4871 /* fontsubto + n * MAXFONTNAME); */ /* copy real name */
4872 if (fontname[k] != NULL) free(fontname[k]);
4873 fontname[k] = zstrdup(newname); /* copy real name */
4879 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
4881 /* returns 0 normally, -1 on EOF, +1 if start of new section (128) */
4883 int readaline (char *line, FILE *input)
4889 c = getc(input); ungetc(c, input);
4890 if (c == EOF) return -1; /* is first character -1 ? */
4891 if (c == 128) return +1; /* is first character 128 ? */
4892 while ((c = getc(input)) != EOF && c != '\r' && c != '\n') *s++ = (char) c;
4902 /* printf("%s", line); */ /* DEBUGGING */
4906 /* find MM base file name from PS FontName of base font */
4907 /* find base font file name */ /* WORK IN PROGRESS !!!! */
4908 /* only called if bMMShortCut == 0 ??? */
4909 /* returns -1 if not OK */
4910 /* picks up PS FontName from subfontname[k] */
4911 /* puts base font file name in fontname[k] */
4913 /* Could we do this using the new ATMFonts table ??? 2000 July 7 */
4915 int FindMMBaseFile (int k)
4917 /* char FontName[MAXTEXNAME]; */ /* 95/May/25 */
4918 // char FontName[MAXFONTNAME]; /* 95/July/27 */
4919 char FontName[FNAMELEN]; /* 99/Nov/6 */
4920 char pfbname[FNAMELEN]; /* 95/May/25 */
4926 if (bMMShortCut != 0) {
4927 /* strcpy (pfbname, fontname + k * MAXTEXNAME); */
4928 return 0; /* just use first 5 chars + "___" ??? */
4930 // strcpy (FontName, subfontname + k * MAXFONTNAME);
4931 if (subfontname[k] != NULL) strcpy(FontName, subfontname[k]);
4932 else *FontName = '\0';
4935 sprintf(logline, "Trying to find MM base font PS name for %s\n", FontName);
4936 showline(logline, 0);
4939 /* strcpy (pfbname, fontname + k * MAXTEXNAME); */ /* first guess */
4940 if ((s = strchr(FontName, '_')) != NULL && s > FontName) { /* 97/June/1 */
4942 sprintf(logline, "Stripping Instance Name %s ", FontName);
4943 showline(logline, 0);
4947 sprintf(logline, "=> %s\n", FontName);
4948 showline(logline, 0);
4951 // PFB file name written back into second argument
4952 mmfile = fopenfont(FontName, pfbname, 1); // in dvispeci.c
4954 if (mmfile != NULL) {
4956 sprintf(logline, "FILE %s ", pfbname); /* 95/May/27 */
4957 showline(logline, 0);
4959 sl = removepath(pfbname); /* remove file path */
4960 if ((pe = strchr(sl, '.')) == NULL)
4961 pe = sl + strlen(sl); /* ignore extension */
4963 while (*pe == '_') pe--; /* step back over _ */
4966 *pe = '\0'; /* temporarily terminate */
4968 sprintf(logline, "=> %s\n", sl); /* 95/May/27 */
4969 showline(logline, 0);
4971 // if (strlen(sl) < MAXTEXNAME) /* 1995/July/27 */
4972 if (strlen(sl) < FNAMELEN) {
4973 // strcpy (fontname + k * MAXTEXNAME, sl);
4974 if (fontname[k] != NULL) free(fontname[k]);
4975 fontname[k] = zstrdup(sl);
4978 sprintf(logline, "Name too long: %s\n", sl);
4979 showline(logline, 1);
4981 if (pe != NULL) *pe = (char) c; /* restore what was there */
4982 /* if (bMMShortCut) return 0; */ /* already done */
4983 /* strcpy (fontname + k * MAXTEXNAME, FileName); */
4984 fclose(mmfile); /* ?? */
4985 /* printf("FOUND %s ", FileName); */ /* debugging */
4989 /* fprintf(errout, " ERROR: MM base `%s' not found\n", FontName); */
4991 sprintf(logline, " WARNING: MM base `%s' not found ", FontName);
4992 showline(logline, 1);
4994 /* errcount(0); */ /* 95/May/28 */
4995 /* just a WARNING: since it drops back to extending with "___" */
4996 /* assumed to be of form kprg_xyz --- should we check for _ ??? */
4997 /* if (strchr(pfbname, '_') != NULL) { */
4998 // strcpy (pfbname, fontname + k * MAXTEXNAME); /* 97/June/1 */
4999 if (fontname[k] != NULL) strcpy (pfbname, fontname[k]); /* 97/June/1 */
5000 else *pfbname = '\0';
5001 if (*(pfbname+4) == '_') { /* 97/June/1 */
5002 strcpy (pfbname + 5, "___"); /* last three characters */
5004 sprintf(logline, "using %s ", pfbname);
5005 showline(logline, 1);
5007 /* test for existence first ? */
5008 // strcpy (fontname + k * MAXTEXNAME, pfbname);
5009 if (fontname[k] != NULL) free(fontname[k]);
5010 fontname[k] = zstrdup(pfbname);
5012 return -1; /* NOT ok */
5016 /* get some compiler error here ??? */
5017 /* dviextra.c(4379) : fatal error C1001: internal compiler error */
5018 /* (compiler file 'msc3.cpp', line 429) */
5020 /* Called with MM instance font number */
5021 /* Finds corresponding MM base font - or adds it if not found */
5022 /* Adds characters needed by new instance */
5024 /* add the corresponding MM base 94/Dec/6 */
5025 int AddMMBase (int m)
5028 char *basewantchrs; /* wanted chars array of MM base font */
5029 char *instwantchrs; /* wanted chars array of MM instance */
5030 /* char basefontname[MAXTEXNAME]; */ /* 95/May/25 */
5031 /* char basefilename[MAXFONTNAME]; */ /* 95/May/25 */
5032 // char psfontname[MAXFONTNAME]; /* 97/June/1 */
5033 char psfontname[FNAMELEN];
5034 // char psbasename[MAXFONTNAME]; /* 97/June/1 */
5035 char psbasename[FNAMELEN];
5038 // strcpy(psfontname, subfontname + m * MAXFONTNAME);
5039 if (subfontname[m] != NULL) strcpy(psfontname, subfontname[m]);
5040 else *psfontname = '\0';
5041 /* Truncate MM instance PS FontName if that is what we have 97/June/1 */
5042 if ((s = strchr(psfontname, '_')) != NULL && s > psfontname)
5046 /* if (bMMShortCut == 0) {
5047 strcpy (stubfilename, fontname + m * MAXTEXNAME);
5048 (void) FindMMBaseFile (stubfilename, basefilename);
5049 strcpy (subfontname + m * MAXFONTNAME, basefilename);
5050 } */ /* new 95/May/25 ? */
5051 // instwantchrs = fontchar + MAXCHRS * m;
5052 instwantchrs = fontchar[m];
5053 if (fontchar[m] == NULL) showline(" BAD instwantchrs", 1);
5054 /* printf("Adding MM base for font %d\n", m); *//* debugging 95/May/25 */
5055 /* check whether we have already added this MM base font */
5056 /* for (k = mmbase; k < fnext; k++) */ /* no longer separate */
5057 for (k = 0; k < fnext; k++) { /* 95/May/14 */
5058 if ((fontproper[k] & C_MULTIPLE) == 0) continue;
5059 // strcpy(psbasename, subfontname + k * MAXFONTNAME);
5060 if (subfontname[k] != NULL) strcpy(psbasename, subfontname[k]);
5061 else *psbasename = '\0';
5062 /* old way check whether matches on first five characters of font file name */
5065 sprintf(logline, "COMPARE %s and %s\n", psbasename, psfontname);
5066 showline(logline, 0);
5069 if (bMMShortCut) { /* assume base name ends in "___" */
5070 // if (strncmp(fontname + k * MAXTEXNAME,
5071 // fontname + m * MAXTEXNAME, 5) != 0) continue;
5072 if (fontname[k] != NULL && fontname[m] != NULL &&
5073 strncmp(fontname[k], fontname[m], 5) != 0) continue;
5075 /* else new way check whether matches PS FontName in PSS stub */
5076 /* else if (strcmp(subfontname + k * MAXFONTNAME, */
5077 else if (strcmp(psbasename, psfontname) != 0) continue;
5078 /* subfontname + m * MAXFONTNAME) != 0) continue; */
5079 /* get here if we found a match */
5082 sprintf(logline, "Already installed MM base font %s %d\n", psbasename, k);
5083 showline(logline, 0);
5086 if (fontchar[k] == NULL) setupfontchar(k);
5087 // basewantchrs = fontchar + MAXCHRS * k; /* 95/May/12 */
5088 basewantchrs = fontchar[k]; /* 95/May/12 */
5089 for (i = 0; i < MAXCHRS; i++) /* or in the bits */
5090 if (instwantchrs[i] != 0) basewantchrs[i] = 1;
5097 sprintf(logline, "Need to construct new MM base entry %s\n", psfontname);
5098 showline(logline, 0);
5102 /* Get here only if MM base font not found, have to add a new MM base font */
5103 /* We construct MM base font file name from stub PSS file name */
5104 /* Typically MM base font has same name, but ends in ___ ??? */
5105 // strcpy(fontname + fnext * MAXTEXNAME, fontname + m * MAXTEXNAME);
5106 // strcpy(fontname + fnext * MAXTEXNAME + 5, "___");
5107 if (fontname[fnext] != NULL) free(fontname[fnext]);
5108 if (fontname[m] != NULL) {
5109 char buffer[FNAMELEN];
5110 strcpy(buffer, fontname[m]);
5111 strcpy(buffer+5, "___"); /* MM Master ends in ___ */
5112 fontname[fnext] = zstrdup(buffer);
5114 else fontname[fnext] = NULL;
5115 /* if (bMMShortCut == 0) { */ /* copy PS FileName from instance, exists yet ??? */
5116 /* strcpy(subfontname + fnext * MAXFONTNAME, subfontname + m * MAXFONTNAME); */
5120 sprintf(logline, "New base font with PS FontName %s\n", psfontname);
5121 showline(logline, 0);
5124 // strcpy(subfontname + fnext * MAXFONTNAME, psfontname);
5125 if (subfontname[fnext] != NULL) free(subfontname[fnext]);
5126 subfontname[fnext] = zstrdup(psfontname);
5127 /* hope this does not create problems with tests on subfontname ... */
5128 /* should we call FindMMBaseFile here to fill in fontname[fnext] ? */
5129 /* or do this later when inserting base font ? */
5130 /* (void) FindMMBaseFile(fnext); */
5134 strcpy(line, subfontname + fnext * MAXFONTNAME);
5135 printf("Claims FontName is %s\n", line);
5136 } *//* debugging 95/May/25 */
5137 fontproper[fnext] = C_MULTIPLE;
5138 fontsubflag[fnext] = -1;
5139 if (fontchar[fnext] == NULL) setupfontchar(fnext);
5140 // basewantchrs = fontchar + MAXCHRS * fnext; /* 95/May/12 */
5141 basewantchrs = fontchar[fnext]; /* 95/May/12 */
5142 for (i = 0; i < MAXCHRS; i++) /* just copy, first instance */
5143 basewantchrs[i] = instwantchrs[i];
5144 if (bMMShortCut == 0) {
5145 if (FindMMBaseFile(fnext) != 0) { /* or do later ? */
5146 /* fprintf(errout, " WARNING: MM base `%s' not found\n", FontName); */
5150 mmcount++; /* how many MM base fonts */
5151 if (fnext >= maxfonts - 1)
5153 /* fprintf(errout, "Too many MM base fonts (%d)\n", fnext - mmbase); */
5154 sprintf(logline, " ERROR: Too many MM base fonts (%d)\n", mmcount);
5155 showline(logline, 1);
5162 /* Now add in the base fonts for MM instances - separated out 95/May/12 */
5163 /* Add this to font table *after* base fonts for substitution */
5164 /* Do we get into any problems because of not checking for substitution ? */
5165 /* Not used anymore ? */
5167 /* Old style PSS stubs look like this: */
5169 /* 128, 1, x, x, x, x (length)
5170 %!PS-AdobeFont-1.0 TektonMM_100_LT_564_NO 001.000
5171 /TektonMM_100_LT_564_NO /TektonMM findfont [.63058 0 .36942 0] makeblendedfont
5172 dup /FontName /TektonMM_100_LT_564_NO put
5176 /* which becomes the following */
5178 /* %!PS-AdobeFont-1.0 TektonMM_100_LT_564_NO 001.000
5179 /zjrg_001 /zjrg____ findfont [.63058 0 .36942 0] makeblendedfont
5180 dup /FontName /zjrg_001 put
5183 /* Get PS FontName from PSS stub file and stick in subfontname[k] */
5184 /* NOTE: in case of PSS stub, this will be the *base font* PS FontName */
5185 /* Get PS FontName from PFM metric file and stick in subfontname[k] */
5186 /* NOTE: in case of PFM file, this will be the *instance* PS FontName */
5188 /* Could we do this using the new ATMFonts table ??? 2000 July 7 */
5190 //int AddMMFontName (FILE *input, int k, int pssflag, char *FileName)
5191 int AddMMFontName (FILE *input, int k, int pssflag, char *FileName, int nlen)
5196 // *(subfontname + k * MAXFONTNAME) = '\0';
5197 if (subfontname[k] != NULL) { /* reset in case not found */
5198 free(subfontname[k]);
5199 subfontname[k] = NULL;
5201 /* PSS file case first --- now outdated since ATM NT no longer */
5202 if (pssflag) { /* read PSS file to extract MM base FontName */
5203 if ((c = getc(input)) != 128) return -1; /* sanity test */
5204 if ((c = getc(input)) != 1) return -1; /* sanity test */
5205 for (m = 0; m < 4; m++) (void) getc(input); /* skip over length */
5206 while (readaline(line, input) == 0) {
5207 /* printf("LINE: %s", line); */ /* debugging 95/May/25 */
5208 if (*line == '%') continue; /* ignore comments */
5209 if ((s = strstr(line, "findfont")) != NULL)
5212 while (*s <= ' ' && s >= line) *s-- = '\0';
5213 if ((s = strrchr(line, '/')) == NULL) return -1;
5215 // strcpy(subfontname + k * MAXFONTNAME, s);
5216 if (subfontname[k] != NULL) free(subfontname[k]);
5217 subfontname[k] = zstrdup(s);
5218 /* MM base PS FontName *//* if using PSS */
5219 /* printf("FontName from PSS stub is %s\n", s); */
5220 /* debugging 95/May/25 */
5226 /* PFM file case next - now standard since ATM NT no longer PSS */
5227 else { /* instanceflag != 0 presumably *//* Read PFM for PS FontName */
5228 // printf("HEY! sizeof(FileName) = %d!\n", sizeof(FileName)); // 4 why ???
5229 /* read PFM file to get instance PS FontName */
5230 // flag = NamesFromPFM(input, NULL, 0, line, MAXFONTNAME, FileName);
5231 // flag = NamesFromPFM(input, NULL, 0, line, sizeof(FileName), FileName);
5232 flag = NamesFromPFM(input, NULL, 0, line, nlen, FileName);
5233 /* do we really want to test for that underscore ??? */
5234 if (flag != 0 && strchr(line, '_') != NULL) {
5235 // strcpy(subfontname + k * MAXFONTNAME, line);
5236 if (subfontname[k] != NULL) free(subfontname[k]);
5237 subfontname[k] = zstrdup(line);
5240 sprintf(logline, "MM PS FontName %s\n", line);
5241 showline(logline, 0);
5244 /* MM base PS FontName */ /* NO: now it is the instance PS FontName */
5247 else { /* NamesFromPFM failed or no _ in name returned */
5248 /* this message now comes up for missing fonts ... */
5250 " Not a PFM file for a MM instance (%s) ", line);
5251 showline(logline, 1);
5257 int notvalidPSS (int pssflag) { /* PSS or PFM file */
5258 sprintf(logline, " ERROR: not a valid %s file ",
5259 pssflag ? "MM PS Stub" : "PFM");
5260 showline(logline, 1);
5264 /* This tries to open font files to see which actually exist */
5265 /* also checks forced substitution flags */ /* should check resident ? */
5267 /* we are assuming this happens *before* we start adding MM base fonts */
5269 void checksubstitute (void)
5272 int k, j, i, n, baseexist, wipeflag;
5273 // char fontnamek[MAXTEXNAME];
5274 char fontnamek[FNAMELEN];
5275 /* char subfontnamek[MAXTEXNAME]; */
5276 // char subfontnamek[MAXFONTNAME]; /* fix 1995/July/15 */
5277 char subfontnamek[FNAMELEN]; /* fix 1995/July/15 */
5279 // char masterfontname[MAXFONTNAME]; /* saved 1995/July/15 */
5280 char masterfontname[FNAMELEN]; /* saved 1995/July/15 */
5284 task = "looking for substitutions";
5285 for (k = 0; k < fnext; k++) {
5286 wipeflag = 0; /* 1995/July/15 */
5287 /* proper = fontproper[k]; */
5288 /* printf("k %d proper ", k); */ /* debugging */
5289 /* don't bother if font unused (?) */
5290 if ((fontproper[k] & C_UNUSED) != 0) continue; /* ??? */
5291 /* don't bother if this font is another size of an existing one */
5292 if ((fontproper[k] & C_DEPENDENT) != 0) continue; /* NEW */
5293 /* if (strcmp(fontname[k], subfontname[k]) == 0) continue; */ /* size ? */
5294 /* if forced substitution, pretend couldn't open file */
5295 // strcpy (fontnamek, fontname + k * MAXTEXNAME);
5296 if (fontname[k] != NULL) strcpy(fontnamek, fontname[k]);
5297 else *fontnamek = '\0';
5299 /* if ((n = forcedsubstitute(fontname[k])) >= 0 || */
5300 if ((n = forcedsubstitute(fontnamek)) >= 0 ||
5301 /* (fp_in = OpenFont(fontname[k])) == NULL) { */
5302 (fp_in = OpenFont(fontnamek, 1)) == NULL) {
5303 /* printf("FORCED %s %s\n", subfontname[k], fontname[k]); */
5304 /* strcpy(subfontname[k], fontname[k]); */ /* copy real name */
5305 /* the following is a hack to deal with conflicing use of subfontname */
5306 /* both for substitution and for MM PS FontName ... */
5307 /* attempt to allow remapping (without name change) */
5308 // if (*(subfontname + k * MAXFONTNAME) != '\0') /* 95/July/15 */
5309 if (subfontname[k] != NULL) {
5310 /* if (fontproper[k] & C_MULTIPLE) { } */
5312 // strcpy (masterfontname, subfontname + k * MAXFONTNAME);
5313 strcpy(masterfontname, subfontname[k]);
5314 if (traceflag) { /* debugging */
5315 sprintf(logline, "Wiping out %s with %s (%d)\n",
5316 masterfontname, fontnamek, fontproper[k]);
5317 showline(logline, 0);
5320 // strcpy(subfontname + k * MAXFONTNAME,
5321 // fontname + k * MAXTEXNAME);
5322 if (subfontname[k] != NULL) free(subfontname[k]);
5324 if (fontname[k] != NULL)
5325 subfontname[k] = zstrdup(fontname[k]); /* copy real name */
5326 else subfontname[k] = NULL;
5328 /* in forced substitution we actually already know n ... */
5329 /* WARNING: fontremap writes new name back into given argument ... */
5330 /* so need to pass actual argument */
5331 /* if ((n = fontremap(subfontname[k])) >= 0) { */
5332 // if ((n = fontremap(subfontname + k * MAXFONTNAME)) >= 0)
5333 if ((n = fontremap(subfontname[k])) >= 0) {
5334 if (subfontname[k] != NULL) free(subfontname[k]);
5335 subfontname[k] = zstrdup(fontsubto[n]); // 99/Nov/17
5336 /* fontproper[k] = fontsubprop[n]; */
5337 fontproper[k] |= fontsubprop[n]; /* check */
5338 if ((fontproper[k] & C_REMAPIT) == 0)
5339 fontsubflag[k] = n; /* mark it */
5340 /* for now anything non-neg - later get proper pointer */
5341 else { /* remapped ? C_REMAPIT */
5342 /* strcpy(fontvector[k], fontsubvec[n]); */ /* 94/Feb/2 */
5343 // strcpy(fontvector[k], fontsubvec + n * MAXVECNAME);
5344 // strcpy(fontvector + k * MAXVECNAME, fontsubvec + n * MAXVECNAME);
5345 if (fontvector[k] != NULL) free(fontvector[k]);
5346 // fontvector[k] = zstrdup(fontsubvec + n * MAXVECNAME);
5347 fontvector[k] = zstrdup(fontsubvec[n]);
5348 /* printf("COPYING %s TO %d from %d\n", fontvector[k], k, n); */
5349 /* Lets check the encoding vector at this point ! 1995/July/15 */
5350 if (bCheckEncoding) /* 1995/Aug/15 */
5351 checkremapencode(k, fontnamek); /* 1995/July/15 */
5353 if ((fontproper[k] & C_FORCESUB) != 0 && /* substitute ? */
5354 (fontproper[k] & C_RESIDENT) == 0) { /* not resident ? */
5355 // strcpy(subfontnamek, subfontname + k * MAXFONTNAME);
5356 if (subfontname[k] != NULL)
5357 strcpy(subfontnamek, subfontname[k]);
5358 else *subfontnamek = '\0';
5359 /* if ((fp_in = OpenFont(subfontname[k])) == NULL) { */
5360 if ((fp_in = OpenFont(subfontnamek, 1)) == NULL) {
5362 "Font %s (substituted for %s) could not be found\n",
5363 /* subfontname[k], fontname[k]); */
5364 subfontnamek, fontnamek);
5365 showline(logline, 1);
5369 sprintf(logline, "Substituting * %s for %s\n",
5370 subfontnamek, fontnamek);/* debug 95/Mar/31 */
5371 showline(logline, 0);
5377 else { /* no substitute found */
5378 fontproper[k] |= C_MISSING; /* new */
5380 " WARNING: Can't find font %s (and no substitute)\n",
5383 showline(logline, 1);
5386 if (wipeflag) { /* a hack 1995/July/15 */
5387 // strcpy(subfontname + k * MAXFONTNAME, masterfontname);
5388 if (subfontname[k] != NULL) free(subfontname[k]);
5389 subfontname[k] = zstrdup(masterfontname);
5390 if (traceflag) { /* debugging */
5391 sprintf(logline, "Restoring %s (%d)\n", masterfontname, fontproper[k]);
5392 showline(logline, 0);
5394 /* fontproper[k] = C_MULTIPLE; */ /* | C_REMAPIT */
5395 /* fontproper[k] = C_MULTIPLE | C_REMAPIT; */ /* ??? */
5398 } /* end of forced substitute or font file not found */
5399 else { /* font file *does* exist */
5400 if (instanceflag != 0) {
5401 /* this is an instance of an MM font */
5402 fontproper[k] |= C_INSTANCE;
5403 /* subfontname is MM *instance* FontName, not MM base */
5404 fontproper[k] |= C_NOTBASE;
5405 /* if (AddMMFontName(fp_in, k, pssflag) != 0) *//* get PS FontName */
5406 if (AddMMFontName(fp_in, k, pssflag,
5407 fontnamek, sizeof(fontnamek)) != 0) { /* FNAMELEN */
5408 notvalidPSS(pssflag); /* specify which PSS file ? */
5409 sprintf(logline, "`%s' ", fontnamek);
5410 showline(logline, 0);
5412 AddMMBase(k); /* add corresponding MM base */
5414 /* fclose(fp_in); */ /* quitely close it again for now ! */
5415 if (pssflag != 0) { /* note that MM instance 94/Dec/6 */
5416 fontproper[k] |= C_INSTANCE;
5417 /* subfontname is MM *base* FontName, not MM instance */
5418 /* if (bMMShortCut == 0) { */ /* 95/May/25 */
5419 /* if (AddMMFontName(fp_in, k, pssflag) != 0) */
5420 if (AddMMFontName(fp_in, k, pssflag, /* get PS FontName */
5421 fontnamek, sizeof(fontnamek)) != 0) { /* FNAMLEN */
5422 notvalidPSS(pssflag); /* specify which PSS file ? */
5423 sprintf(logline, "`%s' ", fontnamek);
5424 showline(logline, 0);
5426 /* don't add it now ? */
5427 /* may need to stick in base for subst - so things will get mixed up */
5428 /* if (bMMNewFlag) */
5429 AddMMBase(k); /* add corresponding MM base */
5431 fclose(fp_in); /* quitely close it again for now ! */
5432 if (syntheticsexist) { /* 1993/Nov/6 */
5433 /* if (checksynthetic(fontname[k]) >= 0) { */ /* 1993/Nov/6 */
5434 if (checksynthetic(fontnamek) >= 0) { /* 1993/Nov/6 */
5435 /* printf(" SYNTHETIC "); */ /* DEBUGGING */
5436 fontproper[k] |= C_SYNTHETIC;
5440 } /* end of for (k = 0; k < fnext; k++) loop */
5442 task = "checking whether base font exists";
5443 for (k = 0; k < fnext; k++) {
5444 if (fontsubflag[k] >= 0) {
5446 if ((fontproper[k] & C_RESIDENT) != 0) baseexist = 1; /* ? */
5447 else if ((fontproper[k] & C_REMAPIT) != 0) baseexist = 1;
5448 /* else if ((fontproper[k] & C_ALIASED) != 0) baseexist = 1; */
5450 for (i = 0; i < fnext; i++) {
5451 if (i == k) continue; /* ignore if same */
5452 /* if (strcmp(fontname[i], subfontname[k]) == 0) { */
5453 if (fontname[i] != NULL && subfontname[k] != NULL &&
5454 strcmp(fontname[i], subfontname[k]) == 0) {
5455 // if (strcmp(fontname + i * MAXTEXNAME,
5456 // subfontname + k * MAXFONTNAME) == 0)
5457 fontsubflag[k] = i; baseexist = -1; /* base found */
5458 // fromfont = fontchar + MAXCHRS * k;
5459 fromfont = fontchar[k];
5460 // tofont = fontchar + MAXCHRS * i;
5461 tofont = fontchar[i];
5462 if (fromfont == NULL) {
5463 sprintf(logline, " BAD fromfont %d ", k);
5464 showline(logline, 1);
5466 if (tofont == NULL) {
5467 sprintf(logline, " BAD tofont %d ", i);
5468 showline(logline, 1);
5470 for (j = 0; j < MAXCHRS; j++) /* or in char req */
5471 if (fromfont[j] != 0) tofont[j] = 1;
5476 if (baseexist == 0) { /* base font does not exist - create it */
5477 task = "adding in base font";
5478 if (fnext >= maxfonts - 1) { /* 1994/May/21 */
5480 "Too many base fonts and substitutions (%d)\n", fnext);
5481 showline(logline, 1);
5485 fontsubflag[k] = fnext;
5486 /* strcpy(fontname[fnext], subfontname[k]); */ /* ??? */
5487 // strcpy(fontname + fnext * MAXTEXNAME,
5488 // subfontname + k * MAXFONTNAME);
5489 if (fontname[fnext] != NULL) free(fontname[fnext]);
5490 if (subfontname[k] != NULL)
5491 fontname[fnext] = zstrdup(subfontname[k]);
5492 else fontname[fnext] = NULL;
5493 // strcpy(subfontname + fnext * MAXTEXNAME, "");
5494 if (subfontname[fnext] != NULL) {
5495 free(subfontname[fnext]);
5496 subfontname[fnext] = NULL;
5497 } /* 95/Mar/31 --- make clean for S output */
5499 /* following may have been exposed by fixing bug in previous comment line .. */
5500 fontproper[fnext] = fontproper[k]; /* 0 ??? unmask problem ? */
5501 /* if ((fontproper[fnext] & C_REMAPIT) != 0) {
5502 strcpy(fontvector[fnext], fontsubvec[k]);
5504 fontsubflag[fnext] = -1;
5505 /* following for debugging only: */
5506 /* if (fontproper[k] != 0)
5507 printf("%d <= %d proper %d\n", fnext, k, fontproper[k]); */
5508 if (fontchar[fnext] == NULL) setupfontchar(fnext); // 2000/Apr/4
5510 // fromfont = fontchar + MAXCHRS * k;
5511 fromfont = fontchar[k];
5512 // tofont = fontchar + MAXCHRS * fnext;
5513 tofont = fontchar[fnext];
5514 if (fromfont == NULL) {
5515 sprintf(logline, " BAD fromfont %d ", k);
5516 showline(logline, 1);
5518 if (tofont == NULL) {
5519 sprintf(logline, " BAD tofont %d ", fnext);
5520 showline(logline, 1);
5522 /* copy across to base font those chars used in font substituted for */
5523 for (j = 0; j < MAXCHRS; j++) tofont[j] = fromfont[j];
5524 /* for (j = 0; j < MAXCHRS; j++) {
5525 if (tofont[j]) printf("USING %d ", j);
5526 } */ /* debug 95/Mar/31 */
5529 /* mmbase = fnext; *//* update start of MM base fonts 95/Mar/31 */
5535 /* Font substitution file is first searched for in dvi directory */
5536 /* then in default substitution file directory */
5537 /* now pass in subfile as argument so we can read more than one 1994/Feb/4 */
5539 /* FILE *OpenFontsub(void) { */
5540 FILE *OpenFontsub (char *subfile)
5544 if (strcmp(subfile, "") == 0) return NULL; /* 1994/Feb/4 */
5546 /* printf("FONTSUBREST %s\n", subfile); */
5548 /* if FONTSUBREST contains a path, use it directly - no other trials */
5549 if (strpbrk(subfile, "\\/:") != NULL) {
5550 strcpy(fontsubfile, subfile);
5551 extension(fontsubfile, "sub");
5552 /* printf("FONTSUBFILE %s\n", fontsubfile); */
5553 return(fopen(fontsubfile, "r"));
5556 /* if not fully qualified name, try in DVI file directory */
5557 if (dvipath != NULL) strcpy(fontsubfile, dvipath);
5558 else strcpy(fontsubfile, "");
5559 /* if (strcmp(fontsubfile, "") != 0)
5560 strcat(fontsubfile, "\\");
5561 strcat(fontsubfile, subfile); */
5562 makefilename(fontsubfile, subfile); /* 1992/Nov/28 */
5563 extension(fontsubfile, "sub");
5564 /* printf("FONTSUBFILE %s\n", fontsubfile); */
5565 if ((input = fopen(fontsubfile, "r")) != NULL) return input;
5567 /* try in specified font substitution `path' */
5568 strcpy(fontsubfile, fontsubpath);
5569 /* strcat(fontsubfile, "\\");
5570 strcat(fontsubfile, subfile); */
5571 makefilename(fontsubfile, subfile); /* 1992/Nov/28 */
5572 extension(fontsubfile, "sub");
5573 /* printf("FONTSUBFILE %s\n", fontsubfile); */
5574 if ((input = fopen(fontsubfile, "r")) != NULL) return input;
5576 /* try in SUBDIRECTORY of font substitution `path' *//* 1992/Nov/28 */
5577 strcpy(fontsubfile, fontsubpath);
5578 /* strcat(fontsubfile, "\\");
5579 strcat(fontsubfile, "sub\\"); */
5580 makefilename(fontsubfile, "sub\\"); /* "sub" sundirectory */
5581 strcat(fontsubfile, subfile);
5582 extension(fontsubfile, "sub");
5583 /* printf("FONTSUBFILE %s\n", fontsubfile); */
5584 if ((input = fopen(fontsubfile, "r")) != NULL) return input;
5586 /* try in current directory */ /* 1992/Dec/8 */
5587 *fontsubfile = '\0'; /* strcpy(fontsubfile, ""); */
5588 makefilename(fontsubfile, subfile); /* */
5589 extension(fontsubfile, "sub");
5590 /* printf("FONTSUBFILE %s\n", fontsubfile); */
5591 if ((input = fopen(fontsubfile, "r")) != NULL) return input;
5596 /* int charneeded(char wantchrs[]) {
5598 for (k = 0; k < fontchrs; k++) if (wantchrs[k] != 0) return -1;
5602 /* see whether font actually used */
5603 int charneeded (char *wantchrs)
5606 if (wantchrs == NULL) return 0;
5607 /* test in decreasing order of expected use */
5608 // for (k = 0; k < fontchrs; k++) if (wantchrs[k] != 0) return -1;
5609 for (k = 64; k < 128; k++) if (wantchrs[k]) return -1;
5610 for (k = 32; k < 64; k++) if (wantchrs[k]) return -1;
5611 for (k = 0; k < 32; k++) if (wantchrs[k]) return -1;
5612 for (k = 160; k < fontchrs; k++) if (wantchrs[k]) return 1; /* G2 */
5613 for (k = 128; k < 160; k++) if (wantchrs[k]) return 1; /* C2 */
5617 /* read font substitution table */ /* returns non-zero if success */
5619 /* return value not used ? */
5620 int GetSubstitutes (void)
5623 char nextfontsub[FNAMELEN]; /* need for multi sub files */
5624 int k, flag=0; /* 1994/Feb/5 */
5625 char *s, *sc, *sl; /* 1994/Feb/5 */
5627 ksubst = 0; /* reset table 1994/Feb/4 */
5628 /* note this may modify the command line, but that is not reused ... */
5629 for (k = 0; k < subfontfileindex; k++) { /* 1994/Feb/8 */
5630 /* s = fontsubrest; */
5631 s = subfontfile[k]; /* 1994/Feb/8 */
5633 if ((sc = strchr(s, ',')) != NULL) *sc = '\0';
5634 /* if ((input = OpenFontsub()) != NULL) { */
5635 /* input = OpenFontsub(fontsubrest); */
5636 strcpy(nextfontsub, s);
5637 /* if ((input = OpenFontsub(s)) != NULL) { */
5638 if ((input = OpenFontsub(nextfontsub)) != NULL)
5641 printf("Reading %s\n", nextfontsub); */ /* debugging */
5642 readsubstitutes(input); /* read font substitution file */
5643 fclose(input); /* 1994/Feb/4 */
5645 /* if (traceflag) showsubtable(stdout); */ /* an experiment */
5646 /* return -1; */ /* OK, specified file worked */
5650 sl = removepath(fontsubfile);
5651 /* fprintf(errout, "WARNING: Can't find font subst file: "); */
5652 sprintf(logline, " WARNING: Can't find %s subst file %s\n",
5654 showline(logline, 1);
5656 /* putc('\n', errout); */
5659 if (sc != NULL) s = sc+1; /* can't use strtok ... */
5665 if (flag == 0) { /* if no substitution files specified */
5666 /* substitute = 0; */ /* NO: still have built in table ... */
5667 /* fprintf(errout, "WARNING: Can't find font substitution file\n"); */
5668 /* perrormod(fontsubfile); */
5669 /* perrormod(removepath(fontsubfile)); */ /* 1992/Nov/28 */
5671 /* then try standard substitution file */
5672 /* if (strcmp(fontsubrest, "standard") == 0) return 0; *//* failed */
5673 /* if (strcmp(fontsubrest, "standard") != 0) { */ /* 1994/Feb/10 */
5674 /* strcpy(fontsubrest, "standard"); */
5675 /* if((input = OpenFontsub()) != NULL) { */
5676 if((input = OpenFontsub("standard")) != NULL)
5678 readsubstitutes(input);
5679 fclose(input); /* 1994/Feb/4 */
5680 /* if (traceflag) showsubtable(stdout); */ /* an experiment */
5681 /* return -1; */ /* OK, standard file worked */
5686 sl = removepath(fontsubfile);
5687 /* substitute = 0; */ /* NO: still have built in table ? */
5688 sprintf(logline, " WARNING: Can't find %s subst file %s\n",
5690 showline(logline, 1);
5691 /* perrormod(fontsubfile); */
5692 perrormod(sl); /* 1992/Nov/28 */
5695 /* } */ /* if strcmp fontsubrest standard removed 1994/Feb/10 */
5696 /* return 0; */ /* No success ! */
5698 /* if (traceflag) showsubtable(stdout); */ /* an experiment */
5701 showsubtable(); /* an experiment */
5702 // if (logfileflag) showsubtable(logfile);
5705 return flag; /* non zero if some substitution table has been read */
5708 /* separated out 94/Oct/5 */
5709 int markunusedfonts0 (void)
5713 /* fontproper[k] &= ~C_UNUSED; */
5714 for (k = 0; k < fnext; k++)
5716 /* if (charneeded(fontchar[k]) == 0) */
5717 // if (fontproper[k] | C_MULTIPLE) continue; /* for now 94/Dec/6 ??? */
5718 if (fontproper[k] & C_MULTIPLE) continue; /* fixed 2000 July 4 */
5719 // if (charneeded(fontchar + MAXCHRS * k) == 0)
5720 if (charneeded(fontchar[k]) == 0) {
5721 fontproper[k] |= C_UNUSED;
5728 /* following called from dvipsone.c before calling extract itself */
5729 /* task = "checking for duplicate & substitutions"; */
5731 /* get font tables straightened out first */
5732 void preextract (void)
5736 // char fontnamek[MAXTEXNAME];
5737 char fontnamek[FNAMELEN];
5738 // char subfontnamek[MAXTEXNAME];
5739 char subfontnamek[FNAMELEN];
5741 /* if (fnext == 0) return; */ /* no fonts - nothing to do ??? */
5742 /* mmbase = fnext; */ /* start of MM base fonts if any */
5743 mmcount = 0; /* number of MM base fonts added */
5746 /* Do we want to read substitution table if already forced all reside ? */
5747 /* YES: need to get PS FontNames if possible etc */
5748 /* following moved to dvipsone.c 95/Oct/15 */
5749 /* if (substituteflag) (void) GetSubstitutes(); */
5750 /* if (GetSubstitutes() < 0) fprintf(errout, " Can't get substitutes"); */
5751 if (fnext == 0) return; /* moved down here 95/May/8 */
5753 /* replace aliased names right away based on substitution table */
5754 if (aliasesexist) replacealias(); /* replace aliased names right away */
5756 /* replace aliased names right away based on texfonts.map 1995/Dec/29 */
5757 if (bForceFontsMap) replacetexfontsmap(); /* 1995/Dec/29 */
5759 flagduplicates(); /* look for same font at different magnifications */
5760 /* mark unused fonts here */
5761 /* markunusedfonts0(); */ /* this was before 94/Oct/5 - problem ? */
5763 if (substituteflag) // try to open fonts and
5764 checksubstitute(); // work out which fonts will be substituted for
5766 /* mmbase = fnext; */ /* update start of MM base fonts 95/Mar/31 ??? */
5767 /* if (bMMNewFlag == 0) AddInBaseFonts(); */ /* old way 95/May/12 */
5768 /* mark unused fonts here ? */ /* after fonts in different sizes combined */
5769 markunusedfonts0(); /* new place on 94/Oct/5 */
5771 /* Deal with situtation where all fonts considered resident */
5772 /* moved down here 1992/July/4 */ /* do this LAST */
5773 if (forcereside != 0)
5775 for (k = 0; k < fnext; k++)
5777 /* debugging output 95/Sep/16 */
5778 /* if (fontsubflag[k] < 0) { */ /* 1992/July/4 */
5779 /* Don't mark fonts substituted for as resident */
5780 /* Don't mark MM font instances resident. But, don't know base FontName ? */
5781 /* if (fontsubflag[k] < 0) { */
5782 if (fontsubflag[k] < 0 &&
5783 (fontproper[k] & C_INSTANCE) == 0) { /* 1995/Sep/16 */
5784 fontproper[k] |= C_RESIDENT;
5785 /* fontproper[k] |= C_FORCESUB; */
5787 /* Try and get the real PS FontName */ /* Maybe do earlier ??? */
5788 /* Avoid repetition ??? - don't do if C_DEPENDENT flag is on ??? */
5789 /* Don't mess with it if a substitute has already been found in table ??? */
5790 /* Don't do if C_FORCESUB is on ??? */
5791 /* if (strcmp(subfontname[k], fontname[k]) == 0) */
5792 /* if ((fontproper[k] & C_DEPENDENT) == 0 &&
5793 (fontproper[k] & C_FORCESUB) == 0) */
5794 /* if ((fontproper[k] & C_DEPENDENT) == 0) { */
5795 /* In case of font instance, don't want to overwrite MM base name */
5796 /* Also, don't really need this for MM base, since already done ... */
5797 if ((fontproper[k] & C_DEPENDENT) == 0 &&
5798 (fontproper[k] & C_INSTANCE) == 0) { /* 1995/Sep/16 */
5799 // strcpy (fontnamek, fontname + k * MAXTEXNAME);
5800 if (fontname[k] != NULL) strcpy(fontnamek, fontname[k]);
5801 else *fontnamek = '\0';
5802 // strcpy (subfontnamek, subfontname + k * MAXTEXNAME);
5803 if (subfontname[k] != NULL) strcpy(subfontnamek, subfontname[k]);
5804 else *subfontnamek = '\0';
5808 sprintf(logline, "%d %s %s %d\n", k, fontnamek, subfontnamek,
5809 fontproper[k]); /* debugging */
5810 showline(logline, 0);
5813 /* WARNING: FindFontName writes back into second argument ! */
5814 /* FindFontName(fontname[k], subfontname[k]);*//* 1993/Sep/30 */
5815 // FindFontName(fontnamek, subfontnamek, MAXFONTNAME); /* 1994/Feb/2 */
5816 FindFontName(fontnamek, subfontnamek, sizeof(subfontnamek)); /* FNAMELEN */
5817 /* printf("%d %s %s %d\n", k, fontnamek, subfontnamek,
5818 fontproper[k]); */ /* debugging */
5819 /* need to copy back result 1994/Feb/3 */
5820 // strcpy(subfontname + k * MAXTEXNAME, subfontnamek);
5821 if (subfontname[k] != NULL) free(subfontname[k]);
5822 subfontname[k] = zstrdup(subfontnamek);
5828 /* following contains kludgy test to avoid repeating vector */
5830 void constructvectors(FILE *fp_out)
5834 /* maybe nothing to do here if just need ansinew due to `-X' flag */
5835 /* we should already have the ansinew vector dumped out */
5837 writedvistart(fp_out); /* 93/Sep/30 */
5838 for (k=0; k < fnext; k++)
5840 if ((fontproper[k] & C_REMAPIT) != 0 &&
5841 (fontproper[k] & C_RESIDENT) != 0)
5844 for (i = 0; i < k; i ++)
5846 if ((fontproper[i] & C_REMAPIT) != 0 &&
5847 (fontproper[i] & C_RESIDENT) != 0 &&
5848 /* strcmp(fontvector + i * MAXVECNAME, fontvector + k * MAXVECNAME) == 0) */
5849 fontvector[i] != NULL &&
5850 fontvector[k] != NULL &&
5851 strcmp(fontvector[i], fontvector[k]) == 0)
5857 // readencoding(fontvector + k * MAXVECNAME);
5858 readencoding(fontvector[k]);
5859 // writevector(fp_out, fontvector[k], MAXCHRS);
5860 // writevector(fp_out, fontvector + k * MAXVECNAME, MAXCHRS);
5861 writevector(fp_out, fontvector[k], MAXCHRS);
5865 /* fprintf(fp_out, "%s\n", textext); */ /* for text fonts */
5866 /* fprintf(fp_out, "%s\n", textype); */ /* for typewriter fonts */
5868 writedviend(fp_out); /* 1992/Nov/17 */
5871 /* Check whether font itself, or its base font are resident */
5873 int fontreside (int f) /* 1995/July/5 */
5876 if ((fontproper[f] & C_RESIDENT) != 0) return 1;
5877 if ((fontproper[f] & C_DEPENDENT) != 0) {
5880 if ((fontproper[k] & C_RESIDENT) != 0) return 1;
5886 /* suppress above remapped font is not resident ? */
5888 /* f is always the short font number */
5889 /* fn is the internal font number if bShortFont == 0 || bUseInternal != 0 */
5890 /* fn is the short font number if bShortFont != 0 && bUseInternal == 0 */
5892 void dofont (FILE *fp_out, int f, int fn)
5894 // char fname[MAXFONTNAME];
5895 char fname[FNAMELEN];
5899 if (f < 0 || f >= maxfonts) { /* 93/May/23 */
5900 sprintf(logline, "Bad font index %d\n", f); /* debugging */
5901 showline(logline, 1);
5902 /* should we skip it in this case to avoid access errors ? */
5905 property = fontproper[f]; /* 97/June/1 */
5907 printf("font %d fontname %s subfontname %s fontsubflag %d\n",
5908 f, fontname[f], subfontname[f], fontsubflag[f]); */
5909 // strcpy(fname, fontname + f * MAXTEXNAME);
5910 if (fontname[f] != NULL) strcpy(fname, fontname[f]);
5913 /* if (strcmp(subfontname[f], "") == 0) { */
5914 // if (*(subfontname + f * MAXFONTNAME) == '\0') /* 1994/Feb/2 */
5915 if (subfontname[f] == NULL) {
5916 /* strcpy(fname, fontname[f]); */
5917 /* strcpy(fname, fontname + f * MAXTEXNAME); */
5919 else { /* i.e. subfontname[f] is not empty */
5920 /* strcpy(fname, fontname[f]); */ /* if nothing else */
5921 /* strcpy(fname, fontname + f * MAXTEXNAME); */ /* if nothing else */
5922 if ((property & C_DEPENDENT) != 0) { /* NEW */
5923 /* if (strcmp(fontname[f], subfontname[f]) == 0) { */
5924 /* if this font already used earlier at other size */
5927 sprintf(logline, "%d %s (%d)", f, fname, n); /* debugging */
5928 showline(logline, 0);
5929 // sprintf(logline, "%s", (subfontname + f * MAXFONTNAME));
5930 sprintf(logline, "%s", subfontname[f]);
5931 showline(logline, 0);
5934 if ((fontproper[n] & C_RESIDENT) != 0) { /* what ? */
5935 if ((fontproper[n] & C_REMAPIT) == 0) { /* ? */
5936 /* strcpy(fname, fontname[n]); */ /* 1992/July/4 */
5937 // strcpy(fname, fontname + n * MAXTEXNAME); /* 94/Feb/2 */
5938 if (fontname[n] != NULL)
5939 strcpy(fname, fontname[n]); /* 94/Feb/2 */
5941 /* if (strcmp(subfontname[n], "") != 0) */ /* 1992/July/4 */
5942 // if (*(subfontname + n * MAXFONTNAME) != '\0') /* 94/Feb/2 */
5943 if (subfontname[n] != NULL) {
5944 /* strcpy(fname, subfontname[n]); */
5945 strcpy(fname, subfontname[n]);
5948 /* printf("Remapped %d to %s\n", f, fname); */
5950 } /* end of (proper & C_DEPENDENT) != 0 case */
5951 else if ((property & C_RESIDENT) != 0) {
5952 /* if this font used here for first time */
5953 if ((property & C_REMAPIT) == 0) {
5954 /* strcpy(fname, subfontname[f]); */
5955 // strcpy(fname, subfontname + f * MAXFONTNAME);
5956 if (subfontname[f] != NULL) strcpy(fname, subfontname[f]);
5959 /* printf("Remapped %d to %s\n", f, fname); */
5960 } /* end of (proper & C_RESIDENT) != 0 case */
5963 /* Use remapped name instead of FontName if resident and ANSI */
5964 if ((property & C_RESIDENT) != 0 &&
5965 (property & C_REMAPIT) == 0 && bWindowsFlag != 0) {
5966 /* special case sy = Symbol and zd = ZapfDingbats ? */ /* 94/Feb/3 */
5967 /* strcpy(fname, fontname[f]); */ /* experiment 93/Oct/4 */
5968 // strcpy(fname, fontname + f * MAXTEXNAME); /* 94/Feb/2 */
5969 if (fontname[f] != NULL) strcpy(fname, fontname[f]); /* 94/Feb/2 */
5972 if ((property & C_DEPENDENT) != 0) { /* experiment 93/Oct/7 */
5973 n = fontsubflag[f]; /* what are we dependent on */
5974 /* Use remapped name instead of FontName if dependent of resident and ANSI */
5975 if ((fontproper[n] & C_RESIDENT) != 0 &&
5976 (fontproper[n] & C_REMAPIT) == 0 && bWindowsFlag) {
5977 /* special case sy = Symbol and zd = ZapfDingbats ? */ /* 94/Feb/3 */
5978 /* strcpy(fname, fontname[n]); */ /* experiment 93/Oct/7 */
5979 // strcpy(fname, fontname + n * MAXTEXNAME); /* 94/Feb/2 */
5980 if (fontname[n] != NULL) strcpy(fname, fontname[n]); /* 94/Feb/2 */
5983 /* subfontname is MM *instance* FontName, not MM base */
5984 if ((fontproper[n] & C_NOTBASE) != 0) {
5985 // strcpy(fname, subfontname + n * MAXTEXNAME); /* 97/Dec/4 */
5986 if (subfontname[n] != NULL) strcpy(fname, subfontname[n]);
5991 if (fs[f] != 0) { /* zero if font not used directly */
5992 /* if ((property & C_ALIASED) != 0)
5993 strcpy(fname, subfontname[f]); */
5994 if ((property & C_UNUSED) == 0) { /* if actually used */
5995 if (strcmp(fname, "") == 0) {
5996 /* fprintf(errout, " ERROR: Empty name: fn %d f %d fontname %s subfontname %s\n",
5997 fn, f, fontname[f], subfontname[f]); */
5998 sprintf(logline, " ERROR: Empty name: fn %d f %d\n", fn, f);
5999 showline(logline, 1);
6001 /* fprintf(fp_out, "/fn%d /%s %ld mf ", fn, fname, fs[f]); */
6002 /* fprintf(fp_out, "/fn%d /", fn); */ /* 1994/June/7 */
6003 sprintf(logline, "/fn%d /", bUseInternal ? fn : f);
6004 PSputs(logline, fp_out);
6005 /* Is this use of prefix always OK? What if we are not dealing with PS name */
6006 /* if (strcmp(fontprefix, "") != 0) fputs(fontprefix, fp_out); */
6007 // if (strcmp(fontprefix, "") != 0) /* 95/July/5 */
6008 if (fontprefix != NULL) {
6009 if (fontreside(f) == 0) {
6010 /* possibly modify if bRandomPrefix is set ??? */
6011 // fputs(fontprefix, fp_out);
6012 PSputs(fontprefix, fp_out);
6015 if (uppercaseflag != 0 && istexfont(fname) != 0)
6016 uppercase(fname, fname); /* 92/Dec/22 */
6017 /* This is where we insert fname after the /fn... */
6018 /* #ifdef ALLOWSCALE
6020 fprintf(fp_out, "%s %.9lg mf ", fname, fs[f] / outscale);
6023 if (bSubRealName == 0) { /* a hack to hack something */
6024 /* we don't normally come here these days ... */
6025 /* use real PS FontName --- unless new size of another font */
6026 if ((property & C_DEPENDENT) == 0) {
6027 // strcpy(fname, subfontname + f * MAXFONTNAME);
6028 if (subfontname[f] != NULL) strcpy(fname, subfontname[f]);
6032 n = fontsubflag[f]; /* what are we dependent on ? */
6033 // strcpy(fname, subfontname + n * MAXFONTNAME);
6034 if (subfontname[n] != NULL) strcpy(fname, subfontname[n]);
6038 if (property & C_INSTANCE) {
6039 /* strcpy(fname, subfontname + f * MAXFONTNAME); */
6042 // strcat(fname, subfontname + f * MAXFONTNAME);
6043 if (subfontname[f] != NULL) strcat(fname, subfontname[f]);
6046 sprintf(logline, "subfontname (%d): %s ", f, fname);
6047 showline(logline, 0);
6050 if (traceflag) { /* debugging */
6051 // if (logfileflag) showproper(logfile, fontproper[f]);
6052 showproper(logline, fontproper[f]);
6053 showline(logline, 0);
6055 /* not sure this is the best way for MM instances - mayby use subfontname */
6057 /* This is where we insert fname after the /fn... */
6060 sprintf(logline, "%s %.9lg mf ", fname, (double) fs[f] /
6064 sprintf(logline, "%s %ld mf ", fname, fs[f]);
6066 PSputs(logline, fp_out);
6069 sprintf(logline, "%s %ld mf ", fname, fs[f]);
6070 PSputs(logline, fp_out);
6073 /* fputs(fname, fp_out); */
6074 /* fprintf(fp_out, " %ld mf ", fs[f]); */
6076 sprintf(logline, "/f%d{fn%d sf}def\n",
6077 bShortFont ? f : fn, bUseInternal ? fn : f);
6078 PSputs(logline, fp_out);
6079 /* fprintf(fp_out, "/f%d{fn%d sf}def\n", fn, fn);*/ /* 1994/June/7 */
6081 /* printf("fontname %s subfontname %s fontproper %0x\n",
6082 fontname[f], subfontname[f], property); */
6085 /* else printf("Font %d noted as C_UNUSED\n", f); */ /* 95/Feb/1 */
6089 /* Replace PostScript FontName in PSS stub with new one */
6091 int replacename (char *line, char *fname)
6094 char buffer[FNAMELEN];
6096 if ((s = strchr(line, '/')) == NULL) return -1;
6098 if ((t = strchr(s, ' ')) == NULL) t = strchr(s, '/');
6099 if (t == NULL) return -1;
6100 if (strlen(t) >= sizeof buffer) /* FNAMELEN */
6108 /* copy and process Multiple Master Instance PSS stub file */
6109 /* fname is file name of MM instance stub */
6110 /* bname is file name of MM base font */
6111 /* encode is optional encoding vector - no longer used */
6112 /* returns -1 if file format bad or parsing error */
6114 /* int copyPSS_sub(FILE *output, FILE *input, char *fname, char *encode) { */
6115 /* int copyPSS_sub(FILE *output, FILE *input, char *fname, char *bname, char *encode) { */
6116 int copyPSS_sub(FILE *output, FILE *input, char *fname, char *bname, char *encode, int proper)
6120 // char basename[MAXTEXNAME]; /* char basename[16]; */
6121 char basename[FNAMELEN]; /* char basename[16]; */
6123 if (getc(input) != 128) return -1; /* check ASCII section */
6124 if (getc(input) != 1) return -1; /* should be 128, 1 */
6125 /* skip over 4 byte length code */
6126 getc(input); getc(input); getc(input); getc(input);
6127 if (readaline(line, input) != 0) return -1;
6128 while (*line == '%') { /* copy comment lines over */
6129 // fputs(line, output);
6130 PSputs(line, output);
6131 if (readaline(line, input) != 0) return -1;
6133 /* while ((s = strchr(line, '/')) == NULL) { */
6134 while ((s = strstr(line, "findfont")) == NULL) {
6135 // fputs(line, output);
6136 PSputs(line, output);
6137 if (readaline(line, input) != 0) return -1;
6139 if ((s = strchr(line, '/')) == NULL) return -1;
6140 /* replace PostScript Multiple Master *Instance* FontName */
6141 if (replacename (s, fname) != 0) return -1;
6142 /* if (bMMNewFlag) { */
6143 if ((s = strchr(line+1, '/')) == NULL) return -1;
6144 /* Construct MM base font file name from stub PSS file name */
6145 if (bMMShortCut) { /* disallow this ? */
6146 strcpy(basename, fname);
6147 strcpy(basename+5, "___");
6148 /* MM base font has same name, but ends in ___ simple minded ? */
6150 else strcpy(basename, bname);
6151 /* Replace PostScript Multiple Master *Base* FontName */
6152 /* Should more generally check whether Base Font is resident ? */
6153 /* if (forcereside == 0) */ /* 95/Sep/16 */
6154 if ((proper & C_RESIDENT) == 0) /* 95/Sep/16 later */
6155 if (replacename (s, basename) != 0) return -1;
6157 while ((s = strstr(line, "/FontName")) == NULL) {
6158 // fputs(line, output);
6159 PSputs(line, output);
6160 if (readaline(line, input) != 0) return -1;
6162 /* if (replacename (s+9, fname) != 0) return -1; */
6163 if ((s = strchr(s+1, '/')) == NULL) return -1;
6164 /* replace PostScript Multiple Master *Instance* FontName */
6165 if (replacename (s, fname) != 0) return -1;
6166 while ((s = strstr(line, "definefont")) == NULL) {
6167 // fputs(line, output);
6168 PSputs(line, output);
6169 if (readaline(line, input) != 0) return -1;
6171 /* if (bMMNewFlag == 0) {*/ /* Insert new encoding vector in PSS 95/May/13 */
6172 /* Should more generally check whether Base Font is resident ? */
6173 /* if (forcereside != 0) { */ /* new encoding vector in PSS 95/Sep/16 */
6174 if (proper & C_RESIDENT) { /* new encoding vector in PSS 95/Sep/16 */
6175 if (encode != NULL && *encode != '\0') {
6176 sprintf(logline, "dup /Encoding %s put\n", encode);
6177 PSputs(logline, output);
6179 else if (bWindowsFlag != 0) {
6180 sprintf(logline, "dup /Encoding get StandardEncoding eq{");
6181 PSputs(logline, output);
6182 sprintf(logline, "dup /Encoding %s put\n", textenconame);
6183 PSputs(logline, output);
6184 PSputs("}if\n", output);
6187 // fputs(line, output);
6188 PSputs(line, output);
6192 /* Danger above is that MM font that is not a text font can get reencoded! */
6193 /* Fixed 96/Sep/29 */
6195 /* use copyPSS_sub(output, input, fname, encode); to copy and expand PSS */
6197 /* compressfont(output, input, FontName) to copy Multiple Master itself ? */
6198 /* how to we get the FontName ??? */ /* needed for BeginResource ... */
6199 /* what about those comments about FontNeeded, FontProvided etc ? */
6201 /* work in progress: deal with PSS stub for Multiple Master */
6203 int copyPSS(FILE *fp_out, FILE *fp_in, int k)
6208 // char vecname[MAXVECNAME]; /* 1994/Feb/4 */
6209 char vecname[FNAMELEN];
6210 /* char basename[MAXFONTNAME]; */ /* 1995/May/25 */
6211 // char basename[MAXTEXNAME]; /* 1997/June/1 */
6212 char basename[FNAMELEN];
6213 // char psfontname[MAXFONTNAME]; /* 1997/June/1 */
6214 char psfontname[FNAMELEN];
6216 /* strcpy(oldname, fontsubfrom + k * MAXTEXNAME); */
6217 /* strcpy(newname, fontsubto + k * MAXFONTNAME); */
6218 // strcpy(vecname, fontsubvec + k * MAXVECNAME);
6219 if (fontsubvec[k] != NULL) strcpy(vecname, fontsubvec[k]);
6220 else *vecname = '\0';
6221 /* file name of corresponding MM base font - old way and default */
6222 // strcpy(psfontname, subfontname + k * MAXFONTNAME); /* 97/June/1 */
6223 if (subfontname[k] != NULL) strcpy(psfontname, subfontname[k]); /* 97/June/1 */
6224 else *psfontname = '\0';
6225 if ((s = strchr(psfontname, '_')) != NULL && s > psfontname) {
6226 return 0; /* actual instance PS FontName - redundant */
6228 // strcpy(basename, fontname + k * MAXTEXNAME); /* 95/May/25 */
6229 if (fontname[k] != NULL) strcpy(basename, fontname[k]); /* 95/May/25 */
6230 else *basename = '\0';
6231 strcpy(basename + 5, "___"); /* 95/May/25 */
6232 if (bMMShortCut == 0) { /* find corresponding MM base entry */
6234 for (m = 0; m < fnext; m++) {
6235 if ((fontproper[m] & C_MULTIPLE) == 0) continue;
6236 // if (strcmp (subfontname + k * MAXFONTNAME,
6237 // subfontname + m * MAXFONTNAME) == 0)
6238 if (subfontname[k] != NULL && subfontname[m] != NULL &&
6239 strcmp (subfontname[k], subfontname[m]) == 0) {
6240 /* we assume that the actual MM font file name has been placed here already */
6241 /* which will not be the case if the darn thing is declared resident ? */
6242 proper = fontproper[m]; /* pick up properties of base */
6243 // strcpy (basename, fontname + m * MAXTEXNAME);
6244 if (fontname[m] != NULL) strcpy (basename, fontname[m]);
6245 else *basename = '\0';
6250 if (flag == 0) { /* should not happen - debugging */
6251 sprintf(logline, " Assuming MM base `%s'", basename);
6252 showline(logline, 1);
6256 beginresource(fp_out, filefontname); /* %%BeginResource: font zjrg_001 */
6257 /* flag = copyPSS_sub(fp_out, fp_in, filefontname, vecname); */
6258 flag = copyPSS_sub(fp_out, fp_in, filefontname, basename, vecname, proper);
6260 notvalidPSS(1); /* pssflag == 1 */
6261 sprintf(logline, "`%s' ", filefontname);
6262 showline(logline, 0);
6264 endresource(fp_out); /* %%EndResource */
6268 int IsItUsed (char *wantchrs)
6271 if (wantchrs == NULL) return 0;
6272 /* test in decreasing order of expected use */
6273 // for (k = 0; k < fontchrs; k++) if (wantchrs[k] != 0) return -1;
6274 for (k = 64; k < 128; k++) if (wantchrs[k]) return 1; /* G1b */
6275 for (k = 32; k < 64; k++) if (wantchrs[k]) return 1; /* G1a */
6276 for (k = 0; k < 32; k++) if (wantchrs[k]) return 1; /* C1 */
6277 for (k = 160; k < fontchrs; k++) if (wantchrs[k]) return 1; /* G2 */
6278 for (k = 128; k < 160; k++) if (wantchrs[k]) return 1; /* C2 */
6282 /* See if can mark unused fonts (in jobs with less than full page range) */
6284 int MarkUnusedFonts (void) /* an experiment 95/Mar/5 */
6287 /* int k, count, property; */
6288 // char fontnamek[MAXTEXNAME];
6289 char fontnamek[FNAMELEN];
6292 /* for (fn = 0; fn < mmbase; fn++) { */ /* ignore MM base fonts for now */
6293 for (fn = 0; fn < fnext; fn++) {
6294 /* if (fontproper[k] & C_MULTIPLE) continue; */ /* ignore MM base fonts */
6295 // wantchrs = fontchar + MAXCHRS * fn;
6296 wantchrs = fontchar[fn];
6297 /* property = fontproper[fn]; */
6299 for (k = 0; k < MAXCHRS; k++) {
6300 if (wantchrs[(k + 32) % 255] != 0) {
6304 /* count = IsItUsed(wantchrs); */
6305 /* if (count == 0) { */
6306 if (! IsItUsed(wantchrs)) {
6308 /* strcpy (fontnamek, fontname + k * MAXTEXNAME); */
6309 // strcpy (fontnamek, fontname + fn * MAXTEXNAME);
6310 if (fontname[fn] != NULL) strcpy (fontnamek, fontname[fn]);
6311 else *fontnamek = '\0';
6312 sprintf(logline, "Marking %s as unused\n", fontnamek);
6313 showline(logline, 0);
6315 fontproper[fn] |= C_UNUSED;
6322 /* following split off 95/May/13 to improve readability ... */
6324 int extractafont (FILE *fp_out, int k)
6328 int proper; /* 1992/Aug/23 */
6329 // char fontnamek[MAXTEXNAME];
6330 char fontnamek[FNAMELEN];
6331 // char subfontnamek[MAXFONTNAME];
6332 char subfontnamek[FNAMELEN];
6334 proper = fontproper[k];
6335 // strcpy(fontnamek, fontname + k * MAXTEXNAME); /* 94/Feb/2 */
6336 if (fontname[k] != NULL) strcpy(fontnamek, fontname[k]); /* 94/Feb/2 */
6337 else *fontnamek = '\0';
6338 /* if ((proper & C_UNUSED) != 0) return; */
6339 if (fontsubflag[k] < 0) { /* not a font substituted for */
6340 /* don't bother if font not used - no characters */
6341 if ((proper & C_UNUSED) != 0) return 0;
6342 /* don't bother if already known not to exist */
6343 if ((proper & C_MISSING) != 0) return 0;
6344 if ((proper & C_RESIDENT) != 0) return 0; /* never */
6345 if ((proper & C_DEPENDENT) != 0) return 0; /* NEW */
6346 /* if (strcmp(fontname[k], subfontname[k]) == 0) continue; */ /* ? */
6347 /* if ((proper & C_ALIASED) != 0)
6348 strcpy(filefontname, subfontname[k]); */
6349 /* strcpy(filefontname, fontname[k]); */
6350 // strcpy(filefontname, fontname + k * MAXTEXNAME);
6351 if (fontname[k] != NULL) strcpy(filefontname, fontname[k]);
6352 else *filefontname = '\0';
6353 if ((proper & C_REMAPIT) != 0) { /* remapped font */
6354 // strcpy (subfontnamek, subfontname + k * MAXFONTNAME);
6355 if (subfontname[k] != NULL) strcpy (subfontnamek, subfontname[k]);
6356 else *subfontnamek = '\0';
6357 /* printf("\n%s AND %s ", filefontname, subfontnamek); */
6358 if (proper & C_MULTIPLE) { /* kludge for remapped MM base 95/Jul/15 */
6359 // strcpy (subfontnamek, fontname + k * MAXFONTNAME);
6360 if (fontname[k] != NULL)
6361 strcpy (subfontnamek, fontname[k]);
6362 else *subfontnamek = '\0';
6364 /* if ((fp_in = OpenFont(subfontname[k])) == NULL) { */
6365 if ((fp_in = OpenFont(subfontnamek, 1)) == NULL) {
6366 /* fprintf(errout, " WARNING: "); */ /* REDUNDANT ? */
6367 sprintf(logline, " WARNING: %s ", subfontnamek); /* REDUNDANT ? */
6368 showline(logline, 1);
6369 /* perrormod(subfontname[k]); */
6370 perrormod(subfontnamek);
6375 else { /* not a remapped font */
6376 /* can we assume fontnamek set correctly ? */
6377 /* if ((fp_in = OpenFont(fontname[k])) == NULL) { */
6378 if ((fp_in = OpenFont(fontnamek, 1)) == NULL) {
6379 /* fprintf(errout, " WARNING: "); */ /* REDUNDANT ? */
6380 sprintf(logline, " WARNING: %s ", fontnamek); /* REDUNDANT ? */
6381 showline(logline, 1);
6382 /* perrormod(fontname[k]); */
6383 perrormod(fontnamek);
6386 } /* shouldn't happen ? */
6389 // putc('[', stdout);
6390 // if (logfileflag) putc('[', logfile);
6393 /* else putc('*', stdout); */ /* 95/Mar/1 */
6395 if (proper & C_MULTIPLE) {
6397 /* (void) FindMMBaseFile(k); */ /* done earlier already */
6398 /* strcpy (fontnamek, fontname + k * MAXTEXNAME); */
6400 if (proper & C_INSTANCE) { /* Is this MM Instance PSS stub ?*/
6401 if (verboseflag) showline(fontnamek, 0); /* 95/May/13 */
6402 if ((proper & C_NOTBASE) != 0)
6403 copyPSS (fp_out, fp_in, k); /* 94/Dec/6 do later ? */
6405 else if (type3flag != 0) {
6406 /* How would type3flag ever get set here ? - By font open mechanism */
6407 if (extracttype3(fp_out, fp_in, k, fontnamek) == 0) {
6408 if (extracttype1(fp_out, fp_in, k, fontnamek) == 0)
6409 copyunknown(fp_out, fp_in, k, fontnamek);
6413 if (extracttype1(fp_out, fp_in, k, fontnamek) == 0) {
6414 if(extracttype3(fp_out, fp_in, k, fontnamek) == 0)
6415 copyunknown(fp_out, fp_in, k, fontnamek);
6418 if (abortflag) return -1;
6419 /* extractfont(fp_out, fp_in, k); */
6423 if (verboseflag) showline("] ", 0);
6424 } /* if (fontsubflag[k] < 0) */
6428 /* main entry point - extract and decompress font files */
6429 /* once it has been verified this works correctly, strip out IGNORE part */
6430 /* present order is: MM base fonts, PSS stub files, other fonts ... */
6432 int extractfonts (FILE *fp_out) /* was called by main */
6435 int proper; /* 1992/Aug/23 */
6436 /* int oldsuppress; */
6438 /* initializeencoding(); */ /* should be done earlier dvipsone.c */
6440 nfonts=0; nsubstitute=0; nremapped=0; nansified=0;
6441 if (fnext == 0) return 0; /* nothing to do ??? */
6443 /* fprintf(fp_out, "dvidict begin\n"); */
6444 writedvistart(fp_out); /* 93/Sep/30 */
6445 /* if (bMarkUnused) MarkUnusedFonts(); */ /* 95/March/5 */
6447 showfonttable(); /* an experiment */
6448 // if (logfileflag) showfonttable(logfile);
6451 task = "decompressing font files";
6453 /* some redundancy with code below */ /* download MM base fonts first */
6454 /* if (fnext > mmbase && forcereside == 0) { */
6455 if (mmcount > 0 && forcereside == 0) { /* ??? */
6456 mmflag = 1; /* flag that these are MM */
6457 /* oldsuppress = bSuppressPartial; */
6458 /* if (bMMNewFlag == 0) bSuppressPartial = 1; *//* backward compat */
6459 /* for (k = mmbase; k < fnext; k++) { */ /* do MM fonts first */
6460 for (k = 0; k < fnext; k++) { /* do MM fonts first */
6461 proper = fontproper[k];
6462 if ((proper & C_MULTIPLE) == 0) continue;
6463 if (extractafont(fp_out, k) != 0) nfonts++;
6464 if (bAbort) abortjob(); /* 1992/Nov/24 */
6465 if (abortflag) return -1;
6466 } /* end of for loop over MM fonts */
6467 /* if (bMMNewFlag == 0) bSuppressPartial = oldsuppress; */
6471 /* extract PSS stub files next */
6473 for (k = 0; k < fnext; k++)
6475 proper = fontproper[k];
6476 if ((proper & C_INSTANCE) == 0) continue;
6477 if (extractafont(fp_out, k) != 0) nfonts++; /* do we count these ? */
6478 if (bAbort) abortjob(); /* 1992/Nov/24 */
6479 if (abortflag) return -1;
6482 /* finally do non MM fonts ... */ /* MM base fonts already done above */
6484 /* for (k = 0; k < mmbase; k++) { */
6485 for (k = 0; k < fnext; k++) { /* 1994/Dec/6 */
6486 proper = fontproper[k];
6487 if (proper & C_MULTIPLE) continue; /* MM base fonts already done */
6488 if (proper & C_INSTANCE) continue; /* MM instances already done */
6489 if (extractafont(fp_out, k) != 0) nfonts++;
6490 if (bAbort) abortjob(); /* 1992/Nov/24 */
6491 if (abortflag) return -1;
6492 } /* for (k=0; k < fnext; k++) */
6493 if (verboseflag) showline("\n", 0);
6495 writedviend(fp_out); /* 1992/Nov/17 */
6497 if (verboseflag) { /* rewrote 1993/Feb/6 */
6499 /* printf("Processed %d font files ", nfonts); */
6500 sprintf(logline, "Processed %d font file%s ", nfonts,
6501 (nfonts == 1) ? "" : "s"); /* 1994/Feb/1 */
6502 else sprintf(logline, "No font files ");
6503 showline(logline, 0);
6508 /* Note: fstart / fend can occur twice (% Font Remap and % Font Defs) */
6509 /* so checking for existing fonts may list only those remapped, miss others */
6510 /* Because `fend' terminates when it has found one or more bad fonts */
6512 /* separated out from the above 94/Mar/3 ************************** */
6514 void fontsetup (FILE *fp_out)
6519 int property; /* 1992/Aug/23 */
6520 // char fname[MAXFONTNAME]; /* 1993/Feb/15 */
6521 char fname[FNAMELEN];
6522 // char fontnamef[MAXTEXNAME];
6523 char fontnamef[FNAMELEN];
6524 // char fontnamek[MAXTEXNAME];
6525 char fontnamek[FNAMELEN];
6526 // char subfontnamek[MAXFONTNAME];
6527 char subfontnamek[FNAMELEN];
6528 static long widths[MAXCHRS]; /* why is this static ? */
6529 /* long widths[MAXCHRS]; */ /* problem with stack space ? */
6532 /* now for the substitutions */
6533 if (substituteflag && needsubstitute() != 0) {
6534 task = "constructing substituted fonts";
6536 if (stripcomment == 0) {
6537 // fputs("% Font Subs:\n", fp_out);
6538 PSputs("% Font Subs:\n", fp_out);
6540 /* fprintf(fp_out, "%s", "dvidict begin\n"); */ /* new */
6541 /* fputs("dvidict begin\n", fp_out); */ /* 1992/July/18 */
6542 writedvistart(fp_out); /* 93/Sep/30 */
6543 for (k = 0; k < fnext; k++) {
6544 property = fontproper[k];
6545 // strcpy (fontnamek, fontname + k * MAXTEXNAME); /* 1994/Feb/2 */
6546 if (fontname[k] != NULL) strcpy (fontnamek, fontname[k]); /* 1994/Feb/2 */
6547 else *fontnamek = '\0';
6548 // strcpy (subfontnamek, subfontname + k * MAXFONTNAME); /* 1997/June/1 */
6549 if (subfontname[k] != NULL) strcpy (subfontnamek, subfontname[k]); /* 1997/June/1 */
6550 else *subfontnamek = '\0';
6551 if ((property & C_REMAPIT) != 0) continue; /* ? */
6552 if ((property & C_RESIDENT) != 0) continue; /* ? */
6553 if ((property & C_DEPENDENT) != 0) continue; /* NEW */
6554 if ((property & C_UNUSED) != 0) continue; /* 95/Sep/9 ??? */
6555 /* if (strcmp(fontname[k], subfontname[k]) == 0) continue; */ /* rep */
6556 if ((f = fontsubflag[k]) >= 0) {
6557 // strcpy (fontnamef, fontname + f * MAXTEXNAME); /* 94/Feb/2 */
6558 if (fontname[f] != NULL) strcpy (fontnamef, fontname[f]); /* 94/Feb/2 */
6559 else *fontnamef = '\0';
6560 /* fprintf(output, "%% FONTSUBFLAG %d\n",
6561 fontsubflag[k]); */ /* debugging */
6562 /* f = fontsubflag[k]; */
6563 /* following moved out here 1995/Sep/9 so we can check usage */
6564 /* fontptr = fontchar + MAXCHRS * k;
6567 for (i= 0; i < ne; i++) if (fontptr[i] != 0) count++;
6569 fontproper[k] |= C_UNUSED;
6571 } */ /* should not happen ! */
6572 /* above moved out here 1995/Sep/9 so we can check usage */
6574 if (stripcomment == 0) {
6575 /* fprintf(fp_out, "%%%%BeginFont: %s\n", fontname[k]); */
6576 /* fprintf(fp_out, "%% BeginFont: %s\n", fontname[k]); */
6577 if (property & C_MULTIPLE) { /* 97/June/1 */
6578 sprintf(logline, "%% BeginFont: %s\n", subfontnamek);
6581 sprintf(logline, "%% BeginFont: %s\n", fontnamek);
6583 PSputs(logline, fp_out);
6585 /* fprintf(fp_out, "/%s fs ", fontname[f]); */
6586 // putc('/', fp_out);
6587 PSputc('/', fp_out);
6588 // if (strcmp(fontprefix, "") != 0) /* 1995/July/5 */
6589 if (fontprefix != NULL) { /* 1995/July/5 */
6590 if (fontreside(f) == 0) {
6591 /* possibly modify if bRandomPrefix is set ??? */
6592 // fputs(fontprefix, fp_out);
6593 PSputs(fontprefix, fp_out);
6596 /* shouldn't this depend on whether it is a texfont or not ??? */
6597 /* if (uppercaseflag) */ /* 1995/July/1 */
6598 if (uppercaseflag && istexfont(fontnamef)) /* 1996/June/20 */
6599 uppercase(fontnamef, fontnamef);
6600 /* fprintf(fp_out, "/%s fs ", fontnamef); */
6601 // fputs(fontnamef, fp_out); /* 1995/July/5 */
6602 PSputs(fontnamef, fp_out); /* 1995/July/5 */
6603 // fputs(" fs ", fp_out);
6604 PSputs(" fs ", fp_out);
6605 /* insert new font metrics - (and possibly new uniqueID ?) */
6606 if (insertmetrics != 0 && (property & C_MTMI) == 0) {
6607 /* if ((ne = readwidths(fontname[k], widths)) != 0) { */
6608 if ((ne = readwidths(fontnamek, widths)) != 0) {
6609 /* fontptr = fontchar[k]; */
6610 /* following moved up above to avoid zero count fonts */
6611 // fontptr = fontchar + MAXCHRS * k;
6612 fontptr = fontchar[k];
6614 for (i= 0; i < ne; i++) if (fontptr[i] != 0) count++;
6616 showline(" zero count", 1); /* 95/Sep/9 */
6618 sprintf(logline, "%d fa\n", count);
6619 PSputs(logline, fp_out);
6620 for (i = 0; i < ne; i++) {
6621 if (fontptr[i] != 0) {
6623 /* following flushed 95/June/6 because fm PS proc *not* scaled */
6624 /* character width in design size units * 2^20 */
6625 /* if (outscaleflag)
6626 fprintf(fp_out, "%d %.9lg fm\n",
6627 i, widths[i] / outscale);
6630 sprintf(logline, "%d %ld fm\n", i, widths[i]);
6631 PSputs(logline, fp_out);
6634 PSputs("fb ", fp_out);
6637 /* fprintf(fp_out, "/%s fe\n", fontname[k]); */
6638 // putc('/', fp_out);
6639 PSputc('/', fp_out);
6640 // if (strcmp(fontprefix, "") != 0)
6641 if (fontprefix != NULL) {
6642 /* if ((fontproper[k] & C_RESIDENT) == 0) */ /* NO ? */
6643 /* possibly modify if bRandomPrefix is set ??? */
6644 // fputs(fontprefix, fp_out); /* 1995/July/5 */
6645 PSputs(fontprefix, fp_out); /* 1995/July/5 */
6647 /* shouldn't this depend on whether it is a texfont or not ??? */
6648 /* if (uppercaseflag) */ /* 1995/July/1 */
6649 if (uppercaseflag && istexfont(fontnamek)) /* 1996/June/20 */
6650 uppercase(fontnamek, fontnamek);
6651 // fputs(fontnamek, fp_out);
6652 PSputs(fontnamek, fp_out);
6653 // fputs(" fe\n", fp_out);
6654 PSputs(" fe\n", fp_out);
6655 if (stripcomment == 0)
6656 /* fprintf(fp_out, "%%%%EndFont\n"); */
6657 /* fprintf(fp_out, "%% EndFont\n"); */
6658 // fputs("% EndFont\n", fp_out);
6659 PSputs("% EndFont\n", fp_out);
6664 writedviend(fp_out); /* 1992/Nov/17 */
6666 if (verboseflag && nsubstitute != 0) {
6667 /* printf("Substituted for %d fonts\n", nsubstitute); */
6668 /* printf("- substituted for %d fonts ", nsubstitute); */
6669 sprintf(logline, "- substituted for %d font%s ",
6670 nsubstitute, (nsubstitute == 1) ? "" : "s"); /* 95/July/15 */
6671 showline(logline, 0);
6675 /* if (needremap() != 0) { */
6676 if ((flag = needremap()) != 0) {
6677 /* constructvectors(fp_out); */
6678 if (flag < 0) constructvectors(fp_out);
6679 task = "constructing remapped fonts";
6681 if (stripcomment == 0) {
6682 // fputs("% Font Remap:\n", fp_out);
6683 PSputs("% Font Remap:\n", fp_out);
6685 /* fprintf(fp_out, "%s", "dvidict begin\n"); */ /* new */
6686 /* fputs("dvidict begin\n", fp_out); */ /* 1992/July/18 */
6687 writedvistart(fp_out); /* 93/Sep/30 */
6688 // fputs("fstart\n", fp_out);
6689 PSputs("fstart\n", fp_out);
6690 for (k = 0; k < fnext; k++) {
6691 property = fontproper[k];
6692 // strcpy (fontnamek, fontname + k * MAXTEXNAME); /* 94/Feb/2 */
6693 if (fontname[k] != NULL) strcpy (fontnamek, fontname[k]); /* 94/Feb/2 */
6694 else *fontnamek = '\0';
6695 // strcpy (subfontnamek, subfontname + k * MAXFONTNAME); /* 97/June/1 */
6696 if (subfontname[k] != NULL) strcpy (subfontnamek, subfontname[k]); /* 97/June/1 */
6697 else *subfontnamek = '\0';
6698 /* printf("k %d proper ", k); */ /* debugging */
6699 if ((property & C_DEPENDENT) != 0) continue;
6700 if ((property & C_UNUSED) != 0) continue; /* 1995/Mar/27 */
6701 /* if (strcmp(fontname[k], subfontname[k]) == 0) continue; */ /* ? */
6702 /* if ((property & C_REMAPIT) != 0 &&
6703 (property & C_RESIDENT) != 0) { */
6704 /* Shouldn't really bother doing this for MM Base Font if it is resident */
6705 /* Since the PSS stub then refers to PS FontName, not this new name ... */
6706 /* only do this for printer resident fonts */
6707 /* if ((property & C_RESIDENT) == 0) continue; */
6708 /* only do this for printer resident fonts and MM base fonts */
6709 if ((property & C_RESIDENT) == 0 && (property & C_MULTIPLE) == 0) continue;
6710 /* only do this if font needs to be remapped */
6711 if ((property & C_REMAPIT) == 0 && bWindowsFlag == 0) continue;
6712 /* if ((property & C_RESIDENT) != 0 &&
6713 ((property & C_REMAPIT) != 0 ||
6714 bWindowsFlag != 0)) { */
6715 if (stripcomment == 0) {
6716 if (property & C_MULTIPLE) { /* 97/June/1 */
6717 sprintf(logline, "%% BeginFont: %s\n", subfontnamek);
6720 sprintf(logline, "%% BeginFont: %s\n", fontnamek);
6722 PSputs(logline, fp_out);
6724 // putc('/', fp_out);
6725 PSputc('/', fp_out);
6726 /* if (strcmp(fontprefix, "") != 0) fputs(fontprefix, fp_out); */
6727 // if (strcmp(fontprefix, "") != 0) /* 1995/July/5 */
6728 if (fontprefix != NULL) { /* 1995/July/5 */
6729 if (fontreside(k) == 0) {
6730 /* possibly modify if bRandomPrefix is set ??? */
6731 // fputs(fontprefix, fp_out);
6732 PSputs(fontprefix, fp_out);
6735 /* strcpy(fname, fontname + k * MAXTEXNAME); */ /* 1994/Feb/2 */
6736 if (property & C_MULTIPLE) { /* 97/June/1 */
6739 // strcat(fname, subfontname + k * MAXFONTNAME);
6740 if (subfontname[k] != NULL) strcat(fname, subfontname[k]);
6743 // strcpy(fname, fontname + k * MAXTEXNAME); /* 1994/Feb/2 */
6744 if (fontname[k] != NULL) strcpy(fname, fontname[k]); /* 1994/Feb/2 */
6747 if (uppercaseflag != 0 && istexfont(fname) != 0)
6748 uppercase(fname, fname);
6749 /* fprintf(fp_out, "/%s %s /%s rmf\n",
6750 fontname[k], fontvector[k], subfontname[k]); */
6751 // strcpy (subfontnamek, subfontname + k * MAXFONTNAME);/* 94/Feb/2 */
6752 if (subfontname[k] != NULL) strcpy (subfontnamek, subfontname[k]);/* 94/Feb/2 */
6753 else *subfontnamek = '\0';
6754 if ((property & C_REMAPIT) != 0) {
6755 sprintf(logline, "%s %s /%s rmf\n",
6756 /* fname, fontvector[k], subfontname[k]); */
6757 // fname, fontvector + k * MAXVECNAME, subfontnamek);
6758 fname, fontvector[k], subfontnamek);
6760 else { /* just due to Windows ANSI remap */
6761 sprintf(logline, "%s %s /%s amf\n",
6762 /* fname, "ansinew", subfontname[k]); */ /* 93/Oct/4 */
6763 /* fname, "ansinew", subfontnamek); */ /* 94/Feb/2 */
6764 /* fname, textencoding, subfontnamek); */ /* 94/Dec/17 */
6765 fname, textenconame, subfontnamek); /* 95/Feb/6 */
6767 PSputs(logline, fp_out);
6768 /* copy font directory and insert new encoding vector */
6769 if (stripcomment == 0) {
6770 /* fprintf(fp_out, "%%%%EndFont\n"); */
6771 /* fprintf(fp_out, "%% EndFont\n"); */
6772 // fputs("% EndFont\n", fp_out);
6773 PSputs("% EndFont\n", fp_out);
6776 /* } */ /* end of resident and remapped */
6777 } /* end of for loop stepping through fonts */
6779 // fputs("fend\n", fp_out);
6780 PSputs("fend\n", fp_out);
6781 writedviend(fp_out); /* 1992/Nov/17 */
6782 } /* end of need remapped */
6784 /* NOTE: this only counts the resident fonts that get remapped ? */
6785 /* if (verboseflag && nremapped != 0)
6786 printf("- remapped %d fonts ", nremapped); */
6787 /* n = nremapped + nansified; */
6788 /* if (verboseflag && n != 0) */
6790 if (nremapped > 0 || nansified > 0) {
6791 if (nremapped > 0) {
6792 sprintf(logline, " - remapped %d font%s", nremapped,
6793 (nremapped == 1) ? "" : "s");
6794 showline(logline, 0);
6797 sprintf(logline, " - remapped %d font%s to `%s' encoding", nansified,
6798 (nansified == 1) ? "" : "s", textencoding);
6799 showline(logline, 0);
6801 /* putc('.', stdout); */
6802 /* putc('\n', stdout); */
6805 /* suppress the above if remapped font is not resident ? */
6807 /* now it is time to actually do the setfonts ! */
6809 if (stripcomment == 0) {
6810 /* fputs("%%BeginSetup\n, fp_out); */ /* ??? */
6811 // fputs("% Font Defs\n", fp_out);
6812 PSputs("% Font Defs\n", fp_out);
6815 /* fprintf(fp_out, "dvidict begin\n"); */
6816 writedvistart(fp_out); /* 93/Sep/30 */
6817 // fprintf(fp_out, "fstart\n"); /* 93/Nov/2 */
6818 PSputs("fstart\n", fp_out);
6819 /* if (bShortFont != 0) { */
6820 if (bShortFont != 0 && bUseInternal == 0) { /* 1994/June/7 */
6821 for (f = 0; f < fnext; f++) dofont(fp_out, f, f);
6823 /* the first chunck of old code above came from here ... */
6824 else { /* not using short font numbers */
6825 for (k=0; k < MAXFONTNUMBERS; k++)
6826 /* if ((f = finx[k]) >= 0) dofont(fp_out, f, k); */ /* 93/Dec/11 */
6827 if ((f = finx[k]) != BLANKFONT) dofont(fp_out, f, k);
6830 /* the second chunck of old code above came from here ... */
6831 // fprintf(fp_out, "fend\n"); /* 93/Nov/2 */
6832 PSputs("fend\n", fp_out);
6834 writedviend(fp_out); /* 1992/Nov/17 */
6836 /* fputs("%%EndSetup\n", fp_out); */ /* ??? */
6839 /* Following called from dvispeci.c */
6840 /* Don't expand %%IncludeFont for printer resident fonts */
6841 /* Use a fixed list ??? */
6842 /* tir, tii, tib, tibi, hv, hvo, hvb, hvbo, com, coo, cob, cobo, sy, zd */
6844 int ResidentFont (char *FileName) /* 1994/Feb/10 */
6852 sprintf(logline, "ResidentFont %s?\n", FileName); /* debugging 97/June/5 */
6853 showline(logline, 0);
6856 /* extract just font file name - get rid of path */
6857 /* if ((s = strrchr(FileName, '\\')) != NULL) s++;
6858 else if ((s = strrchr(FileName, '/')) != NULL) s++;
6859 else if ((s = strrchr(FileName, ':')) != NULL) s++;
6860 else s = FileName; */
6861 s = removepath(FileName); /* 95/May/28 */
6862 /* get rid of extension */
6863 if ((t = strrchr(s, '.')) != NULL) *t ='\0';
6864 t = s + strlen(s) - 1;
6865 while (*t == '_') *t-- = '\0'; /* strip underscores */
6868 sprintf(logline, "Looking for font file: `%s'\n", s);/* debugging 97/June/5 */
6869 showline(logline, 0);
6872 for (k = 0; k < ksubst; k++) {
6873 if (fontsubprop[k] & C_RESIDENT) {
6874 /* if (strcmp (s, fontsubfrom + k * MAXTEXNAME) == 0) */
6875 // if (stricmp (s, fontsubfrom + k * MAXTEXNAME) == 0)
6876 if (fontsubfrom[k] != NULL &&
6877 stricmp (s, fontsubfrom[k]) == 0)
6878 return 1; /* is resident in table */
6881 return 0; /* not in table as resident font */
6884 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
6886 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
6888 /* should earlier BeginSetup and EndSetup be moved to after loading fonts ? */
6890 /* should tokenize input ? - remove dependency on lines */
6891 /* definitely ignoring synthetic and hybrid fonts ? */
6892 /* change font dictionary allocation ? first line after end of FontInfo OK */
6893 /* abbreviate dup and put ? */
6894 /* flush space before ND or | - NOT SAFE ?, make selectable ? */
6895 /* flush \r both before encryption and after - make selectable ? */
6897 /* extract actual FontName from font directory OK, not used */
6898 /* replace actual FontName with what was passed along from dvianal OK */
6899 /* make up copies of fonts with different metrics, if substituting OK */
6900 /* need to read tfm files for this OK */
6902 /* need to check EOF in calls to getline */
6904 /* RD could be -| and ND could be | OK */
6905 /* check on how this treats Subrs and OtherSubrs !!! */
6907 /* do the right thing with StandardEncoding ? */
6908 /* will this every be used with fonts other than TeX fonts ? */
6909 /* distinguish TeX fonts ? */
6911 /* possibly copy over that stuff from fontone.c */
6912 /* for constructing Encoding from StandardEncoding ? efficiency */
6913 /* break up big functions to allow global optimizations */
6915 /* make default directory c:\psfonts instead of c:\cm ? */
6917 /* allow for cmr10___.pfb format of file name OK */
6919 /* make deletion of input files default - controlled by command line flag */
6921 /* decrypt, remove first four bytes of each CharString reencrypt lenIV NO */
6922 /* allow for removal of four leading bytes in CharStrings ? NO */
6924 /* make flushing of FontInfo optional ... */
6926 /* give warning if ASCII section has wrong length ? */
6928 /* send control D if output direct to printer, or if requested. OK */
6930 /* stick in %!PS-Adobe-2.0 etc etc at beginning ? OK */
6932 /* in case only page interval output is selected, slight weirdness: */
6933 /* will set up fonts that are not used and hence not loaded */
6934 /* but no error results, Courier is substituted, but no one knows */
6935 /* since font never actually used ... */ /* to be fixed in merge OK ? */
6937 /* may need facility to generate new uniqueIDs */
6938 /* better to leave uniqueID off copy of font ? YES */
6939 /* helpful generating new uniqueID ? NO */
6941 /* distinguish force substitution from substitution when file not found */
6942 /* invoke substitution when file not found ? OK */
6944 /* some time break up "extractfont" and "extract" */
6946 /* use table for dehexing hex and for creating hex ? */
6948 /* right now there is no check whether font substituted exists ! */
6949 /* if it is not found try using table again ? loops ? */
6951 /* specify encoding vector in substitution file */
6953 /* problems remain with remapping resident fonts ... */
6955 /* deal with *force* in substitution table OK */
6956 /* deal with *remap* in substitution table OK */
6958 /* maybe check whether font file already was .pfb before trying that ext OK */
6960 /* search for *//* make parallel to above ! */
6962 /* worry about possible problems from assumed font ending - breakearly ? */
6963 /* breakearly != 0 may be too risky - don't know what weird things happen */
6965 /* should tokenize input ? - remove dependency on lines */
6967 /* what about .pfb files that have return as line terminator ? OK */
6968 /* need to fix getline and getrealline to deal with this */
6970 /* need to treat /Subr strings specially */
6971 /* particularly since they may be long */
6973 /* output font file name in [..] always - even for remapped fonts ? */
6975 /* major space user is charnames[MAXCHRS][MAXCHARNAME] = 8192 bytes */
6976 /* OK, cut in half by using pointers into namestring instead */
6978 /* check if font is really needed before bothering to extract it OK */
6980 /* `Substituting' Times-Roman for psmtr - isn't quite appropriate phrasing */
6982 /* check that long checksum = 0x424B5048; - add brownie points ? */
6984 /* should *reside* imply *force* ? */ /* no, use *force* explicitely */
6985 /* should *remap* imply force ? */
6987 /* maybe remove default font substitution table ? - always read it in ? */
6989 /* don't reread font substitution table for each DVI file processed ? */
6990 /* NO, have to, since it may be on DVI file path ! */
6992 /* simplify all that hair for making up encoding vectors ... */
6994 /* don't use textext vec if output is to be previewed ? use flag to control */
6996 /* assuming it is either RD or -| and ND or |- */
6998 /* do we need to cripple UniqueID when reencoding and using dviencoding ? */
7000 /* command line flag 'k' not tested (forces printer resident for all) */
7002 /* Compound Fonts are `Oblique' and `Narrow' fonts. Examples: */
7003 /* Courier-Oblique, Courier-BoldOblique */
7004 /* Helvetica-Oblique, Helvetica-BoldOblique */
7005 /* Helvetica-Narrow, Helvetica-Narrow-Bold */
7006 /* Helvetica-Narrow-Oblique, Helvetica-Narrow-BoldOblique */
7007 /* Typically these have Fontmatrix m11 != m22 or m21 != 0 */
7009 /* What's the problem with synthetic fonts ? Why be paranoid ? */
7010 /* 1. They may pick up base font that is partial (but FontName changed?) */
7011 /* 2. They may create a font that is partial (but has original name) */
7012 /* 3. There may be a problem if font is remapped ? */
7013 /* but only if the base font is picked up by some other font ... */
7015 /* Some interpreters fail on textext encoding, cause its not 256 element */
7016 /* Some interpreters fail on shortened encoding, cause its not 256 element */
7017 /* examples: ALW II NTJ */
7019 /* complain if `hires' so-called hybrid font ??? */
7020 /* ask user to use *synthetic* flag */ /* Not any more, hybrid font fixed */
7022 /* problems with fonts that have wrappings mostly fixed */
7023 /* can handle wrapped synthetic fonts now */
7024 /* may be able to handle wrapped PFA fonts also */
7026 /* Typical wrapping format: */
7028 /* FontDirectory/Symbol known{/Symbol findfont dup/UniqueID known{dup */
7029 /* /UniqueID get 5016107 eq exch/FontType get 1 eq and}{pop false}ifelse */
7030 /* {save true}{false}ifelse}{false}ifelse */
7035 /* cleartomark{restore}if */
7037 /* Note: In DOS, TFM file names are not case sensitive in TeX */
7038 /* however, here in dealing with font substitution file, things ARE */
7039 /* So, its possible to get confused because a font is found by TeX */
7040 /* but not matched in substitution table */
7042 /* Note `k' turns on *force* and *reside* which may not be desirable for */
7043 /* lines like `cmr8 cmr7' which should only trigger if cmr8 is not found */
7044 /* However, the new scheme for getting FontNames from PFB files solves */
7045 /* this problem ... */
7047 /* MM font support incomplete */
7048 /* presently downloads full font - need to provide for partial font */
7049 /* collect wantchrs contributions from MM instances for base */
7050 /* remap / encoding not checked out */
7052 /* if forcereside on, we should still download/expand the PSS stubs ... */
7054 /* extracttype3, does fontname get printed ? */
7055 /* mac style font, does fontname get printed ? */
7056 /* what is font can't be found does font name get printed ? */
7057 /* what is some error in extraction does font name get printed ? */
7058 /* repeated output of font name if switch between type3 and type1 */
7060 /* Presently we reencode the PSS stub files if needed */
7061 /* We do not reencode the MM master file */
7062 /* Which means we can't do selected down loading quite yet */
7063 /* Also seems like we are reencoding to ENCODING the PSS stub */
7064 /* without knowing whether the base font is a text font! */
7066 /* if we want to use partial font downloading, then need to reencode */
7067 /* and then we have to assume that all instances encoded the same ? */
7068 /* we also then need to set up wantchrs[] as or of instances ... */