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