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
/>.
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
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;
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;
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
84 static const char
*standard_glyph_names
[256] = {
86 notdef
, notdef
, notdef
, notdef
, notdef
, notdef
, notdef
, notdef
, notdef
,
87 notdef
, notdef
, notdef
, notdef
, notdef
, notdef
, notdef
,
89 notdef
, notdef
, notdef
, notdef
, notdef
, notdef
, notdef
, notdef
, notdef
,
90 notdef
, notdef
, notdef
, notdef
, notdef
, notdef
, notdef
,
92 "space", "exclam", "quotedbl", "numbersign", "dollar", "percent",
93 "ampersand", "quoteright", "parenleft", "parenright", "asterisk",
94 "plus", "comma", "hyphen", "period", "slash",
96 "zero", "one", "two", "three", "four", "five", "six", "seven", "eight",
97 "nine", "colon", "semicolon", "less", "equal", "greater", "question",
99 "at", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N",
102 "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "bracketleft",
103 "backslash", "bracketright", "asciicircum", "underscore",
105 "quoteleft", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l",
108 "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "braceleft", "bar",
109 "braceright", "asciitilde", notdef
,
111 notdef
, notdef
, notdef
, notdef
, notdef
, notdef
, notdef
, notdef
, notdef
,
112 notdef
, notdef
, notdef
, notdef
, notdef
, notdef
, notdef
,
114 notdef
, notdef
, notdef
, notdef
, notdef
, notdef
, notdef
, notdef
, notdef
,
115 notdef
, notdef
, notdef
, notdef
, notdef
, notdef
, notdef
,
117 notdef
, "exclamdown", "cent", "sterling", "fraction", "yen", "florin",
118 "section", "currency", "quotesingle", "quotedblleft", "guillemotleft",
119 "guilsinglleft", "guilsinglright", "fi", "fl",
121 notdef
, "endash", "dagger", "daggerdbl", "periodcentered", notdef
,
122 "paragraph", "bullet", "quotesinglbase", "quotedblbase",
123 "quotedblright", "guillemotright", "ellipsis", "perthousand", notdef
,
126 notdef
, "grave", "acute", "circumflex", "tilde", "macron", "breve",
127 "dotaccent", "dieresis", notdef
,
128 "ring", "cedilla", notdef
, "hungarumlaut", "ogonek", "caron",
130 "emdash", notdef
, notdef
, notdef
, notdef
, notdef
, notdef
, notdef
, notdef
,
131 notdef
, notdef
, notdef
, notdef
, notdef
, notdef
, notdef
,
133 notdef
, "AE", notdef
, "ordfeminine", notdef
, notdef
, notdef
, notdef
,
134 "Lslash", "Oslash", "OE", "ordmasculine", notdef
, notdef
, notdef
,
137 notdef
, "ae", notdef
, notdef
, notdef
, "dotlessi", notdef
, notdef
, "lslash",
138 "oslash", "oe", "germandbls", notdef
, notdef
, notdef
, notdef
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
158 #define CS_RRCURVETO
8
159 #define CS_CLOSEPATH
9
160 #define CS_CALLSUBR
10
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
184 typedef unsigned char byte
;
187 byte nargs
; /* number of arguments
*/
188 boolean bottom
; /* take arguments from bottom of stack?
*/
189 boolean clear
; /* clear stack?
*/
191 } cc_entry
; /* CharString Command
*/
194 char
*name
; /* glyph name
(or notdef for Subrs entry
) */
196 unsigned short len
; /* length of the whole string
*/
197 unsigned short cslen
; /* length of the encoded part of the string
*/
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
);
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] = {
235 {" RD", "noaccess put"},
236 {" -|", "noaccess put"},
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
;
251 static void enc_getline
(void
)
257 normal_error
("type 1","unexpected end of file");
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
== '
%'
)
269 @ read encoding from .enc file
, return |glyph_names array|
, or |pdffail
()|
271 char
**load_enc_file
(char
*enc_name
)
276 char buf
[ENC_BUF_SIZE
], *p
, *r
;
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
);
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
);
295 if
(!enc_open
(cur_file_name
)) {
296 formatted_error
("type 1","cannot open encoding file '%s' for reading", cur_file_name
);
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
);
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
);
316 *r
!= ' '
&& *r != 10 && *r != ']' && *r != '/'; *p++ = *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
);
325 if
(*r
!= 10 && *r != '%') {
326 if
(strncmp
(r
, "] def", strlen
("] def")) == 0)
329 remove_eol
(r
, enc_line
);
330 formatted_error
("type 1","invalid encoding vector: a name or '] def' expected: `%s'",enc_line
);
337 report_stop_file
(filetype_map
);
338 cur_file_name
= NULL;
345 static void free_glyph_names
(char
**glyph_names
)
348 assert
(glyph_names
!= NULL);
349 for
(i
= 0; i
< 256; i
++)
350 if
(glyph_names
[i
] != notdef
)
351 xfree
(glyph_names
[i
]);
356 static void t1_check_pfa
(void
)
358 const int c
= t1_getchar
();
359 t1_pfa
= (c
!= 128) ? true
: false
;
363 static int t1_getbyte
(void
)
365 int c
= t1_getchar
();
368 if
(t1_block_length
== 0) {
370 normal_error
("type 1","invalid marker");
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;
387 static int hexval
(int c
)
389 if
(c
>= 'A'
&& c <= 'F')
391 else if
(c
>= 'a'
&& c <= 'f')
393 else if
(c
>= '
0'
&& c <= '9')
399 static byte edecrypt
(byte cipher
)
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
);
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
);
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
);
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
);
434 static char
*eol
(char
*s
)
437 if
(p
- s
> 1 && p[-1] != 10) {
444 static float t1_scan_num
(char
*p
, char
**r
)
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
);
453 for
(; isdigit
((unsigned char
)*p
) ||
*p
== '.' ||
454 *p
== 'e' ||
*p
== 'E' ||
*p
== '
+' ||
*p
== '
-'
; p
++);
460 static boolean str_suffix
(const char
*begin_buf
, const char
*end_buf
,
463 const char
*s1
= end_buf
- 1, *s2
= strend
(s
) - 1;
466 while
(s1
>= begin_buf
&& s2 >= s) {
474 static void t1_getline
(void
)
476 int c
, l
, eexec_scan
;
478 static const char eexec_str
[] = "currentfile eexec";
479 static int eexec_len
= 17; /* |strlen
(eexec_str
)|
*/
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
);
491 if
(t1_in_eexec
== 1)
492 c
= edecrypt
((byte
) c
);
493 alloc_array
(t1_line
, 1, T1_BUF_SIZE
);
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
])
504 if
(c
== 10 || c
== 13
505 ||
(t1_pfa
&& eexec_scan == eexec_len && c == 32)) {
508 if
(t1_cs
&& t1_cslen == 0 && (t1_line_ptr - t1_line_array > 4) &&
509 (t1_suffix
(" RD ") || t1_suffix
(" -| "))) {
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
);
518 *t1_line_ptr
++ = (t1_line_entry
) edecrypt
((byte
) 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)
526 if
(eexec_scan
== eexec_len
)
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
);
535 static void t1_putline
(PDF pdf
)
537 char
*p
= t1_line_array
;
538 if
(t1_line_ptr
- t1_line_array
<= 1)
540 if
(t1_eexec_encrypt
) {
541 while
(p
< t1_line_ptr
)
542 t1_putchar
((eight_bits
) eencrypt
((byte
) * p
++));
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
);
556 __attribute__
((format
(printf
, 2, 3)))
557 static void t1_printf
(PDF pdf
, const char
*fmt
, ...
)
561 vsprintf
(t1_line_array
, fmt
, args
);
562 t1_puts
(pdf
, t1_line_array
);
567 static void t1_init_params
(int open_name_prefix
)
569 report_start_file
(open_name_prefix
,cur_file_name
);
576 t1_synthetic
= false
;
577 t1_eexec_encrypt
= false
;
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
)
591 if
(t1_block_length
== 0)
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);
603 static void t1_start_eexec
(PDF pdf
)
606 assert
(is_included
(fd_cur-
>fm
));
611 t1_check_block_len
(false
);
612 for
(t1_line_ptr
= t1_line_array
, i
= 0; i
< 4; i
++) {
613 edecrypt
((byte
) t1_getbyte
());
616 t1_eexec_encrypt
= true
;
617 t1_putline
(pdf
); /* to put the first four bytes
*/
620 static void t1_stop_eexec
(PDF pdf
)
623 assert
(is_included
(fd_cur-
>fm
));
626 t1_eexec_encrypt
= false
;
628 t1_check_block_len
(true
);
630 c
= edecrypt
((byte
) t1_getbyte
());
631 if
(!(c
== 10 || c
== 13)) {
632 if
(last_hexbyte
== 0)
635 normal_error
("type 1","unexpected data after eexec");
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
); \
657 x
[1] =x
[0]*v
+x
[1]* u
; x
[0]=t
; \
659 x
[3] =x
[2]*v
+x
[3]* u
; x
[2]=t
; \
661 x
[5] =x
[4]*v
+x
[5]* u
; x
[4]=t
;}
665 static void t1_scan_keys
(PDF pdf
)
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
);
676 for
(key
= (const key_entry
*) font_key
; key
- font_key
< FONT_KEYS_NUM
;
678 if
(key-
>t1name
[0] != '\
0'
679 && str_prefix(t1_line_array + 1, key->t1name))
682 if
(key
- font_key
== FONT_KEYS_NUM
)
684 p
= t1_line_array
+ strlen
(key-
>t1name
) + 1;
686 if
((k
= (int
) (key
- font_key
)) == FONTNAME_CODE
) {
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++);
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
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
);
708 if
((k
== STEMV_CODE || k
== FONTBBOX1_CODE
) && (*p == '[' || *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
;
718 fd_cur-
>font_dim
[k
].val
= (int
) t1_scan_num
(p
, 0);
719 fd_cur-
>font_dim
[k
].set
= true
;
723 static void t1_scan_param
(PDF pdf
)
725 static const char
*lenIV
= "/lenIV";
726 if
(!t1_scan ||
*t1_line_array
!= '
/'
)
728 if
(t1_prefix
(lenIV
)) {
729 t1_lenIV
= (short
) t1_scan_num
(t1_line_array
+ strlen
(lenIV
), 0);
731 normal_error
("type 1","negative value of lenIV is not supported");
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"), "%255s", 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
]);
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
781 \.
{/Encoding
256 array
0 1 255 {1 index exch
/.notdef put
} for
}
787 t1_encoding
= ENC_BUILTIN
;
788 if
(t1_prefix
("/Encoding [") || t1_prefix
("/Encoding[")) { /* the first case
*/
789 r
= strchr
(t1_line_array
, '
['
) + 1;
793 for
(p
= t1_buf_array
, r
++;
794 *r
!= 32 && *r != 10 && *r != ']' && *r != '/';
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
);
804 if
(*r
!= 10 && *r != '%') {
805 if
(str_prefix
(r
, "] def") || str_prefix
(r
, "] readonly def"))
808 remove_eol
(r
, t1_line_array
);
809 formatted_error
("type 1","a name or '] def' or '] readonly def' expected: '%s'", t1_line_array
);
815 } else
{ /* the second case
*/
816 p
= strchr
(t1_line_array
, 10);
823 check for \.
{dup
<index
> <glyph
> put
}
825 if
(sscanf
(p
, "dup %i%255s 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");
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");
842 check for \.
{dup dup
<from
> <size
> getinterval
<to
> exch putinterval
}
845 (p
, "dup dup %i %i getinterval %i exch putinterval",
846 &a, &c, &b) == 3 && valid_code(a) && valid_code(b)
848 for
(i
= 0; i
< c
; i
++)
849 copy_glyph_names
(glyph_names
, a
+ i
, b
+ i
);
850 p
= strstr
(p
, " putinterval") + strlen
(" putinterval");
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)
860 skip an unrecognizable word
863 while
(*p
!= ' '
&& *p != 10)
875 static void t1_check_end
(PDF pdf
)
880 if
(t1_prefix
("{restore}"))
886 static boolean t1_open_fontfile
(int open_name_prefix
)
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
);
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
);
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
);
911 t1_file
= xfopen
(cur_file_name
, FOPEN_RBIN_MODE
);
915 recorder_record_input
(cur_file_name
);
916 t1_init_params
(open_name_prefix
);
920 static void t1_include
(PDF pdf
)
927 while
(t1_in_eexec
== 0);
934 while
(!(t1_charstrings
() || t1_subrs
()));
940 while
(!t1_end_eexec
());
942 if
(fixedcontent
) { /* copy
512 zeros
(not needed for PDF
) */
947 while
(!t1_cleartomark
());
948 t1_check_end
(pdf
); /* write
"{restore}if" if found
*/
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]))
968 static void cs_store
(boolean is_subr
)
973 for
(p
= t1_line_array
, t1_buf_ptr
= t1_buf_array
; *p
!= ' '
;
974 *t1_buf_ptr
++ = *p
++);
977 subr
= (int
) t1_scan_num
(p
+ 1, 0);
979 ptr
= subr_tab
+ subr
;
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
;
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
++);
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
);
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
;
1018 if
(stack_ptr
- cc_stack
< (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
)); \
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
)
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
);
1056 set_cc
(CS_ESCAPE
, false
, 0, false
);
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
);
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
];
1087 va_start
(args
, fmt
);
1088 vsprintf
(buf
, fmt
, args
);
1090 if
(cs_name
== NULL)
1091 formatted_error
("type 1","Subr '%i': %s", (int
) subr
, buf
);
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
)
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;
1109 for
(i
= 0; i
< ptr-
>cslen
; i
++)
1110 *p
++ = cs_getchar
();
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);
1117 q
= (byte
*) t1_buf_array
;
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));
1125 ptr-
>data
= new_data
;
1132 static void cs_mark
(const char
*cs_name
, int subr
)
1139 static int lastargOtherSubr3
= 3; /* the argument of last call to
1143 if
(cs_name
== NULL) {
1145 ptr
= subr_tab
+ subr
;
1149 if
(cs_notdef
!= NULL &&
1150 (cs_name
== notdef || strcmp
(cs_name
, notdef
) == 0))
1153 for
(ptr
= cs_tab
; ptr
< cs_ptr
; ptr
++)
1154 if
(strcmp
(ptr-
>name
, cs_name
) == 0)
1156 if
(ptr
== cs_ptr
) {
1157 formatted_warning
("type 1","glyph '%s' undefined", cs_name
);
1160 if
(ptr-
>name
== notdef
)
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))
1170 cs_len
= ptr-
>cslen
;
1171 data
= ptr-
>data
+ 4;
1172 for
(i
= 0; i
< t1_lenIV
; i
++, cs_len--
)
1174 while
(cs_len
> 0) {
1180 else if
(b
<= 250) {
1182 a
= ((b
- 247) << 8) + 108 + cs_getchar
();
1183 } else if
(b
<= 254) {
1185 a
= -((b
- 251) << 8) - 108 - cs_getchar
();
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))
1197 if
(b
== CS_ESCAPE
) {
1198 b
= cs_getchar
() + CS_1BYTE_MAX
;
1202 cs_fail
(cs_name
, subr
, "command value out of range: %i", (int
) b
);
1207 cs_fail
(cs_name
, subr
, "command not valid: %i", (int
) b
);
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
);
1221 switch
(cc
- cc_tab
) {
1226 if
(!subr_tab
[a1
].valid
) {
1227 cs_fail
(cs_name
, subr
, "cannot call subr '%i'", (int
) a1
);
1235 case CS_CALLOTHERSUBR
:
1236 if
(cc_get
(-1) == 3)
1237 lastargOtherSubr3
= cc_get
(-3);
1238 a1
= cc_get
(-2) + 2;
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
1252 mark_cs
(standard_glyph_names
[a1
]);
1253 mark_cs
(standard_glyph_names
[a2
]);
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",
1265 append_cs_return
(ptr
);
1268 cs_error
: /* an error occured during parsing
*/
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
)
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]);
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
)
1311 char
*glyph
, **gg
, **glyph_names
;
1312 struct avl_table
*gl_tree
;
1313 struct avl_traverser t
;
1315 assert
(fd_cur
!= NULL);
1316 assert
(fd_cur-
>gl_tree
!= NULL);
1318 while
(!t1_prefix
("/Encoding")) {
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
);
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");
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);
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
),
1361 destroy_t1_glyph_tree
(gl_tree
);
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");
1371 if
(!t1_prefix
("/UniqueID")) /* ignore UniqueID for subsetted fonts
*/
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;
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
)
1403 static void t1_read_subrs
(PDF pdf
)
1408 while
(!(t1_charstrings
() || t1_subrs
())) {
1410 if
(!t1_prefix
("/UniqueID")) /* ignore UniqueID for subsetted fonts
*/
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
())
1427 subr_tab
= xtalloc
((unsigned
) subr_size
, cs_entry
);
1428 for
(ptr
= subr_tab
; ptr
- subr_tab
< subr_size
; ptr
++)
1430 subr_array_start
= xstrdup
(t1_line_array
);
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
1446 #define POST_SUBRS_SCAN
5
1449 for
(i
= 0; i
< POST_SUBRS_SCAN
; i
++) {
1450 if
(t1_charstrings
())
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
);
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
++)
1464 xfree
(subr_array_start
);
1465 xfree
(subr_array_end
);
1468 t1_synthetic
= true
;
1469 while
(!(t1_charstrings
() || t1_subrs
()))
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
)
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
;
1489 start_line
= subr_array_start
;
1490 line_end
= subr_array_end
;
1491 size_pos
= subr_size_pos
;
1493 count
= subr_max
+ 1;
1494 end_tab
= subr_tab
+ count
;
1496 start_line
= cs_dict_start
;
1497 line_end
= cs_dict_end
;
1498 size_pos
= cs_size_pos
;
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
))
1508 sprintf
(t1_line_ptr
, "%u", count
);
1509 strcat
(t1_line_ptr
, p
);
1510 t1_line_ptr
= eol
(t1_line_array
);
1513 cs_len
= 0; /* for
-Wall
*/
1514 /* create |return_cs| to replace unsused subr's
*/
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);
1527 for
(ptr
= tab
; ptr
< end_tab
; ptr
++) {
1530 sprintf
(t1_line_array
, "dup %li %u", (long int
) (ptr
- tab
),
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
;
1539 /* replace unsused subr's by |return_cs|
*/
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
;
1547 sprintf
(t1_line_array
, " %s", cs_token_pair
[1]);
1548 t1_line_ptr
= eol
(t1_line_array
);
1555 if
(ptr-
>name
!= notdef
)
1558 sprintf
(t1_line_array
, "%s", line_end
);
1559 t1_line_ptr
= eol
(t1_line_array
);
1562 end_tab
= subr_tab
+ subr_size
;
1563 for
(ptr
= tab
; ptr
< end_tab
; ptr
++) {
1566 if
(ptr-
>name
!= notdef
)
1579 static void t1_mark_glyphs
(void
)
1582 struct avl_traverser t
;
1584 if
(t1_synthetic || fd_cur-
>all_glyphs
) { /* mark everything
*/
1586 for
(ptr
= cs_tab
; ptr
< cs_ptr
; ptr
++)
1589 if
(subr_tab
!= NULL) {
1590 for
(ptr
= subr_tab
; ptr
- subr_tab
< subr_size
; ptr
++)
1593 subr_max
= subr_size
- 1;
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)) {
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
:
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
);
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
);
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
)
1638 t1_check_unusual_charstring
();
1640 cs_size_pos
= (int
) (strstr
(t1_line_array
,
1641 charstringname
) + strlen
(charstringname
) -
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
++)
1650 cs_dict_start
= xstrdup
(t1_line_array
);
1656 cs_dict_end
= xstrdup
(t1_line_array
);
1658 if
(subr_tab
!= NULL) {
1661 if
(cs_token_pair
== NULL)
1662 formatted_error
("type 1","mismatched subroutine begin/end token pairs");
1666 for
(cs_counter
= 0, ptr
= cs_tab
; ptr
< cs_ptr
; ptr
++)
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")) {
1681 while
(!t1_end_eexec
())
1682 t1_getline
(); /* ignore the rest
*/
1683 t1_putline
(pdf
); /* write \.
{mark currentfile closefile
} */
1685 while
(!t1_end_eexec
()) { /* copy to \.
{mark currentfile closefile
} */
1690 if
(fixedcontent
) { /* copy
512 zeros
(not needed for PDF
) */
1691 while
(!t1_cleartomark
()) {
1695 if
(!t1_synthetic
) /* don't check \.
{{restore
}if
} for synthetic fonts
*/
1696 t1_check_end
(pdf
); /* write \.
{{restore
}if
} if found
*/
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
));
1711 if
(!is_subsetted
(fd_cur-
>fm
)) { /* include entire font
*/
1712 if
(!(fd-
>ff_found
= t1_open_fontfile
(filetype_font
)))
1715 t1_close_font_file
(filetype_font
);
1719 /* partial downloading
*/
1720 if
(!(fd-
>ff_found
= t1_open_fontfile
(filetype_subset
)))
1722 t1_subset_ascii_part
(pdf
);
1723 t1_start_eexec
(pdf
);
1727 t1_subset_charstrings
(pdf
);
1729 t1_close_font_file
(filetype_subset
);
1737 xfree
(t1_line_array
);
1738 xfree
(t1_buf_array
);