1 /*
2 Copyright 1996-2014 Han The Thanh <thanh@pdftex.org>
3 
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8 
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 GNU General Public License for more details.
13 
14 You should have received a copy of the GNU General Public License
15 along with this program.  If not, see  <http://www.gnu.org/licenses/>.  */
16 
17 #include "ptexlib.h"
18 #include <stdarg.h>
19 #include <string.h>
20 
21 #define t1_log(str)      tex_printf("%s",str)
22 #define get_length1()    t1_length1 = t1_offset() - t1_save_offset
23 #define get_length2()    t1_length2 = t1_offset() - t1_save_offset
24 #define get_length3()    t1_length3 = fixedcontent? t1_offset() - t1_save_offset : 0
25 #define save_offset()    t1_save_offset = t1_offset()
26 
27 #define t1_open()        open_input(&t1_file, kpse_type1_format, FOPEN_RBIN_MODE)
28 #define t1_close()       xfclose(t1_file, cur_file_name)
29 #define t1_getchar()     getc(t1_file)
30 #define t1_putchar       fb_putchar
31 #define t1_offset        fb_offset
32 #define t1_ungetchar(c)  ungetc(c, t1_file)
33 #define t1_eof()         feof(t1_file)
34 
35 #define t1_prefix(s)     str_prefix(t1_line_array, s)
36 #define t1_buf_prefix(s) str_prefix(t1_buf_array, s)
37 #define t1_suffix(s)     str_suffix(t1_line_array, t1_line_ptr, s)
38 #define t1_buf_suffix(s) str_suffix(t1_buf_array, t1_buf_ptr, s)
39 #define t1_charstrings() strstr(t1_line_array, charstringname)
40 #define t1_subrs()       t1_prefix("/Subrs")
41 #define t1_end_eexec()   t1_suffix("mark currentfile closefile")
42 #define t1_cleartomark() t1_prefix("cleartomark")
43 
44 #define enc_open()       open_input(&enc_file, kpse_enc_format, FOPEN_RBIN_MODE)
45 #define enc_close()      xfclose(enc_file, cur_file_name)
46 #define enc_getchar()    getc(enc_file)
47 #define enc_eof()        feof(enc_file)
48 
49 #define valid_code(c)    (c >= 0 && c < 256)
50 #define fixedcontent     false /* false for pdfTeX, true for dvips */
51 
52 static const char *standard_glyph_names[256] = {
53     /* 0x00 */
54     notdef, notdef, notdef, notdef, notdef, notdef, notdef, notdef, notdef,
55     notdef, notdef, notdef, notdef, notdef, notdef, notdef,
56     /* 0x10 */
57     notdef, notdef, notdef, notdef, notdef, notdef, notdef, notdef, notdef,
58     notdef, notdef, notdef, notdef, notdef, notdef, notdef,
59     /* 0x20 */
60     "space", "exclam", "quotedbl", "numbersign", "dollar", "percent",
61     "ampersand", "quoteright", "parenleft", "parenright", "asterisk",
62     "plus", "comma", "hyphen", "period", "slash",
63     /* 0x30 */
64     "zero", "one", "two", "three", "four", "five", "six", "seven", "eight",
65     "nine", "colon", "semicolon", "less", "equal", "greater", "question",
66     /* 0x40 */
67     "at", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N",
68     "O",
69     /* 0x50 */
70     "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "bracketleft",
71     "backslash", "bracketright", "asciicircum", "underscore",
72     /* 0x60 */
73     "quoteleft", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l",
74     "m", "n", "o",
75     /* 0x70 */
76     "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "braceleft", "bar",
77     "braceright", "asciitilde", notdef,
78     /* 0x80 */
79     notdef, notdef, notdef, notdef, notdef, notdef, notdef, notdef, notdef,
80     notdef, notdef, notdef, notdef, notdef, notdef, notdef,
81     /* 0x90 */
82     notdef, notdef, notdef, notdef, notdef, notdef, notdef, notdef, notdef,
83     notdef, notdef, notdef, notdef, notdef, notdef, notdef,
84     /* 0xa0 */
85     notdef, "exclamdown", "cent", "sterling", "fraction", "yen", "florin",
86     "section", "currency", "quotesingle", "quotedblleft", "guillemotleft",
87     "guilsinglleft", "guilsinglright", "fi", "fl",
88     /* 0xb0 */
89     notdef, "endash", "dagger", "daggerdbl", "periodcentered", notdef,
90     "paragraph", "bullet", "quotesinglbase", "quotedblbase",
91     "quotedblright", "guillemotright", "ellipsis", "perthousand", notdef,
92     "questiondown",
93     /* 0xc0 */
94     notdef, "grave", "acute", "circumflex", "tilde", "macron", "breve",
95     "dotaccent", "dieresis", notdef,
96     "ring", "cedilla", notdef, "hungarumlaut", "ogonek", "caron",
97     /* 0xd0 */
98     "emdash", notdef, notdef, notdef, notdef, notdef, notdef, notdef, notdef,
99     notdef, notdef, notdef, notdef, notdef, notdef, notdef,
100     /* 0xe0 */
101     notdef, "AE", notdef, "ordfeminine", notdef, notdef, notdef, notdef,
102     "Lslash", "Oslash", "OE", "ordmasculine", notdef, notdef, notdef,
103     notdef,
104     /* 0xf0 */
105     notdef, "ae", notdef, notdef, notdef, "dotlessi", notdef, notdef, "lslash",
106     "oslash", "oe", "germandbls", notdef, notdef, notdef, notdef
107 };
108 
109 integer t1_length1, t1_length2, t1_length3;
110 static integer t1_save_offset;
111 static integer t1_fontname_offset;
112 static fd_entry *fd_cur;
113 
114 static char charstringname[] = "/CharStrings";
115 
116 enum { ENC_STANDARD, ENC_BUILTIN } t1_encoding;
117 
118 #define T1_BUF_SIZE      0x10
119 #define ENC_BUF_SIZE     0x1000
120 
121 #define CS_HSTEM         1
122 #define CS_VSTEM         3
123 #define CS_VMOVETO       4
124 #define CS_RLINETO       5
125 #define CS_HLINETO       6
126 #define CS_VLINETO       7
127 #define CS_RRCURVETO     8
128 #define CS_CLOSEPATH     9
129 #define CS_CALLSUBR      10
130 #define CS_RETURN        11
131 #define CS_ESCAPE        12
132 #define CS_HSBW          13
133 #define CS_ENDCHAR       14
134 #define CS_RMOVETO       21
135 #define CS_HMOVETO       22
136 #define CS_VHCURVETO     30
137 #define CS_HVCURVETO     31
138 #define CS_1BYTE_MAX     (CS_HVCURVETO + 1)
139 
140 #define CS_DOTSECTION    CS_1BYTE_MAX + 0
141 #define CS_VSTEM3        CS_1BYTE_MAX + 1
142 #define CS_HSTEM3        CS_1BYTE_MAX + 2
143 #define CS_SEAC          CS_1BYTE_MAX + 6
144 #define CS_SBW           CS_1BYTE_MAX + 7
145 #define CS_DIV           CS_1BYTE_MAX + 12
146 #define CS_CALLOTHERSUBR CS_1BYTE_MAX + 16
147 #define CS_POP           CS_1BYTE_MAX + 17
148 #define CS_SETCURRENTPOINT CS_1BYTE_MAX + 33
149 #define CS_2BYTE_MAX     (CS_SETCURRENTPOINT + 1)
150 #define CS_MAX           CS_2BYTE_MAX
151 
152 typedef unsigned char byte;
153 
154 typedef struct {
155     byte nargs;                 /* number of arguments */
156     boolean bottom;             /* take arguments from bottom of stack? */
157     boolean clear;              /* clear stack? */
158     boolean valid;
159 } cc_entry;                     /* CharString Command */
160 
161 typedef struct {
162     char *name;                 /* glyph name (or notdef for Subrs entry) */
163     byte *data;
164     unsigned short len;         /* length of the whole string */
165     unsigned short cslen;       /* length of the encoded part of the string */
166     boolean used;
167     boolean valid;
168 } cs_entry;
169 
170 static unsigned short t1_dr, t1_er;
171 static const unsigned short t1_c1 = 52845, t1_c2 = 22719;
172 static unsigned short t1_cslen;
173 static short t1_lenIV;
174 static char enc_line[ENC_BUF_SIZE];
175 
176 /* define t1_line_ptr, t1_line_array & t1_line_limit */
177 typedef char t1_line_entry;
178 define_array(t1_line);
179 
180 /* define t1_buf_ptr, t1_buf_array & t1_buf_limit */
181 typedef char t1_buf_entry;
182 define_array(t1_buf);
183 
184 static int cs_start;
185 
186 static cs_entry *cs_tab, *cs_ptr, *cs_notdef;
187 static char *cs_dict_start, *cs_dict_end;
188 static int cs_count, cs_size, cs_size_pos;
189 
190 static cs_entry *subr_tab;
191 static char *subr_array_start, *subr_array_end;
192 static int subr_max, subr_size, subr_size_pos;
193 
194 /* This list contains the begin/end tokens commonly used in the */
195 /* /Subrs array of a Type 1 font.                               */
196 
197 static const char *cs_token_pairs_list[][2] = {
198     {" RD", "NP"},
199     {" -|", "|"},
200     {" RD", "noaccess put"},
201     {" -|", "noaccess put"},
202     {NULL, NULL}
203 };
204 static const char **cs_token_pair;
205 
206 static boolean t1_pfa, t1_cs, t1_scan, t1_eexec_encrypt, t1_synthetic;
207 static int t1_in_eexec;         /* 0 before eexec-encrypted, 1 during, 2 after */
208 static long t1_block_length;
209 static int last_hexbyte;
210 static FILE *t1_file;
211 static FILE *enc_file;
212 
enc_getline(void)213 static void enc_getline(void)
214 {
215     char *p;
216     int c;
217   restart:
218     if (enc_eof())
219         pdftex_fail("unexpected end of file");
220     p = enc_line;
221     do {
222         c = enc_getchar();
223         append_char_to_buf(c, p, enc_line, ENC_BUF_SIZE);
224     } while (c != 10);
225     append_eol(p, enc_line, ENC_BUF_SIZE);
226     if (p - enc_line < 2 || *enc_line == '%')
227         goto restart;
228 }
229 
230 /* read encoding from .enc file, return glyph_names array, or pdffail() */
231 
load_enc_file(char * enc_name)232 char **load_enc_file(char *enc_name)
233 {
234     char buf[ENC_BUF_SIZE], *p, *r;
235     int i, names_count;
236     char **glyph_names;
237     set_cur_file_name(enc_name);
238     if (!enc_open()) {
239         pdftex_fail("cannot open encoding file for reading");
240     }
241     glyph_names = xtalloc(256, char *);
242     for (i = 0; i < 256; i++)
243         glyph_names[i] = notdef;
244     t1_log("{");
245     t1_log(cur_file_name = (char *) nameoffile + 1);
246     enc_getline();
247     if (*enc_line != '/' || (r = strchr(enc_line, '[')) == NULL) {
248         remove_eol(r, enc_line);
249         pdftex_fail
250            ("invalid encoding vector (a name or `[' missing): `%s'", enc_line);
251     }
252     names_count = 0;
253     r++;                        /* skip '[' */
254     skip(r, ' ');
255     for (;;) {
256         while (*r == '/') {
257             for (p = buf, r++;
258                  *r != ' ' && *r != 10 && *r != ']' && *r != '/'; *p++ = *r++);
259             *p = 0;
260             skip(r, ' ');
261             if (names_count > 255)
262                 pdftex_fail("encoding vector contains more than 256 names");
263             if (strcmp(buf, notdef) != 0)
264                 glyph_names[names_count] = xstrdup(buf);
265             names_count++;
266         }
267         if (*r != 10 && *r != '%') {
268             if (str_prefix(r, "] def"))
269                 goto done;
270             else {
271                 remove_eol(r, enc_line);
272                 pdftex_fail
273        ("invalid encoding vector: a name or `] def' expected: `%s'", enc_line);
274             }
275         }
276         enc_getline();
277         r = enc_line;
278     }
279   done:
280     enc_close();
281     t1_log("}");
282     cur_file_name = NULL;
283     return glyph_names;
284 }
285 
t1_check_pfa(void)286 static void t1_check_pfa(void)
287 {
288     const int c = t1_getchar();
289     t1_pfa = (c != 128) ? true : false;
290     t1_ungetchar(c);
291 }
292 
t1_getbyte(void)293 static int t1_getbyte(void)
294 {
295     int c = t1_getchar();
296     if (t1_pfa)
297         return c;
298     if (t1_block_length == 0) {
299         if (c != 128)
300             pdftex_fail("invalid marker");
301         c = t1_getchar();
302         if (c == 3) {
303             while (!t1_eof())
304                 t1_getchar();
305             return EOF;
306         }
307         t1_block_length = t1_getchar() & 0xff;
308         t1_block_length |= (t1_getchar() & 0xff) << 8;
309         t1_block_length |= (t1_getchar() & 0xff) << 16;
310         t1_block_length |= (t1_getchar() & 0xff) << 24;
311         c = t1_getchar();
312     }
313     t1_block_length--;
314     return c;
315 }
316 
hexval(int c)317 static int hexval(int c)
318 {
319     if (c >= 'A' && c <= 'F')
320         return c - 'A' + 10;
321     else if (c >= 'a' && c <= 'f')
322         return c - 'a' + 10;
323     else if (c >= '0' && c <= '9')
324         return c - '0';
325     else
326         return -1;
327 }
328 
edecrypt(byte cipher)329 static byte edecrypt(byte cipher)
330 {
331     byte plain;
332     if (t1_pfa) {
333         while (cipher == 10 || cipher == 13)
334             cipher = t1_getbyte();
335         last_hexbyte = cipher = (hexval(cipher) << 4) + hexval(t1_getbyte());
336     }
337     plain = (cipher ^ (t1_dr >> 8));
338     t1_dr = (cipher + t1_dr) * t1_c1 + t1_c2;
339     return plain;
340 }
341 
cdecrypt(byte cipher,unsigned short * cr)342 static byte cdecrypt(byte cipher, unsigned short *cr)
343 {
344     const byte plain = (cipher ^ (*cr >> 8));
345     *cr = (cipher + *cr) * t1_c1 + t1_c2;
346     return plain;
347 }
348 
eencrypt(byte plain)349 static byte eencrypt(byte plain)
350 {
351     const byte cipher = (plain ^ (t1_er >> 8));
352     t1_er = (cipher + t1_er) * t1_c1 + t1_c2;
353     return cipher;
354 }
355 
cencrypt(byte plain,unsigned short * cr)356 static byte cencrypt(byte plain, unsigned short *cr)
357 {
358     const byte cipher = (plain ^ (*cr >> 8));
359     *cr = (cipher + *cr) * t1_c1 + t1_c2;
360     return cipher;
361 }
362 
eol(char * s)363 static char *eol(char *s)
364 {
365     char *p = strend(s);
366     if (p - s > 1 && p[-1] != 10) {
367         *p++ = 10;
368         *p = 0;
369     }
370     return p;
371 }
372 
t1_scan_num(char * p,char ** r)373 static float t1_scan_num(char *p, char **r)
374 {
375     float f;
376     skip(p, ' ');
377     if (sscanf(p, "%g", &f) != 1) {
378         remove_eol(p, t1_line_array);
379         pdftex_fail("a number expected: `%s'", t1_line_array);
380     }
381     if (r != NULL) {
382         for (; isdigit((unsigned char)*p) || *p == '.' ||
383              *p == 'e' || *p == 'E' || *p == '+' || *p == '-'; p++);
384         *r = p;
385     }
386     return f;
387 }
388 
str_suffix(const char * begin_buf,const char * end_buf,const char * s)389 static boolean str_suffix(const char *begin_buf, const char *end_buf,
390                           const char *s)
391 {
392     const char *s1 = end_buf - 1, *s2 = strend(s) - 1;
393     if (*s1 == 10)
394         s1--;
395     while (s1 >= begin_buf && s2 >= s) {
396         if (*s1-- != *s2--)
397             return false;
398     }
399     return s2 < s;
400 }
401 
t1_getline(void)402 static void t1_getline(void)
403 {
404     int c, l, eexec_scan;
405     char *p;
406     static const char eexec_str[] = "currentfile eexec";
407     static int eexec_len = 17;  /* strlen(eexec_str) */
408   restart:
409     if (t1_eof())
410         pdftex_fail("unexpected end of file");
411     t1_line_ptr = t1_line_array;
412     alloc_array(t1_line, 1, T1_BUF_SIZE);
413     t1_cslen = 0;
414     eexec_scan = 0;
415     c = t1_getbyte();
416     if (c == EOF)
417         goto exit;
418     while (!t1_eof()) {
419         if (t1_in_eexec == 1)
420             c = edecrypt((byte)c);
421         alloc_array(t1_line, 1, T1_BUF_SIZE);
422         append_char_to_buf(c, t1_line_ptr, t1_line_array, t1_line_limit);
423         if (t1_in_eexec == 0 && eexec_scan >= 0 && eexec_scan < eexec_len) {
424             if (t1_line_array[eexec_scan] == eexec_str[eexec_scan])
425                 eexec_scan++;
426             else
427                 eexec_scan = -1;
428         }
429         if (c == 10 || (t1_pfa && eexec_scan == eexec_len && c == 32))
430             break;
431         if (t1_cs && t1_cslen == 0 && (t1_line_ptr - t1_line_array > 4) &&
432             (t1_suffix(" RD ") || t1_suffix(" -| "))) {
433             p = t1_line_ptr - 5;
434             while (*p != ' ')
435                 p--;
436             t1_cslen = l = t1_scan_num(p + 1, 0);
437             cs_start = t1_line_ptr - t1_line_array;     /* cs_start is an index now */
438             alloc_array(t1_line, l, T1_BUF_SIZE);
439             while (l-- > 0)
440                 *t1_line_ptr++ = edecrypt((byte)t1_getbyte());
441         }
442         c = t1_getbyte();
443     }
444     alloc_array(t1_line, 2, T1_BUF_SIZE);       /* append_eol can append 2 chars */
445     append_eol(t1_line_ptr, t1_line_array, t1_line_limit);
446     if (t1_line_ptr - t1_line_array < 2)
447         goto restart;
448     if (eexec_scan == eexec_len)
449         t1_in_eexec = 1;
450   exit:
451     /* ensure that t1_buf_array has as much room as t1_line_array */
452     t1_buf_ptr = t1_buf_array;
453     alloc_array(t1_buf, t1_line_limit, t1_line_limit);
454 }
455 
t1_putline(void)456 static void t1_putline(void)
457 {
458     char *p = t1_line_array;
459     if (t1_line_ptr - t1_line_array <= 1)
460         return;
461     if (t1_eexec_encrypt) {
462         while (p < t1_line_ptr)
463             t1_putchar(eencrypt(*p++));
464     } else
465         while (p < t1_line_ptr)
466             t1_putchar(*p++);
467 }
468 
t1_puts(const char * s)469 static void t1_puts(const char *s)
470 {
471     if (s != t1_line_array)
472         strcpy(t1_line_array, s);
473     t1_line_ptr = strend(t1_line_array);
474     t1_putline();
475 }
476 
477 __attribute__ ((format(printf, 1, 2)))
t1_printf(const char * fmt,...)478 static void t1_printf(const char *fmt, ...)
479 {
480     va_list args;
481     va_start(args, fmt);
482     vsprintf(t1_line_array, fmt, args);
483     t1_puts(t1_line_array);
484     va_end(args);
485 }
486 
t1_init_params(const char * open_name_prefix)487 static void t1_init_params(const char *open_name_prefix)
488 {
489     t1_log(open_name_prefix);
490     t1_log(cur_file_name);
491     t1_lenIV = 4;
492     t1_dr = 55665;
493     t1_er = 55665;
494     t1_in_eexec = 0;
495     t1_cs = false;
496     t1_scan = true;
497     t1_synthetic = false;
498     t1_eexec_encrypt = false;
499     t1_block_length = 0;
500     t1_check_pfa();
501 }
502 
t1_close_font_file(const char * close_name_suffix)503 static void t1_close_font_file(const char *close_name_suffix)
504 {
505     t1_log(close_name_suffix);
506     t1_close();
507     cur_file_name = NULL;
508 }
509 
t1_check_block_len(boolean decrypt)510 static void t1_check_block_len(boolean decrypt)
511 {
512     int l, c;
513     if (t1_block_length == 0)
514         return;
515     c = t1_getbyte();
516     if (decrypt)
517         c = edecrypt((byte)c);
518     l = t1_block_length;
519     if (!(l == 0 && (c == 10 || c == 13))) {
520         pdftex_fail("%i bytes more than expected", l + 1);
521     }
522 }
523 
t1_start_eexec(void)524 static void t1_start_eexec(void)
525 {
526     int i;
527     assert(is_included(fd_cur->fm));
528     get_length1();
529     save_offset();
530     if (!t1_pfa)
531         t1_check_block_len(false);
532     for (t1_line_ptr = t1_line_array, i = 0; i < 4; i++) {
533         edecrypt((byte)t1_getbyte());
534         *t1_line_ptr++ = 0;
535     }
536     t1_eexec_encrypt = true;
537     t1_putline();               /* to put the first four bytes */
538 }
539 
t1_stop_eexec(void)540 static void t1_stop_eexec(void)
541 {
542     int c;
543     assert(is_included(fd_cur->fm));
544     get_length2();
545     save_offset();
546     t1_eexec_encrypt = false;
547     if (!t1_pfa)
548         t1_check_block_len(true);
549     else {
550         c = edecrypt((byte)t1_getbyte());
551         if (!(c == 10 || c == 13)) {
552             if (last_hexbyte == 0)
553                 t1_puts("00");
554             else
555                 pdftex_fail("unexpected data after eexec");
556         }
557     }
558     t1_cs = false;
559     t1_in_eexec = 2;
560 }
561 
562 /* macros for various transforms; currently only slant and extend are used */
563 
564 #define do_xshift(x,a) {x[4]+=a;}
565 #define do_yshift(x,a) {x[5]+=a;}
566 #define do_xscale(x,a) {x[0]*=a; x[2]*=a; x[4]*=a;}
567 #define do_yscale(x,a) {x[1]*=a; x[3]*=a; x[5]*=a;}
568 #define do_extend(x,a) {do_xscale(x,a);}
569 #define do_scale(x,a)  {do_xscale(x,a); do_yscale(x,a);}
570 #define do_slant(x,a)  {x[0]+=x[1]*(a); x[2]+=x[3]*(a); x[4]+=x[5]*(a);}
571 #define do_shear(x,a)  {x[1]+=x[0]*(a); x[3]+=x[2]*(a); x[5]+=x[4]*(a);}
572 #define do_rotate(x,a)          \
573   {float t, u=cos(a), v=sin(a); \
574   t    =x[0]*u+x[1]*-v;         \
575   x[1] =x[0]*v+x[1]* u; x[0]=t; \
576   t    =x[2]*u+x[3]*-v;         \
577   x[3] =x[2]*v+x[3]* u; x[2]=t; \
578   t    =x[4]*u+x[5]*-v;         \
579   x[5] =x[4]*v+x[5]* u; x[4]=t;}
580 
t1_modify_fm(void)581 static void t1_modify_fm(void)
582 {
583     /*
584      * font matrix is given as six numbers a0..a5, which stands for the matrix
585      *
586      *           a0 a1 0
587      *     M =   a2 a3 0
588      *           a4 a5 1
589      *
590      * ExtendFont is given as
591      *
592      *           e 0 0
593      *     E =   0 1 0
594      *           0 0 1
595      *
596      * SlantFont is given as
597      *
598      *           1 0 0
599      *     S =   s 1 0
600      *           0 0 1
601      *
602      * The slant transform must be done _before_ the extend transform
603      * for compatibility!
604      */
605     float a[6];
606     int i, c;
607     char *p, *q, *r;
608     if ((p = strchr(t1_line_array, '[')) == 0)
609         if ((p = strchr(t1_line_array, '{')) == 0) {
610             remove_eol(p, t1_line_array);
611             pdftex_fail("FontMatrix: an array expected: `%s'", t1_line_array);
612         }
613     c = *p++;                   /* save the character '[' resp. '{' */
614     strncpy(t1_buf_array, t1_line_array, (size_t) (p - t1_line_array));
615     r = t1_buf_array + (p - t1_line_array);
616     for (i = 0; i < 6; i++) {
617         a[i] = t1_scan_num(p, &q);
618         p = q;
619     }
620     if (fm_slant(fd_cur->fm) != 0)
621         do_slant(a, fm_slant(fd_cur->fm) * 1E-3);
622     if (fm_extend(fd_cur->fm) != 0)
623         do_extend(a, fm_extend(fd_cur->fm) * 1E-3);
624     for (i = 0; i < 6; i++) {
625         sprintf(r, "%g ", a[i]);
626         r = strend(r);
627     }
628     if (c == '[') {
629         while (*p != ']' && *p != 0)
630             p++;
631     } else {
632         while (*p != '}' && *p != 0)
633             p++;
634     }
635     if (*p == 0) {
636         remove_eol(p, t1_line_array);
637         pdftex_fail
638             ("FontMatrix: cannot find the corresponding character to '%c': `%s'",
639              c, t1_line_array);
640     }
641     strcpy(r, p);
642     strcpy(t1_line_array, t1_buf_array);
643     t1_line_ptr = eol(t1_line_array);
644 }
645 
t1_modify_italic(void)646 static void t1_modify_italic(void)
647 {
648     float a;
649     char *p, *r;
650     if (fm_slant(fd_cur->fm) == 0)
651         return;
652     p = strchr(t1_line_array, ' ');
653     strncpy(t1_buf_array, t1_line_array, (size_t) (p - t1_line_array + 1));
654     a = t1_scan_num(p + 1, &r);
655     a -= atan(fm_slant(fd_cur->fm) * 1E-3) * (180 / M_PI);
656     sprintf(t1_buf_array + (p - t1_line_array + 1), "%g", a);
657     strcpy(strend(t1_buf_array), r);
658     strcpy(t1_line_array, t1_buf_array);
659     t1_line_ptr = eol(t1_line_array);
660     fd_cur->font_dim[ITALIC_ANGLE_CODE].val = round(a);
661     fd_cur->font_dim[ITALIC_ANGLE_CODE].set = true;
662 }
663 
t1_scan_keys(void)664 static void t1_scan_keys(void)
665 {
666     int i, k;
667     char *p, *q, *r;
668     const key_entry *key;
669     if (fm_extend(fd_cur->fm) != 0 || fm_slant(fd_cur->fm) != 0) {
670         if (t1_prefix("/FontMatrix")) {
671             t1_modify_fm();
672             return;
673         }
674         if (t1_prefix("/ItalicAngle")) {
675             t1_modify_italic();
676             return;
677         }
678     }
679     if (t1_prefix("/FontType")) {
680         p = t1_line_array + strlen("FontType") + 1;
681         if ((i = t1_scan_num(p, 0)) != 1)
682             pdftex_fail("Type%d fonts unsupported by pdfTeX", i);
683         return;
684     }
685     for (key = font_key; key - font_key < FONT_KEYS_NUM; key++) {
686         if (key->t1name[0] != '\0' &&
687             str_prefix(t1_line_array + 1, key->t1name))
688             break;
689     }
690     if (key - font_key == FONT_KEYS_NUM)
691         return;
692     p = t1_line_array + strlen(key->t1name) + 1;
693     skip(p, ' ');
694     if ((k = key - font_key) == FONTNAME_CODE) {
695         if (*p != '/') {
696             remove_eol(p, t1_line_array);
697             pdftex_fail("a name expected: `%s'", t1_line_array);
698         }
699         r = ++p;                /* skip the slash */
700         for (q = t1_buf_array; *p != ' ' && *p != 10; *q++ = *p++);
701         *q = 0;
702         if (fm_slant(fd_cur->fm) != 0) {
703             sprintf(q, "-Slant_%i", (int) fm_slant(fd_cur->fm));
704             q = strend(q);
705         }
706         if (fm_extend(fd_cur->fm) != 0) {
707             sprintf(q, "-Extend_%i", (int) fm_extend(fd_cur->fm));
708         }
709         xfree(fd_cur->fontname);
710         fd_cur->fontname = xstrdup(t1_buf_array);
711         /* at this moment we cannot call make_subset_tag() yet, as the encoding
712          * is not read; thus we mark the offset of the subset tag and write it
713          * later */
714         if (is_subsetted(fd_cur->fm)) {
715             assert(is_included(fd_cur->fm));
716             t1_fontname_offset = t1_offset() + (r - t1_line_array);
717             strcpy(t1_buf_array, p);
718             sprintf(r, "ABCDEF+%s%s", fd_cur->fontname, t1_buf_array);
719             t1_line_ptr = eol(r);
720         }
721         return;
722     }
723     if ((k == STEMV_CODE || k == FONTBBOX1_CODE)
724         && (*p == '[' || *p == '{'))
725         p++;
726     if (k == FONTBBOX1_CODE) {
727         for (i = 0; i < 4; i++, k++) {
728             fd_cur->font_dim[k].val = t1_scan_num(p, &r);
729             fd_cur->font_dim[k].set = true;
730             p = r;
731         }
732         return;
733     }
734     fd_cur->font_dim[k].val = t1_scan_num(p, 0);
735     fd_cur->font_dim[k].set = true;
736 }
737 
t1_scan_param(void)738 static void t1_scan_param(void)
739 {
740     static const char *lenIV = "/lenIV";
741     if (!t1_scan || *t1_line_array != '/')
742         return;
743     if (t1_prefix(lenIV)) {
744         t1_lenIV = t1_scan_num(t1_line_array + strlen(lenIV), 0);
745         if (t1_lenIV < 0)
746             pdftex_fail("negative value of lenIV is not supported");
747         return;
748     }
749     t1_scan_keys();
750 }
751 
copy_glyph_names(char ** glyph_names,int a,int b)752 static void copy_glyph_names(char **glyph_names, int a, int b)
753 {
754     if (glyph_names[b] != notdef) {
755         xfree(glyph_names[b]);
756         glyph_names[b] = notdef;
757     }
758     if (glyph_names[a] != notdef) {
759         glyph_names[b] = xstrdup(glyph_names[a]);
760     }
761 }
762 
763 /* read encoding from Type1 font file, return glyph_names array, or pdffail() */
764 
t1_builtin_enc(void)765 static char **t1_builtin_enc(void)
766 {
767     int i, a, b, c, counter = 0;
768     char *r, *p, **glyph_names;
769     /* At this moment "/Encoding" is the prefix of t1_line_array */
770     glyph_names = xtalloc(256, char *);
771     for (i = 0; i < 256; i++)
772         glyph_names[i] = notdef;
773     if (t1_suffix("def")) {     /* predefined encoding */
774         sscanf(t1_line_array + strlen("/Encoding"), "%256s", t1_buf_array);
775         if (strcmp(t1_buf_array, "StandardEncoding") == 0) {
776             t1_encoding = ENC_STANDARD;
777             for (i = 0; i < 256; i++) {
778                 if (standard_glyph_names[i] != notdef)
779                     glyph_names[i] = xstrdup(standard_glyph_names[i]);
780             }
781             return glyph_names;
782         }
783         pdftex_fail("cannot subset font (unknown predefined encoding `%s')",
784                     t1_buf_array);
785     }
786     /* At this moment "/Encoding" is the prefix of t1_line_array, and the encoding is
787      * not a predefined encoding.
788      *
789      * We have two possible forms of Encoding vector. The first case is
790      *
791      *     /Encoding [/a /b /c...] readonly def
792      *
793      * and the second case can look like
794      *
795      *     /Encoding 256 array 0 1 255 {1 index exch /.notdef put} for
796      *     dup 0 /x put
797      *     dup 1 /y put
798      *     ...
799      *     readonly def
800      */
801     t1_encoding = ENC_BUILTIN;
802     if (t1_prefix("/Encoding [") || t1_prefix("/Encoding[")) {  /* the first case */
803         r = strchr(t1_line_array, '[') + 1;
804         skip(r, ' ');
805         for (;;) {
806             while (*r == '/') {
807                 for (p = t1_buf_array, r++;
808                      *r != 32 && *r != 10 && *r != ']' && *r != '/';
809                      *p++ = *r++);
810                 *p = 0;
811                 skip(r, ' ');
812                 if (counter > 255)
813                     pdftex_fail("encoding vector contains more than 256 names");
814                 if (strcmp(t1_buf_array, notdef) != 0)
815                     glyph_names[counter] = xstrdup(t1_buf_array);
816                 counter++;
817             }
818             if (*r != 10 && *r != '%') {
819                 if (str_prefix(r, "] def") || str_prefix(r, "] readonly def"))
820                     break;
821                 else {
822                     remove_eol(r, t1_line_array);
823                     pdftex_fail
824        ("a name or `] def' or `] readonly def' expected: `%s'", t1_line_array);
825                 }
826             }
827             t1_getline();
828             r = t1_line_array;
829         }
830     } else {                    /* the second case */
831         p = strchr(t1_line_array, 10);
832         for (;;) {
833             if (*p == 10) {
834                 t1_getline();
835                 p = t1_line_array;
836             }
837             /*
838                check for `dup <index> <glyph> put'
839              */
840             if (sscanf(p, "dup %i%256s put", &i, t1_buf_array) == 2 &&
841                 *t1_buf_array == '/' && valid_code(i)) {
842                 if (strcmp(t1_buf_array + 1, notdef) != 0)
843                     glyph_names[i] = xstrdup(t1_buf_array + 1);
844                 p = strstr(p, " put") + strlen(" put");
845                 skip(p, ' ');
846             }
847             /*
848                check for `dup dup <to> exch <from> get put'
849              */
850             else if (sscanf(p, "dup dup %i exch %i get put", &b, &a) == 2
851                      && valid_code(a) && valid_code(b)) {
852                 copy_glyph_names(glyph_names, a, b);
853                 p = strstr(p, " get put") + strlen(" get put");
854                 skip(p, ' ');
855             }
856             /*
857                check for `dup dup <from> <size> getinterval <to> exch putinterval'
858              */
859             else if (sscanf(p, "dup dup %i %i getinterval %i exch putinterval",
860                             &a, &c, &b) == 3
861                      && valid_code(a) && valid_code(b) && valid_code(c)) {
862                 for (i = 0; i < c; i++)
863                     copy_glyph_names(glyph_names, a + i, b + i);
864                 p = strstr(p, " putinterval") + strlen(" putinterval");
865                 skip(p, ' ');
866             }
867             /*
868                check for `def' or `readonly def'
869              */
870             else if ((p == t1_line_array || (p > t1_line_array && p[-1] == ' '))
871                      && strcmp(p, "def\n") == 0)
872                 return glyph_names;
873             /*
874                skip an unrecognizable word
875              */
876             else {
877                 while (*p != ' ' && *p != 10)
878                     p++;
879                 skip(p, ' ');
880             }
881         }
882     }
883     return glyph_names;
884 }
885 
t1_check_end(void)886 static void t1_check_end(void)
887 {
888     if (t1_eof())
889         return;
890     t1_getline();
891     if (t1_prefix("{restore}"))
892         t1_putline();
893 }
894 
t1_open_fontfile(const char * open_name_prefix)895 static boolean t1_open_fontfile(const char *open_name_prefix)
896 {
897     ff_entry *ff;
898     ff = check_ff_exist(fd_cur->fm->ff_name, is_truetype(fd_cur->fm));
899     if (ff->ff_path != NULL) {
900         t1_file = xfopen(cur_file_name = ff->ff_path, FOPEN_RBIN_MODE);
901         recorder_record_input(ff->ff_path);
902     } else {
903         set_cur_file_name(fd_cur->fm->ff_name);
904         pdftex_fail("cannot open Type 1 font file for reading");
905     }
906     t1_init_params(open_name_prefix);
907     return true;                /* font file found */
908 }
909 
t1_include(void)910 static void t1_include(void)
911 {
912     do {
913         t1_getline();
914         t1_scan_param();
915         t1_putline();
916     } while (t1_in_eexec == 0);
917     t1_start_eexec();
918     do {
919         t1_getline();
920         t1_scan_param();
921         t1_putline();
922     } while (!(t1_charstrings() || t1_subrs()));
923     t1_cs = true;
924     do {
925         t1_getline();
926         t1_putline();
927     } while (!t1_end_eexec());
928     t1_stop_eexec();
929     if (fixedcontent) {         /* copy 512 zeros (not needed for PDF) */
930         do {
931             t1_getline();
932             t1_putline();
933         } while (!t1_cleartomark());
934         t1_check_end();         /* write "{restore}if" if found */
935     }
936     get_length3();
937 }
938 
939 #define check_subr(subr) \
940     if (subr >= subr_size || subr < 0) \
941         pdftex_fail("Subrs array: entry index out of range (%i)",  subr);
942 
check_cs_token_pair(void)943 static const char **check_cs_token_pair(void)
944 {
945     const char **p = (const char **) cs_token_pairs_list;
946     for (; p[0] != NULL; ++p)
947         if (t1_buf_prefix(p[0]) && t1_buf_suffix(p[1]))
948             return p;
949     return NULL;
950 }
951 
cs_store(boolean is_subr)952 static void cs_store(boolean is_subr)
953 {
954     char *p;
955     cs_entry *ptr;
956     int subr;
957     for (p = t1_line_array, t1_buf_ptr = t1_buf_array; *p != ' ';
958          *t1_buf_ptr++ = *p++);
959     *t1_buf_ptr = 0;
960     if (is_subr) {
961         subr = t1_scan_num(p + 1, 0);
962         check_subr(subr);
963         ptr = subr_tab + subr;
964     } else {
965         ptr = cs_ptr++;
966         if (cs_ptr - cs_tab > cs_size)
967             pdftex_fail
968                 ("CharStrings dict: more entries than dict size (%i)", cs_size);
969         if (strcmp(t1_buf_array + 1, notdef) == 0)      /* skip the slash */
970             ptr->name = notdef;
971         else
972             ptr->name = xstrdup(t1_buf_array + 1);
973     }
974     /* copy " RD " + cs data to t1_buf_array */
975     memcpy(t1_buf_array, t1_line_array + cs_start - 4,
976            (unsigned) (t1_cslen + 4));
977     /* copy the end of cs data to t1_buf_array */
978     for (p = t1_line_array + cs_start + t1_cslen,
979            t1_buf_ptr = t1_buf_array + t1_cslen + 4;
980          *p != 10; *t1_buf_ptr++ = *p++);
981     *t1_buf_ptr++ = 10;
982     if (is_subr && cs_token_pair == NULL)
983         cs_token_pair = check_cs_token_pair();
984     ptr->len = t1_buf_ptr - t1_buf_array;
985     ptr->cslen = t1_cslen;
986     ptr->data = xtalloc(ptr->len, byte);
987     memcpy(ptr->data, t1_buf_array, ptr->len);
988     ptr->valid = true;
989 }
990 
991 #define store_subr()     cs_store(true)
992 #define store_cs()       cs_store(false)
993 
994 #define CC_STACK_SIZE    24
995 
996 static integer cc_stack[CC_STACK_SIZE], *stack_ptr = cc_stack;
997 static cc_entry cc_tab[CS_MAX];
998 static boolean is_cc_init = false;
999 
1000 #define cc_pop(N)                   \
1001     if (stack_ptr - cc_stack < (N)) \
1002         stack_error(N);             \
1003     stack_ptr -= N
1004 
1005 #define stack_error(N) {            \
1006     pdftex_fail("CharString: invalid access (%i) to stack (%i entries)", \
1007                 (int) N, (int)(stack_ptr - cc_stack));                  \
1008     goto cs_error;                  \
1009 }
1010 
1011 /*
1012 static integer cc_get(integer index)
1013 {
1014     if (index <  0) {
1015         if (stack_ptr + index < cc_stack )
1016             stack_error(stack_ptr - cc_stack + index);
1017         return *(stack_ptr + index);
1018     }
1019     else {
1020         if (cc_stack  + index >= stack_ptr)
1021             stack_error(index);
1022         return cc_stack[index];
1023     }
1024 }
1025 */
1026 
1027 #define cc_get(N)   ((N) < 0 ? *(stack_ptr + (N)) : *(cc_stack + (N)))
1028 #define cc_push(V)  *stack_ptr++ = V
1029 #define cc_clear()  stack_ptr = cc_stack
1030 #define set_cc(N, B, A, C) \
1031     cc_tab[N].nargs = A;   \
1032     cc_tab[N].bottom = B;  \
1033     cc_tab[N].clear = C;   \
1034     cc_tab[N].valid = true
1035 
cc_init(void)1036 static void cc_init(void)
1037 {
1038     int i;
1039     if (is_cc_init)
1040         return;
1041     for (i = 0; i < CS_MAX; i++)
1042         cc_tab[i].valid = false;
1043     set_cc(CS_HSTEM, true, 2, true);
1044     set_cc(CS_VSTEM, true, 2, true);
1045     set_cc(CS_VMOVETO, true, 1, true);
1046     set_cc(CS_RLINETO, true, 2, true);
1047     set_cc(CS_HLINETO, true, 1, true);
1048     set_cc(CS_VLINETO, true, 1, true);
1049     set_cc(CS_RRCURVETO, true, 6, true);
1050     set_cc(CS_CLOSEPATH, false, 0, true);
1051     set_cc(CS_CALLSUBR, false, 1, false);
1052     set_cc(CS_RETURN, false, 0, false);
1053     /*
1054        set_cc(CS_ESCAPE, false, 0, false);
1055      */
1056     set_cc(CS_HSBW, true, 2, true);
1057     set_cc(CS_ENDCHAR, false, 0, true);
1058     set_cc(CS_RMOVETO, true, 2, true);
1059     set_cc(CS_HMOVETO, true, 1, true);
1060     set_cc(CS_VHCURVETO, true, 4, true);
1061     set_cc(CS_HVCURVETO, true, 4, true);
1062     set_cc(CS_DOTSECTION, false, 0, true);
1063     set_cc(CS_VSTEM3, true, 6, true);
1064     set_cc(CS_HSTEM3, true, 6, true);
1065     set_cc(CS_SEAC, true, 5, true);
1066     set_cc(CS_SBW, true, 4, true);
1067     set_cc(CS_DIV, false, 2, false);
1068     set_cc(CS_CALLOTHERSUBR, false, 0, false);
1069     set_cc(CS_POP, false, 0, false);
1070     set_cc(CS_SETCURRENTPOINT, true, 2, true);
1071     is_cc_init = true;
1072 }
1073 
1074 #define cs_getchar()     cdecrypt(*data++, &cr)
1075 
1076 #define mark_subr(n)     cs_mark(0, n)
1077 #define mark_cs(s)       cs_mark(s, 0)
1078 
1079 __attribute__ ((format(printf, 3, 4)))
cs_fail(const char * cs_name,int subr,const char * fmt,...)1080 static void cs_fail(const char *cs_name, int subr, const char *fmt, ...)
1081 {
1082     char buf[SMALL_BUF_SIZE];
1083     va_list args;
1084     va_start(args, fmt);
1085     vsprintf(buf, fmt, args);
1086     va_end(args);
1087     if (cs_name == NULL)
1088         pdftex_fail("Subr (%i): %s", (int) subr, buf);
1089     else
1090         pdftex_fail("CharString (/%s): %s", cs_name, buf);
1091 }
1092 
1093 /* fix a return-less subr by appending CS_RETURN */
append_cs_return(cs_entry * ptr)1094 static void append_cs_return(cs_entry *ptr)
1095 {
1096     unsigned short cr;
1097     int i;
1098     byte *p, *q, *data, *new_data;
1099     assert(ptr != NULL && ptr->valid && ptr->used);
1100 
1101     /* decrypt the cs data to t1_buf_array, append CS_RETURN */
1102     p = (byte *) t1_buf_array;
1103     data = ptr->data + 4;
1104     cr = 4330;
1105     for (i = 0; i < ptr->cslen; i++)
1106         *p++ = cs_getchar();
1107     *p = CS_RETURN;
1108 
1109     /* encrypt the new cs data to new_data */
1110     new_data = xtalloc(ptr->len + 1, byte);
1111     memcpy(new_data, ptr->data, 4);
1112     p = new_data + 4;
1113     q = (byte *) t1_buf_array;
1114     cr = 4330;
1115     for (i = 0; i < ptr->cslen + 1; i++)
1116         *p++ = cencrypt(*q++, &cr);
1117     memcpy(p, ptr->data + 4 + ptr->cslen, ptr->len - ptr->cslen - 4);
1118 
1119     /* update *ptr */
1120     xfree(ptr->data);
1121     ptr->data = new_data;
1122     ptr->len++;
1123     ptr->cslen++;
1124 }
1125 
cs_mark(const char * cs_name,int subr)1126 static void cs_mark(const char *cs_name, int subr)
1127 {
1128     byte *data;
1129     int i, b, cs_len;
1130     int last_cmd = 0;
1131     integer a, a1, a2;
1132     unsigned short cr;
1133     static integer lastargOtherSubr3 = 3;       /* the argument of last call to
1134                                                    OtherSubrs[3] */
1135     cs_entry *ptr;
1136     cc_entry *cc;
1137     if (cs_name == NULL) {
1138         check_subr(subr);
1139         ptr = subr_tab + subr;
1140         if (!ptr->valid)
1141             return;
1142     } else {
1143         if (cs_notdef != NULL &&
1144             (cs_name == notdef || strcmp(cs_name, notdef) == 0))
1145             ptr = cs_notdef;
1146         else {
1147             for (ptr = cs_tab; ptr < cs_ptr; ptr++)
1148                 if (strcmp(ptr->name, cs_name) == 0)
1149                     break;
1150             if (ptr == cs_ptr) {
1151                 pdftex_warn("glyph `%s' undefined", cs_name);
1152                 return;
1153             }
1154             if (ptr->name == notdef)
1155                 cs_notdef = ptr;
1156         }
1157     }
1158     /* only marked CharString entries and invalid entries can be skipped;
1159        valid marked subrs must be parsed to keep the stack in sync */
1160     if (!ptr->valid || (ptr->used && cs_name != NULL))
1161         return;
1162     ptr->used = true;
1163     cr = 4330;
1164     cs_len = ptr->cslen;
1165     data = ptr->data + 4;
1166     for (i = 0; i < t1_lenIV; i++, cs_len--)
1167         cs_getchar();
1168     while (cs_len > 0) {
1169         --cs_len;
1170         b = cs_getchar();
1171         if (b >= 32) {
1172             if (b <= 246)
1173                 a = b - 139;
1174             else if (b <= 250) {
1175                 --cs_len;
1176                 a = ((b - 247) << 8) + 108 + cs_getchar();
1177             } else if (b <= 254) {
1178                 --cs_len;
1179                 a = -((b - 251) << 8) - 108 - cs_getchar();
1180             } else {
1181                 cs_len -= 4;
1182                 a = (cs_getchar() & 0xff) << 24;
1183                 a |= (cs_getchar() & 0xff) << 16;
1184                 a |= (cs_getchar() & 0xff) << 8;
1185                 a |= (cs_getchar() & 0xff) << 0;
1186                 if (sizeof(integer) > 4 && (a & 0x80000000))
1187                     a |= ~0x7FFFFFFF;
1188             }
1189             cc_push(a);
1190         } else {
1191             if (b == CS_ESCAPE) {
1192                 b = cs_getchar() + CS_1BYTE_MAX;
1193                 cs_len--;
1194             }
1195             if (b >= CS_MAX) {
1196                 cs_fail(cs_name, subr, "command value out of range: %i",
1197                         (int) b);
1198                 goto cs_error;
1199             }
1200             cc = cc_tab + b;
1201             if (!cc->valid) {
1202                 cs_fail(cs_name, subr, "command not valid: %i", (int) b);
1203                 goto cs_error;
1204             }
1205             if (cc->bottom) {
1206                 if (stack_ptr - cc_stack < cc->nargs)
1207                     cs_fail(cs_name, subr,
1208                             "less arguments on stack (%i) than required (%i)",
1209                             (int) (stack_ptr - cc_stack), (int) cc->nargs);
1210                 else if (stack_ptr - cc_stack > cc->nargs)
1211                     cs_fail(cs_name, subr,
1212                             "more arguments on stack (%i) than required (%i)",
1213                             (int) (stack_ptr - cc_stack), (int) cc->nargs);
1214             }
1215             last_cmd = b;
1216             switch (cc - cc_tab) {
1217             case CS_CALLSUBR:
1218                 a1 = cc_get(-1);
1219                 cc_pop(1);
1220                 mark_subr(a1);
1221                 if (!subr_tab[a1].valid) {
1222                     cs_fail(cs_name, subr, "cannot call subr (%i)", (int) a1);
1223                     goto cs_error;
1224                 }
1225                 break;
1226             case CS_DIV:
1227                 cc_pop(2);
1228                 cc_push(0);
1229                 break;
1230             case CS_CALLOTHERSUBR:
1231                 if (cc_get(-1) == 3)
1232                     lastargOtherSubr3 = cc_get(-3);
1233                 a1 = cc_get(-2) + 2;
1234                 cc_pop(a1);
1235                 break;
1236             case CS_POP:
1237                 cc_push(lastargOtherSubr3);
1238                 /* the only case when we care about the value being pushed onto
1239                    stack is when POP follows CALLOTHERSUBR (changing hints by
1240                    OtherSubrs[3])
1241                  */
1242                 break;
1243             case CS_SEAC:
1244                 a1 = cc_get(3);
1245                 a2 = cc_get(4);
1246                 cc_clear();
1247                 mark_cs(standard_glyph_names[a1]);
1248                 mark_cs(standard_glyph_names[a2]);
1249                 break;
1250             default:
1251                 if (cc->clear)
1252                     cc_clear();
1253             }
1254         }
1255     }
1256     if (cs_name == NULL && last_cmd != CS_RETURN) {
1257         pdftex_warn("last command in subr `%i' is not a RETURN; "
1258                     "I will add it now but please consider fixing the font",
1259                     (int) subr);
1260         append_cs_return(ptr);
1261     }
1262     return;
1263   cs_error:                    /* an error occured during parsing */
1264     cc_clear();
1265     ptr->valid = false;
1266     ptr->used = false;
1267 }
1268 
1269 /**********************************************************************/
1270 /* AVL search tree for glyph code by glyph name */
1271 
comp_t1_glyphs(const void * pa,const void * pb,void * p)1272 static int comp_t1_glyphs(const void *pa, const void *pb, void *p)
1273 {
1274     return strcmp(*((const char * const *) pa), *((const char * const *) pb));
1275 }
1276 
create_t1_glyph_tree(char ** glyph_names)1277 static struct avl_table *create_t1_glyph_tree(char **glyph_names)
1278 {
1279     int i;
1280     void **aa;
1281     static struct avl_table *gl_tree;
1282     gl_tree = avl_create(comp_t1_glyphs, NULL, &avl_xallocator);
1283     assert(gl_tree != NULL);
1284     for (i = 0; i < 256; i++) {
1285         if (glyph_names[i] != notdef &&
1286             (char **) avl_find(gl_tree, &glyph_names[i]) == NULL) {
1287             /* no strdup here, just point to the glyph_names array members */
1288             aa = avl_probe(gl_tree, &glyph_names[i]);
1289             assert(aa != NULL);
1290         }
1291     }
1292     return gl_tree;
1293 }
1294 
destroy_t1_glyph_tree(struct avl_table * gl_tree)1295 static void destroy_t1_glyph_tree(struct avl_table *gl_tree)
1296 {
1297     assert(gl_tree != NULL);
1298     avl_destroy(gl_tree, NULL);
1299 }
1300 
1301 /**********************************************************************/
1302 
t1_subset_ascii_part(void)1303 static void t1_subset_ascii_part(void)
1304 {
1305     int j, *p;
1306     char *glyph, **gg, **glyph_names;
1307     struct avl_table *gl_tree;
1308     struct avl_traverser t;
1309     void **aa;
1310     assert(fd_cur != NULL);
1311     assert(fd_cur->gl_tree != NULL);
1312     t1_getline();
1313     while (!t1_prefix("/Encoding")) {
1314         t1_scan_param();
1315         if (!(t1_prefix("/UniqueID")
1316               && !strncmp(t1_line_array + strlen(t1_line_array) -4, "def", 3)))
1317             t1_putline();
1318         t1_getline();
1319     }
1320     glyph_names = t1_builtin_enc();
1321     fd_cur->builtin_glyph_names = glyph_names;
1322     if (is_subsetted(fd_cur->fm)) {
1323         assert(is_included(fd_cur->fm));
1324         if (fd_cur->tx_tree != NULL) {
1325             /* take over collected non-reencoded characters from TeX */
1326             avl_t_init(&t, fd_cur->tx_tree);
1327             for (p = (int *) avl_t_first(&t, fd_cur->tx_tree); p != NULL;
1328                  p = (int *) avl_t_next(&t)) {
1329                 if ((char *) avl_find(fd_cur->gl_tree, glyph_names[*p]) == NULL) {
1330                     glyph = xstrdup(glyph_names[*p]);
1331                     aa = avl_probe(fd_cur->gl_tree, glyph);
1332                     assert(aa != NULL);
1333                 }
1334             }
1335         }
1336         make_subset_tag(fd_cur);
1337         assert(t1_fontname_offset != 0);
1338         strncpy(fb_array + t1_fontname_offset, fd_cur->subset_tag, 6);
1339     }
1340     /* now really all glyphs needed from this font are in the fd_cur->gl_tree */
1341     if (t1_encoding == ENC_STANDARD)
1342         t1_puts("/Encoding StandardEncoding def\n");
1343     else {
1344         t1_puts
1345             ("/Encoding 256 array\n0 1 255 {1 index exch /.notdef put} for\n");
1346         gl_tree = create_t1_glyph_tree(glyph_names);
1347         avl_t_init(&t, fd_cur->gl_tree);
1348         j = 0;
1349         for (glyph = (char *) avl_t_first(&t, fd_cur->gl_tree); glyph != NULL;
1350              glyph = (char *) avl_t_next(&t)) {
1351             if ((gg = (char **) avl_find(gl_tree, &glyph)) != NULL) {
1352                 t1_printf("dup %i /%s put\n", (int) (gg - glyph_names), *gg);
1353                 j++;
1354             }
1355         }
1356         destroy_t1_glyph_tree(gl_tree);
1357         if (j == 0)
1358             /* We didn't mark anything for the Encoding array. */
1359             /* We add "dup 0 /.notdef put" for compatibility   */
1360             /* with Acrobat 5.0.                               */
1361             t1_puts("dup 0 /.notdef put\n");
1362         t1_puts("readonly def\n");
1363     }
1364     do {
1365         t1_getline();
1366         t1_scan_param();
1367         if (!t1_prefix("/UniqueID"))    /* ignore UniqueID for subsetted fonts */
1368             t1_putline();
1369     } while (t1_in_eexec == 0);
1370 }
1371 
cs_init(void)1372 static void cs_init(void)
1373 {
1374     cs_ptr = cs_tab = NULL;
1375     cs_dict_start = cs_dict_end = NULL;
1376     cs_count = cs_size = cs_size_pos = 0;
1377     cs_token_pair = NULL;
1378     subr_tab = NULL;
1379     subr_array_start = subr_array_end = NULL;
1380     subr_max = subr_size = subr_size_pos = 0;
1381 }
1382 
init_cs_entry(cs_entry * cs)1383 static void init_cs_entry(cs_entry *cs)
1384 {
1385     cs->data = NULL;
1386     cs->name = NULL;
1387     cs->len = 0;
1388     cs->cslen = 0;
1389     cs->used = false;
1390     cs->valid = false;
1391 }
1392 
t1_read_subrs(void)1393 static void t1_read_subrs(void)
1394 {
1395     int i, s;
1396     cs_entry *ptr;
1397     t1_getline();
1398     while (!(t1_charstrings() || t1_subrs())) {
1399         t1_scan_param();
1400         if (!t1_prefix("/UniqueID"))    /* ignore UniqueID for subsetted fonts */
1401             t1_putline();
1402         t1_getline();
1403     }
1404   found:
1405     t1_cs = true;
1406     t1_scan = false;
1407     if (!t1_subrs())
1408         return;
1409     subr_size_pos = strlen("/Subrs") + 1;
1410     /* subr_size_pos points to the number indicating dict size after "/Subrs" */
1411     subr_size = t1_scan_num(t1_line_array + subr_size_pos, 0);
1412     if (subr_size == 0) {
1413         while (!t1_charstrings())
1414             t1_getline();
1415         return;
1416     }
1417     subr_tab = xtalloc(subr_size, cs_entry);
1418     for (ptr = subr_tab; ptr - subr_tab < subr_size; ptr++)
1419         init_cs_entry(ptr);
1420     subr_array_start = xstrdup(t1_line_array);
1421     t1_getline();
1422     while (t1_cslen) {
1423         store_subr();
1424         t1_getline();
1425     }
1426     /* mark the first four entries without parsing */
1427     for (i = 0; i < subr_size && i < 4; i++)
1428         subr_tab[i].used = true;
1429     /* the end of the Subrs array might have more than one line so we need to
1430        concatnate them to subr_array_end. Unfortunately some fonts don't have
1431        the Subrs array followed by the CharStrings dict immediately (synthetic
1432        fonts). If we cannot find CharStrings in next POST_SUBRS_SCAN lines then
1433        we will treat the font as synthetic and ignore everything until next
1434        Subrs is found
1435      */
1436 
1437 #define POST_SUBRS_SCAN  5
1438 
1439     s = 0;
1440     *t1_buf_array = 0;
1441     for (i = 0; i < POST_SUBRS_SCAN; i++) {
1442         if (t1_charstrings())
1443             break;
1444         s += t1_line_ptr - t1_line_array;
1445         alloc_array(t1_buf, s, T1_BUF_SIZE);
1446         strcat(t1_buf_array, t1_line_array);
1447         t1_getline();
1448     }
1449     subr_array_end = xstrdup(t1_buf_array);
1450     if (i == POST_SUBRS_SCAN) { /* CharStrings not found;
1451                                    suppose synthetic font */
1452         for (ptr = subr_tab; ptr - subr_tab < subr_size; ptr++)
1453             if (ptr->valid)
1454                 xfree(ptr->data);
1455         xfree(subr_tab);
1456         xfree(subr_array_start);
1457         xfree(subr_array_end);
1458         cs_init();
1459         t1_cs = false;
1460         t1_synthetic = true;
1461         while (!(t1_charstrings() || t1_subrs()))
1462             t1_getline();
1463         goto found;
1464     }
1465 }
1466 
1467 #define t1_subr_flush()  t1_flush_cs(true)
1468 #define t1_cs_flush()    t1_flush_cs(false)
1469 
t1_flush_cs(boolean is_subr)1470 static void t1_flush_cs(boolean is_subr)
1471 {
1472     char *p;
1473     byte *r, *return_cs = NULL;
1474     cs_entry *tab, *end_tab, *ptr;
1475     char *start_line, *line_end;
1476     int count, size_pos;
1477     unsigned short cr, cs_len = 0;      /* to avoid warning about uninitialized use of cs_len */
1478     if (is_subr) {
1479         start_line = subr_array_start;
1480         line_end = subr_array_end;
1481         size_pos = subr_size_pos;
1482         tab = subr_tab;
1483         count = subr_max + 1;
1484         end_tab = subr_tab + count;
1485     } else {
1486         start_line = cs_dict_start;
1487         line_end = cs_dict_end;
1488         size_pos = cs_size_pos;
1489         tab = cs_tab;
1490         end_tab = cs_ptr;
1491         count = cs_count;
1492     }
1493     t1_line_ptr = t1_line_array;
1494     for (p = start_line; p - start_line < size_pos;)
1495         *t1_line_ptr++ = *p++;
1496     while (isdigit((unsigned char)*p))
1497         p++;
1498     sprintf(t1_line_ptr, "%u", count);
1499     strcat(t1_line_ptr, p);
1500     t1_line_ptr = eol(t1_line_array);
1501     t1_putline();
1502 
1503     /* create return_cs to replace unused subr's */
1504     if (is_subr) {
1505         cr = 4330;
1506         cs_len = 0;
1507         /* at this point we have t1_lenIV >= 0;
1508          * a negative value would be caught in t1_scan_param() */
1509         return_cs = xtalloc(t1_lenIV + 1, byte);
1510         for (cs_len = 0, r = return_cs; cs_len < t1_lenIV; cs_len++, r++)
1511             *r = cencrypt(0x00, &cr);
1512         *r = cencrypt(CS_RETURN, &cr);
1513         cs_len++;
1514     }
1515 
1516     for (ptr = tab; ptr < end_tab; ptr++) {
1517         if (ptr->used) {
1518             if (is_subr)
1519                 sprintf(t1_line_array, "dup %lu %u",
1520                         (unsigned long) (ptr - tab), ptr->cslen);
1521             else
1522                 sprintf(t1_line_array, "/%s %u", ptr->name, ptr->cslen);
1523             p = strend(t1_line_array);
1524             memcpy(p, ptr->data, ptr->len);
1525             t1_line_ptr = p + ptr->len;
1526             t1_putline();
1527         } else {
1528             /* replace unsused subr's by return_cs */
1529             if (is_subr) {
1530                 sprintf(t1_line_array, "dup %lu %u%s ",
1531                         (unsigned long) (ptr - tab), cs_len, cs_token_pair[0]);
1532                 p = strend(t1_line_array);
1533                 memcpy(p, return_cs, cs_len);
1534                 t1_line_ptr = p + cs_len;
1535                 t1_putline();
1536                 sprintf(t1_line_array, " %s", cs_token_pair[1]);
1537                 t1_line_ptr = eol(t1_line_array);
1538                 t1_putline();
1539             }
1540         }
1541         xfree(ptr->data);
1542         if (ptr->name != notdef)
1543             xfree(ptr->name);
1544     }
1545     sprintf(t1_line_array, "%s", line_end);
1546     t1_line_ptr = eol(t1_line_array);
1547     t1_putline();
1548     if (is_subr)
1549         xfree(return_cs);
1550     xfree(tab);
1551     xfree(start_line);
1552     xfree(line_end);
1553 }
1554 
t1_mark_glyphs(void)1555 static void t1_mark_glyphs(void)
1556 {
1557     char *glyph;
1558     struct avl_traverser t;
1559     cs_entry *ptr;
1560     if (t1_synthetic || fd_cur->all_glyphs) {   /* mark everything */
1561         if (cs_tab != NULL)
1562             for (ptr = cs_tab; ptr < cs_ptr; ptr++)
1563                 if (ptr->valid)
1564                     ptr->used = true;
1565         if (subr_tab != NULL) {
1566             for (ptr = subr_tab; ptr - subr_tab < subr_size; ptr++)
1567                 if (ptr->valid)
1568                     ptr->used = true;
1569             subr_max = subr_size - 1;
1570         }
1571         return;
1572     }
1573     mark_cs(notdef);
1574     avl_t_init(&t, fd_cur->gl_tree);
1575     for (glyph = (char *) avl_t_first(&t, fd_cur->gl_tree); glyph != NULL;
1576          glyph = (char *) avl_t_next(&t)) {
1577         mark_cs(glyph);
1578     }
1579     if (subr_tab != NULL)
1580         for (subr_max = -1, ptr = subr_tab; ptr - subr_tab < subr_size; ptr++)
1581             if (ptr->used && ptr - subr_tab > subr_max)
1582                 subr_max = ptr - subr_tab;
1583 }
1584 
t1_check_unusual_charstring(void)1585 static void t1_check_unusual_charstring(void)
1586 {
1587     char *p = strstr(t1_line_array, charstringname) + strlen(charstringname);
1588     int i;
1589     /* if no number follows "/CharStrings", let's read the next line */
1590     if (sscanf(p, "%i", &i) != 1) {
1591         /* pdftex_warn("no number found after `%s', I assume it's on the next line",
1592                     charstringname); */
1593         strcpy(t1_buf_array, t1_line_array);
1594 
1595         /* t1_getline always appends EOL to t1_line_array; let's change it to
1596          * space before appending the next line
1597          */
1598         *(strend(t1_buf_array) - 1) = ' ';
1599 
1600         t1_getline();
1601         strcat(t1_buf_array, t1_line_array);
1602         strcpy(t1_line_array, t1_buf_array);
1603         t1_line_ptr = eol(t1_line_array);
1604     }
1605 }
1606 
t1_subset_charstrings(void)1607 static void t1_subset_charstrings(void)
1608 {
1609     cs_entry *ptr;
1610 
1611     /* at this point t1_line_array contains "/CharStrings".
1612        when we hit a case like this:
1613          dup/CharStrings
1614          229 dict dup begin
1615        we read the next line and concatenate to t1_line_array before moving on
1616     */
1617     t1_check_unusual_charstring();
1618 
1619     cs_size_pos = strstr(t1_line_array, charstringname)
1620                   + strlen(charstringname) - t1_line_array + 1;
1621     /* cs_size_pos points to the number indicating
1622        dict size after "/CharStrings" */
1623     cs_size = t1_scan_num(t1_line_array + cs_size_pos, 0);
1624     cs_ptr = cs_tab = xtalloc(cs_size, cs_entry);
1625     for (ptr = cs_tab; ptr - cs_tab < cs_size; ptr++)
1626         init_cs_entry(ptr);
1627     cs_notdef = NULL;
1628     cs_dict_start = xstrdup(t1_line_array);
1629     t1_getline();
1630     while (t1_cslen) {
1631         store_cs();
1632         t1_getline();
1633     }
1634     cs_dict_end = xstrdup(t1_line_array);
1635     t1_mark_glyphs();
1636     if (subr_tab != NULL) {
1637         if (cs_token_pair == NULL)
1638             pdftex_fail
1639                 ("This Type 1 font uses mismatched subroutine begin/end token pairs.");
1640         t1_subr_flush();
1641     }
1642     for (cs_count = 0, ptr = cs_tab; ptr < cs_ptr; ptr++)
1643         if (ptr->used)
1644             cs_count++;
1645     t1_cs_flush();
1646 }
1647 
t1_subset_end(void)1648 static void t1_subset_end(void)
1649 {
1650     if (t1_synthetic) {         /* copy to "dup /FontName get exch definefont pop" */
1651         while (!strstr(t1_line_array, "definefont")) {
1652             t1_getline();
1653             t1_putline();
1654         }
1655         while (!t1_end_eexec())
1656             t1_getline();       /* ignore the rest */
1657         t1_putline();           /* write "mark currentfile closefile" */
1658     } else
1659         while (!t1_end_eexec()) {       /* copy to "mark currentfile closefile" */
1660             t1_getline();
1661             t1_putline();
1662         }
1663     t1_stop_eexec();
1664     if (fixedcontent) {         /* copy 512 zeros (not needed for PDF) */
1665         while (!t1_cleartomark()) {
1666             t1_getline();
1667             t1_putline();
1668         }
1669         if (!t1_synthetic)      /* don't check "{restore}if" for synthetic fonts */
1670             t1_check_end();     /* write "{restore}if" if found */
1671     }
1672     get_length3();
1673 }
1674 
writet1(fd_entry * fd)1675 void writet1(fd_entry *fd)
1676 {
1677     fd_cur = fd;                /* fd_cur is global inside writet1.c */
1678     assert(fd_cur->fm != NULL);
1679     assert(is_type1(fd->fm));
1680     assert(is_included(fd->fm));
1681 
1682     t1_save_offset = 0;
1683     if (!is_subsetted(fd_cur->fm)) {    /* include entire font */
1684         if (!(fd->ff_found = t1_open_fontfile("<<")))
1685             return;
1686         t1_include();
1687         t1_close_font_file(">>");
1688         return;
1689     }
1690     /* partial downloading */
1691     if (!(fd->ff_found = t1_open_fontfile("<")))
1692         return;
1693     t1_subset_ascii_part();
1694     t1_start_eexec();
1695     cc_init();
1696     cs_init();
1697     t1_read_subrs();
1698     t1_subset_charstrings();
1699     t1_subset_end();
1700     t1_close_font_file(">");
1701 }
1702 
t1_free(void)1703 void t1_free(void)
1704 {
1705     xfree(t1_line_array);
1706     xfree(t1_buf_array);
1707 }
1708