2 Copyright (c) 1996-2002 Han The Thanh, <thanh@pdftex.org>
4 This file is part of pdfTeX.
5 It was adapted for the use in PyX by André Wobst.
7 pdfTeX is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 pdfTeX is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with pdfTeX; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #include "pyxadapt.h" /* PyX */
24 #ifdef pdfTeX /* writet1 used with pdfTeX */
26 #define t1_log(s) tex_printf(s)
28 open_input(&t1_file, kpse_type1_format, FOPEN_RBIN_MODE)
30 open_input(&enc_file, kpse_tex_ps_header_format, FOPEN_RBIN_MODE)
31 #define external_enc() enc_tab[fm_cur->encoding].glyph_names
32 #define full_file_name() (char*)nameoffile + 1
33 #define get_length1() t1_length1 = t1_offset() - t1_save_offset
34 #define get_length2() t1_length2 = t1_offset() - t1_save_offset
35 #define get_length3() t1_length3 = t1_offset() - t1_save_offset
36 #define is_used_char(c) pdfcharmarked(tex_font, c)
37 #define t1_putchar ff_putchar
38 #define t1_offset ff_offset
39 #define out_eexec_char t1_putchar
40 #define save_offset() t1_save_offset = t1_offset()
41 #define end_last_eexec_line() \
42 t1_eexec_encrypt = false
43 #define update_builtin_enc(font, glyph_names) update_enc(font, glyph_names)
45 #define embed_all_glyphs(tex_font) fm_cur->all_glyphs
46 #define extra_charset() fm_cur->charset
47 integer t1_length1
, t1_length2
, t1_length3
;
48 static integer t1_save_offset
;
49 static integer t1_fontname_offset
;
51 #else /* writet1 used with dvips */
52 /* #include "ptexmac.h" PyX */
53 /* #include "dvips.h" PyX */
55 #define fm_extend(f) 0
59 #define is_reencoded(f) (cur_enc_name != 0)
61 #define is_subsetted(f) true
63 #define is_included(f) true
64 #undef set_cur_file_name
65 #define set_cur_file_name(s) cur_file_name = s
67 ((t1_file = search(headerpath, cur_file_name, FOPEN_RBIN_MODE)) != NULL)
69 ((enc_file = search(headerpath, cur_file_name, FOPEN_RBIN_MODE)) != NULL)
70 #define external_enc() ext_glyph_names
71 #define full_file_name() cur_file_name
75 #define is_used_char(c) (grid[c] == 1)
76 #define out_eexec_char t1_outhex
78 #define end_last_eexec_line() \
79 hexline_length = HEXLINE_WIDTH; \
81 t1_eexec_encrypt = false
83 #define t1_scan_only()
85 #define t1_putchar(c) fputc(c, bitfile)
86 #define t1_scan_keys()
87 #define update_builtin_enc(font, glyph_names)
88 #define embed_all_glyphs(tex_font) false
91 #define t1_char(c) T1Char(c)
92 #define pdfmovechars 1
93 #else /* SHIFTLOWCHARS */
95 #define pdfmovechars 0
96 #endif /* SHIFTLOWCHARS */
97 #define extra_charset() dvips_extra_charset
98 #define make_subset_tag(a, b)
99 static char *dvips_extra_charset
;
100 extern FILE *bitfile
;
101 /* extern FILE *search(); PyX */
102 static char *cur_file_name
;
103 static char *cur_enc_name
;
104 static unsigned char *grid
;
105 static char *ext_glyph_names
[MAX_CHAR_CODE
+ 1];
106 static char print_buf
[PRINTF_BUF_SIZE
];
107 static int hexline_length
;
108 static char notdef
[] = ".notdef";
111 /* #include <kpathsea/c-vararg.h> PyX */
112 /* #include <kpathsea/c-proto.h> PyX */
114 #define t1_getchar() getc(t1_file)
115 #define t1_ungetchar(c) ungetc(c, t1_file)
116 #define t1_eof() feof(t1_file)
117 #define t1_close() xfclose(t1_file, cur_file_name)
119 #define enc_getchar() getc(enc_file)
120 #define enc_eof() feof(enc_file)
121 #define enc_close() xfclose(enc_file, cur_file_name)
123 #define valid_code(c) (c >= 0 && c <= MAX_CHAR_CODE)
125 static const char *standard_glyph_names
[MAX_CHAR_CODE
+ 1] = {
126 notdef
, notdef
, notdef
, notdef
, notdef
, notdef
, notdef
, notdef
, notdef
,
127 notdef
, notdef
, notdef
, notdef
, notdef
, notdef
, notdef
, notdef
, notdef
,
128 notdef
, notdef
, notdef
, notdef
, notdef
, notdef
, notdef
, notdef
, notdef
,
129 notdef
, notdef
, notdef
, notdef
, notdef
, "space", "exclam", "quotedbl",
130 "numbersign", "dollar", "percent", "ampersand", "quoteright", "parenleft",
131 "parenright", "asterisk", "plus", "comma", "hyphen", "period", "slash",
132 "zero", "one", "two", "three", "four", "five", "six", "seven", "eight",
133 "nine", "colon", "semicolon", "less", "equal", "greater", "question", "at",
134 "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O",
135 "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "bracketleft",
136 "backslash", "bracketright", "asciicircum", "underscore", "quoteleft", "a",
137 "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p",
138 "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "braceleft", "bar",
139 "braceright", "asciitilde", notdef
, notdef
, notdef
, notdef
, notdef
, notdef
,
140 notdef
, notdef
, notdef
, notdef
, notdef
, notdef
, notdef
, notdef
, notdef
,
141 notdef
, notdef
, notdef
, notdef
, notdef
, notdef
, notdef
, notdef
, notdef
,
142 notdef
, notdef
, notdef
, notdef
, notdef
, notdef
, notdef
, notdef
, notdef
,
143 notdef
, "exclamdown", "cent", "sterling", "fraction", "yen", "florin",
144 "section", "currency", "quotesingle", "quotedblleft", "guillemotleft",
145 "guilsinglleft", "guilsinglright", "fi", "fl", notdef
, "endash", "dagger",
146 "daggerdbl", "periodcentered", notdef
, "paragraph", "bullet",
147 "quotesinglbase", "quotedblbase", "quotedblright", "guillemotright",
148 "ellipsis", "perthousand", notdef
, "questiondown", notdef
, "grave", "acute",
149 "circumflex", "tilde", "macron", "breve", "dotaccent", "dieresis", notdef
,
150 "ring", "cedilla", notdef
, "hungarumlaut", "ogonek", "caron", "emdash",
151 notdef
, notdef
, notdef
, notdef
, notdef
, notdef
, notdef
, notdef
, notdef
,
152 notdef
, notdef
, notdef
, notdef
, notdef
, notdef
, notdef
, "AE", notdef
,
153 "ordfeminine", notdef
, notdef
, notdef
, notdef
, "Lslash", "Oslash", "OE",
154 "ordmasculine", notdef
, notdef
, notdef
, notdef
, notdef
, "ae", notdef
, notdef
,
155 notdef
, "dotlessi", notdef
, notdef
, "lslash", "oslash", "oe", "germandbls",
156 notdef
, notdef
, notdef
, notdef
159 char **t1_glyph_names
;
160 char *t1_builtin_glyph_names
[MAX_CHAR_CODE
+ 1];
161 static boolean read_encoding_only
;
162 static int t1_encoding
;
165 typedef char *extra_glyphs_entry;
166 static char **extra_glyphs_ptr, **extra_glyphs_tab;
167 static int extra_glyphs_max;
170 #define T1_BUF_SIZE 0x4000
171 #define ENC_BUF_SIZE 1024
173 #define ENC_STANDARD 0
174 #define ENC_BUILTIN 1
182 #define CS_RRCURVETO 8
183 #define CS_CLOSEPATH 9
184 #define CS_CALLSUBR 10
188 #define CS_ENDCHAR 14
189 #define CS_RMOVETO 21
190 #define CS_HMOVETO 22
191 #define CS_VHCURVETO 30
192 #define CS_HVCURVETO 31
193 #define CS_1BYTE_MAX (CS_HVCURVETO + 1)
195 #define CS_DOTSECTION CS_1BYTE_MAX + 0
196 #define CS_VSTEM3 CS_1BYTE_MAX + 1
197 #define CS_HSTEM3 CS_1BYTE_MAX + 2
198 #define CS_SEAC CS_1BYTE_MAX + 6
199 #define CS_SBW CS_1BYTE_MAX + 7
200 #define CS_DIV CS_1BYTE_MAX + 12
201 #define CS_CALLOTHERSUBR CS_1BYTE_MAX + 16
202 #define CS_POP CS_1BYTE_MAX + 17
203 #define CS_SETCURRENTPOINT CS_1BYTE_MAX + 33
204 #define CS_2BYTE_MAX (CS_SETCURRENTPOINT + 1)
205 #define CS_MAX CS_2BYTE_MAX
207 typedef unsigned char byte
;
210 byte nargs
; /* number of arguments */
211 boolean bottom
; /* take arguments from bottom of stack? */
212 boolean clear
; /* clear stack? */
214 } cc_entry
; /* CharString Command */
217 char *name
; /* glyph name (or notdef for Subrs entry) */
219 unsigned short len
; /* length of the whole string */
220 unsigned short cslen
; /* length of the encoded part of the string */
225 static unsigned short t1_dr
, t1_er
;
226 static unsigned short t1_c1
= 52845, t1_c2
= 22719;
227 static unsigned short t1_cslen
;
228 static short t1_lenIV
;
229 static char t1_line
[T1_BUF_SIZE
], t1_buf
[T1_BUF_SIZE
], *t1_line_ptr
;
230 static char enc_line
[ENC_BUF_SIZE
];
232 static char *cs_start
;
234 static cs_entry
*cs_tab
, *cs_ptr
, *cs_notdef
;
235 static char *cs_dict_start
, *cs_dict_end
;
236 static int cs_count
, cs_size
, cs_size_pos
;
238 static cs_entry
*subr_tab
;
239 static char *subr_array_start
, *subr_array_end
;
240 static int subr_max
, subr_size
, subr_size_pos
;
242 /* This array contains the begin/end tokens commonly used in the */
243 /* /Subrs array of a Type 1 font. */
244 static const char *cs_token_pairs
[4][2] = {
247 {"RD", "noaccess put"},
248 {"-|", "noaccess put"}
251 /* Which begin/end token set do we use for the font? */
252 static int cs_token_choice
= -1;
253 static boolean cs_tokens_found
= false;
255 static boolean t1_pfa
, t1_cs
, t1_scan
, t1_eexec_encrypt
, t1_synthetic
;
256 static int t1_in_eexec
; /* 0 before eexec-encrypted, 1 during, 2 after */
257 static long t1_block_length
;
258 static int last_hexbyte
;
259 static FILE *t1_file
;
260 static FILE *enc_file
;
262 #define str_prefix(s1, s2) (strncmp(s1, s2, strlen(s2)) == 0)
263 #define t1_prefix(s) str_prefix(t1_line, s)
264 #define t1_buf_prefix(s) str_prefix(t1_buf, s)
265 #define t1_charstrings() strstr(t1_line, "/CharStrings")
266 #define t1_subrs() t1_prefix("/Subrs")
267 #define t1_end_eexec() t1_suffix("mark currentfile closefile")
268 #define t1_cleartomark() t1_prefix("cleartomark")
271 static void pdftex_fail(char *fmt
,...)
275 fputs("\nError: module writet1", stderr
);
277 fprintf(stderr
, " (file %s)", cur_file_name
);
279 vsprintf(print_buf
, fmt
, args
);
280 fputs(print_buf
, stderr
);
281 fputs("\n ==> Fatal error occurred, the output PDF file is not finished!\n", stderr
);
286 static void pdftex_warn(char *fmt
,...)
290 fputs("\nWarning: module writet1 of dvips", stderr
);
292 fprintf(stderr
, " (file %s)", cur_file_name
);
294 vsprintf(print_buf
, fmt
, args
);
295 fputs(print_buf
, stderr
);
300 #define HEXLINE_WIDTH 64
302 static void end_hexline()
304 if (hexline_length
== HEXLINE_WIDTH
) {
305 fputs("\n", bitfile
);
310 static void t1_outhex(byte b
)
312 static char *hexdigits
= "0123456789ABCDEF";
313 t1_putchar(hexdigits
[b
/16]);
314 t1_putchar(hexdigits
[b
%16]);
321 static void enc_getline(void)
327 pdftex_fail("unexpected end of file");
331 append_char_to_buf(c
, p
, enc_line
, ENC_BUF_SIZE
);
333 append_eol(p
, enc_line
, ENC_BUF_SIZE
);
334 if (p
- enc_line
<= 2 || *enc_line
== '%')
338 void load_enc(char *enc_name
, char **glyph_names
)
340 char buf
[ENC_BUF_SIZE
], *p
, *r
;
342 set_cur_file_name(enc_name
);
344 pdftex_warn("cannot open encoding file for reading");
349 t1_log(cur_file_name
= full_file_name());
351 if (*enc_line
!= '/' || (r
= strchr(enc_line
, '[')) == NULL
) {
352 remove_eol(r
, enc_line
);
353 pdftex_fail("invalid encoding vector (a name or `[' missing): `%s'", enc_line
);
360 for (p
= buf
, r
++; *r
!= ' ' && *r
!= 10 && *r
!= ']' && *r
!= '/'; *p
++ = *r
++);
363 if (names_count
> MAX_CHAR_CODE
)
364 pdftex_fail("encoding vector contains more than %i names",
365 (int)(MAX_CHAR_CODE
+ 1));
366 if (strcmp(buf
, notdef
) != 0)
367 glyph_names
[names_count
] = xstrdup(buf
);
370 if (*r
!= 10 && *r
!= '%') {
371 if (strncmp(r
, "] def", strlen("] def")) == 0)
374 remove_eol(r
, enc_line
);
375 pdftex_fail("invalid encoding vector: a name or `] def' expected: `%s'", enc_line
);
387 static void t1_check_pfa(void)
389 int c
= t1_getchar();
397 static int t1_getbyte(void)
399 int c
= t1_getchar();
402 if (t1_block_length
== 0) {
404 pdftex_fail("invalid marker");
411 t1_block_length
= t1_getchar() & 0xff;
412 t1_block_length
|= (t1_getchar() & 0xff) << 8;
413 t1_block_length
|= (t1_getchar() & 0xff) << 16;
414 t1_block_length
|= (t1_getchar() & 0xff) << 24;
421 static int hexval(int c
)
423 if (c
>= 'A' && c
<= 'F')
425 else if (c
>= 'a' && c
<= 'f')
427 else if (c
>= '0' && c
<= '9')
433 static byte
edecrypt(byte cipher
)
437 while (cipher
== 10 || cipher
== 13)
438 cipher
= t1_getbyte();
439 last_hexbyte
= cipher
= (hexval(cipher
) << 4) + hexval(t1_getbyte());
441 plain
= (cipher
^(t1_dr
>> 8));
442 t1_dr
= (cipher
+ t1_dr
)*t1_c1
+ t1_c2
;
446 static byte
cdecrypt(byte cipher
, unsigned short *cr
)
448 byte plain
= (cipher
^(*cr
>> 8));
449 *cr
= (cipher
+ *cr
)*t1_c1
+ t1_c2
;
453 static byte
eencrypt(byte plain
)
455 byte cipher
= (plain
^(t1_er
>> 8));
456 t1_er
= (cipher
+ t1_er
)*t1_c1
+ t1_c2
;
460 static byte
cencrypt(byte plain
, unsigned short *cr
)
462 byte cipher
= (plain
^(*cr
>> 8));
463 *cr
= (cipher
+ *cr
)*t1_c1
+ t1_c2
;
467 static char *eol(char *s
)
470 if (p
- s
> 1 && p
[-1] != 10) {
477 static float t1_scan_num(char *p
, char **r
)
481 if (sscanf(p
, "%g", &f
) != 1) {
482 remove_eol(p
, t1_line
);
483 pdftex_fail("a number expected: `%s'", t1_line
);
486 for (; isdigit(*p
) || *p
== '.' ||
487 *p
== 'e' || *p
== 'E' || *p
== '+' || *p
== '-'; p
++);
493 static boolean
t1_suffix(const char *s
)
495 char *s1
= t1_line_ptr
- 1,
499 while (s1
>= t1_line
&& s2
>= s
) {
503 return s1
>= t1_line
- 1;
506 static boolean
t1_buf_suffix(const char *s
, char *r
)
512 while (s1
>= t1_buf
&& s2
>= s
) {
516 return s1
>= t1_buf
- 1;
519 static void t1_getline(void)
521 int c
, l
, eexec_scan
;
523 static char eexec_str
[] = "currentfile eexec";
524 static int eexec_len
= 17; /* strlen(eexec_str) */
527 pdftex_fail("unexpected end of file");
528 t1_line_ptr
= t1_line
;
535 if (t1_in_eexec
== 1)
537 append_char_to_buf(c
, t1_line_ptr
, t1_line
, T1_BUF_SIZE
);
538 if (t1_in_eexec
== 0 && eexec_scan
>= 0 && eexec_scan
< eexec_len
) {
539 if (t1_line
[eexec_scan
] == eexec_str
[eexec_scan
])
544 if (c
== 10 || (t1_pfa
&& eexec_scan
== eexec_len
&& c
== 32))
546 if (t1_cs
&& t1_cslen
== 0 && (t1_line_ptr
- t1_line
> 4) &&
547 (t1_suffix(" RD ") || t1_suffix(" -| "))) {
551 t1_cslen
= l
= t1_scan_num(p
+ 1, 0);
552 cs_start
= t1_line_ptr
;
553 check_buf(t1_line_ptr
- t1_line
+ l
, T1_BUF_SIZE
);
555 *t1_line_ptr
++ = edecrypt(t1_getbyte());
559 append_eol(t1_line_ptr
, t1_line
, T1_BUF_SIZE
);
560 if (t1_line_ptr
- t1_line
<= 1)
562 if (eexec_scan
== eexec_len
)
566 static void t1_putline(void)
569 if (t1_line_ptr
- t1_line
<= 1)
571 if (t1_eexec_encrypt
) {
572 while (p
< t1_line_ptr
)
573 out_eexec_char(eencrypt(*p
++));
576 while (p
< t1_line_ptr
)
580 static void t1_puts(const char *s
)
584 t1_line_ptr
= strend(t1_line
);
588 static void t1_printf(const char *fmt
,...)
592 vsprintf(t1_line
, fmt
, args
);
597 static void t1_init_params(const char *open_name_prefix
)
599 t1_log(open_name_prefix
);
600 t1_log(cur_file_name
);
607 t1_synthetic
= false;
608 t1_eexec_encrypt
= false;
613 static void t1_close_font_file(const char *close_name_suffix
)
615 t1_log(close_name_suffix
);
620 static void t1_check_block_len(boolean decrypt
)
623 if (t1_block_length
== 0)
629 if (!(l
== 0 && (c
== 10 || c
== 13))) {
630 pdftex_warn("%i bytes more than expected were ignored", l
+ 1);
636 static void t1_start_eexec(void)
639 if (is_included(fm_cur
)) {
644 t1_check_block_len(false);
645 for (t1_line_ptr
= t1_line
, i
= 0; i
< 4; i
++) {
646 edecrypt(t1_getbyte());
649 t1_eexec_encrypt
= true;
650 if (is_included(fm_cur
))
651 t1_putline(); /* to put the first four bytes */
654 static void t1_stop_eexec(void)
657 if (is_included(fm_cur
)) {
661 end_last_eexec_line();
663 t1_check_block_len(true);
665 c
= edecrypt(t1_getbyte());
666 if (!(c
== 10 || c
== 13)) {
667 if (last_hexbyte
== 0)
670 pdftex_warn("unexpected data after eexec");
678 static void t1_modify_fm(void)
681 * font matrix is given as six numbers a0..a5, which stands for the matrix
687 * ExtendFont is given as
693 * SlantFont is given as
699 * and the final transformation is
702 * F = E.S.M = s*e*a0+a2 s*e*a1+a3 0
705 float e
, s
, a
[6], b
[6];
708 if ((p
= strchr(t1_line
, '[')) == 0)
709 if ((p
= strchr(t1_line
, '{')) == 0) {
710 remove_eol(p
, t1_line
);
711 pdftex_fail("FontMatrix: an array expected: `%s'", t1_line
);
713 c
= *p
++; /* save the character '[' resp. '{' */
714 strncpy(t1_buf
, t1_line
, (unsigned)(p
- t1_line
));
715 r
= t1_buf
+ (p
- t1_line
);
716 for (i
= 0; i
< 6; i
++) {
717 a
[i
] = t1_scan_num(p
, &q
);
720 if (fm_extend(fm_cur
) != 0)
721 e
= fm_extend(fm_cur
)*1E-3;
724 s
= fm_slant(fm_cur
)*1E-3;
727 b
[2] = s
*e
*a
[0] + a
[2];
728 b
[3] = s
*e
*a
[1] + a
[3];
731 for (i
= 0; i
< 6; i
++) {
732 sprintf(r
, "%G ", b
[i
]);
736 while (*p
!= ']' && *p
!= 0)
740 while (*p
!= '}' && *p
!= 0)
744 remove_eol(p
, t1_line
);
745 pdftex_fail("FontMatrix: cannot find the corresponding character to '%c': `%s'", c
, t1_line
);
748 strcpy(t1_line
, t1_buf
);
749 t1_line_ptr
= eol(t1_line
);
752 static void t1_modify_italic(void)
756 if (fm_slant(fm_cur
) == 0)
758 p
= strchr(t1_line
, ' ');
759 strncpy(t1_buf
, t1_line
, (unsigned)(p
- t1_line
+ 1));
760 a
= t1_scan_num(p
+ 1, &r
);
761 a
-= atan(fm_slant(fm_cur
)*1E-3)*(180/M_PI
);
762 sprintf(t1_buf
+ (p
- t1_line
+ 1), "%.2g", a
);
763 strcpy(strend(t1_buf
), r
);
764 strcpy(t1_line
, t1_buf
);
765 t1_line_ptr
= eol(t1_line
);
766 font_keys
[ITALIC_ANGLE_CODE
].value
.num
= round(a
);
767 font_keys
[ITALIC_ANGLE_CODE
].valid
= true;
770 static void t1_scan_keys(void)
775 if (fm_extend(fm_cur
) != 0 || fm_slant(fm_cur
) != 0) {
776 if (strncmp(t1_line
+ 1, "FontMatrix", strlen("FontMatrix")) == 0) {
780 if (strncmp(t1_line
+ 1, "ItalicAngle", strlen("ItalicAngle")) == 0) {
785 for (key
= font_keys
; key
- font_keys
< MAX_KEY_CODE
; key
++)
786 if (strncmp(t1_line
+ 1, key
->t1name
, strlen(key
->t1name
)) == 0)
788 if (key
- font_keys
== MAX_KEY_CODE
)
791 p
= t1_line
+ strlen(key
->t1name
) + 1;
793 if ((k
= key
- font_keys
) == FONTNAME_CODE
) {
795 remove_eol(p
, t1_line
);
796 pdftex_fail("a name expected: `%s'", t1_line
);
798 r
= ++p
; /* skip the slash */
799 for (q
= t1_buf
; *p
!= ' ' && *p
!= 10; *q
++ = *p
++);
801 if (fm_extend(fm_cur
) != 0) {
802 sprintf(q
, "-Extend_%i", (int)fm_extend(fm_cur
));
804 if (fm_slant(fm_cur
) != 0) {
805 sprintf(q
, "-Slant_%i", (int)fm_slant(fm_cur
));
807 key
->value
.string
= xstrdup(t1_buf
);
808 if (is_included(fm_cur
) && is_subsetted(fm_cur
)) {
809 t1_fontname_offset
= ff_offset() + (r
- t1_line
);
811 sprintf(r
, "******+%s%s", key
->value
.string
, t1_buf
);
812 t1_line_ptr
= eol(r
);
816 if ((k
== STEMV_CODE
|| k
== FONTBBOX1_CODE
) &&
817 (*p
== '[' || *p
== '{'))
819 if (k
== FONTBBOX1_CODE
) {
820 for (i
= 0; i
< 4; i
++) {
821 key
[i
].value
.num
= t1_scan_num(p
, &r
);
826 key
->value
.num
= t1_scan_num(p
, 0);
831 static void t1_scan_param(void)
833 static const char *lenIV
= "/lenIV";
834 if (!t1_scan
|| *t1_line
!= '/')
836 if (t1_prefix(lenIV
)) {
837 t1_lenIV
= t1_scan_num(t1_line
+ strlen(lenIV
), 0);
843 static void copy_glyph_names(char **glyph_names
, int a
, int b
)
845 if (glyph_names
[b
] != notdef
) {
846 free(glyph_names
[b
]);
847 glyph_names
[b
] = xstrdup(notdef
);
849 if (glyph_names
[a
] != notdef
) {
850 glyph_names
[b
] = xstrdup(glyph_names
[a
]);
854 static void t1_builtin_enc(void)
856 int i
, a
, b
, c
, counter
= 0;
859 * At this moment "/Encoding" is the prefix of t1_line
861 if (t1_suffix("def")) { /* predefined encoding */
862 sscanf(t1_line
+ strlen("/Encoding"), "%256s", t1_buf
);
863 if (strcmp(t1_buf
, "StandardEncoding") == 0) {
864 for (i
= 0; i
<= MAX_CHAR_CODE
; i
++)
865 if (standard_glyph_names
[i
] == notdef
)
866 t1_builtin_glyph_names
[i
] = xstrdup(notdef
);
868 t1_builtin_glyph_names
[i
] = xstrdup(standard_glyph_names
[i
]);
869 t1_encoding
= ENC_STANDARD
;
872 pdftex_fail("cannot subset font (unknown predefined encoding `%s')",
876 t1_encoding
= ENC_BUILTIN
;
878 * At this moment "/Encoding" is the prefix of t1_line, and the encoding is
879 * not a predefined encoding
881 * We have two possible forms of Encoding vector. The first case is
883 * /Encoding [/a /b /c...] readonly def
885 * and the second case can look like
887 * /Encoding 256 array 0 1 255 {1 index exch /.notdef put} for
893 for (i
= 0; i
<= MAX_CHAR_CODE
; i
++)
894 t1_builtin_glyph_names
[i
] = xstrdup(notdef
);
895 if (t1_prefix("/Encoding [") || t1_prefix("/Encoding[")) { /* the first case */
896 r
= strchr(t1_line
, '[') + 1;
900 for (p
= t1_buf
, r
++;
901 *r
!= 32 && *r
!= 10 && *r
!= ']' && *r
!= '/';
905 if (counter
> MAX_CHAR_CODE
)
906 pdftex_fail("encoding vector contains more than %i names",
907 (int)(MAX_CHAR_CODE
+ 1));
908 if (strcmp(t1_buf
, notdef
) != 0)
909 t1_builtin_glyph_names
[counter
] = xstrdup(t1_buf
);
912 if (*r
!= 10 && *r
!= '%') {
913 if (str_prefix(r
, "] def") || str_prefix(r
, "] readonly def"))
916 remove_eol(r
, t1_line
);
917 pdftex_fail("a name or `] def' or `] readonly def' expected: `%s'",
925 else { /* the second case */
926 p
= strchr(t1_line
, 10);
933 check for `dup <index> <glyph> put'
935 if (sscanf(p
, "dup %i%256s put", &i
, t1_buf
) == 2 &&
936 *t1_buf
== '/' && valid_code(i
)) {
937 if (strcmp(t1_buf
+ 1, notdef
) != 0)
938 t1_builtin_glyph_names
[i
] = xstrdup(t1_buf
+ 1);
939 p
= strstr(p
, " put") + strlen(" put");
943 check for `dup dup <to> exch <from> get put'
945 else if (sscanf(p
, "dup dup %i exch %i get put", &b
, &a
) == 2 &&
946 valid_code(a
) && valid_code(b
)) {
947 copy_glyph_names(t1_builtin_glyph_names
, a
, b
);
948 p
= strstr(p
, " get put") + strlen(" get put");
952 check for `dup dup <from> <size> getinterval <to> exch putinterval'
954 else if (sscanf(p
, "dup dup %i %i getinterval %i exch putinterval",
956 valid_code(a
) && valid_code(b
) && valid_code(c
)) {
957 for (i
= 0; i
< c
; i
++)
958 copy_glyph_names(t1_builtin_glyph_names
, a
+ i
, b
+ i
);
959 p
= strstr(p
, " putinterval") + strlen(" putinterval");
963 check for `def' or `readonly def'
965 else if ((p
== t1_line
|| (p
> t1_line
&& p
[-1] == ' ')) &&
966 strcmp(p
, "def\n") == 0)
969 skip an unrecognizable word
972 while (*p
!= ' ' && *p
!= 10)
980 static void t1_check_end(void)
985 if (t1_prefix("{restore}"))
990 static boolean
t1_open_fontfile(const char *open_name_prefix
)
993 if (fm_cur
->expansion
!= 0) {
994 ex_ffname
= mk_exname(fm_cur
->ff_name
, fm_cur
->expansion
);
995 set_cur_file_name(ex_ffname
);
996 if (t1_open()) { /* found mm instance */
997 cur_file_name
= full_file_name();
1002 t1_file
= xfopen(cur_file_name
= fm_cur
->ff_name
, FOPEN_RBIN_MODE
);
1004 set_cur_file_name(fm_cur
->ff_name
);
1006 pdftex_warn("cannot open Type 1 font file for reading");
1009 fix_ffname(fm_cur
, cur_file_name
= full_file_name());
1011 if (fm_cur
->expansion
!= 0 && is_included(fm_cur
)) { /* use ExtendFont to simulate MM instance */
1012 if (fm_extend(fm_cur
) == 0)
1013 fm_extend(fm_cur
) = 1000;
1015 roundxnoverd(fm_extend(fm_cur
), 1000 + fm_cur
->expansion
, 1000);
1018 t1_init_params(open_name_prefix
);
1019 fontfile_found
= true;
1024 boolean
t1_read_enc(fm_entry
*fm
)
1026 read_encoding_only
= true;
1028 if (!t1_open_fontfile("{"))
1030 fix_ffname(fm_cur
, cur_file_name
= full_file_name());
1031 while (!t1_prefix("/Encoding"))
1034 t1_close_font_file("}");
1038 static void t1_scan_only(void)
1043 } while (t1_in_eexec
== 0);
1048 } while (!(t1_charstrings() || t1_subrs()));
1051 static void t1_include(void)
1058 } while (t1_in_eexec
== 0);
1064 } while (!(t1_charstrings() || t1_subrs()));
1069 } while (!t1_end_eexec());
1074 } while (!t1_cleartomark());
1075 t1_check_end(); /* write "{restore}if" if found */
1079 #else /* not pdfTeX */
1080 static boolean
t1_open_fontfile(char *open_name_prefix
)
1084 t1_init_params(open_name_prefix
);
1089 #define check_subr(subr) \
1090 if (subr >= subr_size || subr < 0) \
1091 pdftex_fail("Subrs array: entry index out of range (%i)", subr);
1093 static void cs_store(boolean is_subr
)
1098 for (p
= t1_line
, q
= t1_buf
; *p
!= ' '; *q
++ = *p
++);
1101 subr
= t1_scan_num(p
+ 1, 0);
1103 ptr
= subr_tab
+ subr
;
1107 if (cs_ptr
- cs_tab
> cs_size
)
1108 pdftex_fail("CharStrings dict: more entries than dict size (%i)", cs_size
);
1109 if (strcmp(t1_buf
+ 1, notdef
) == 0) /* skip the slash */
1110 ptr
->name
= xstrdup(notdef
);
1112 ptr
->name
= xstrdup(t1_buf
+ 1);
1114 /* copy " RD " + cs data to t1_buf */
1115 memcpy(t1_buf
, cs_start
- 4, (unsigned)(t1_cslen
+ 4));
1116 /* copy the end of cs data to t1_buf */
1117 for (p
= cs_start
+ t1_cslen
, q
= t1_buf
+ t1_cslen
+ 4; *p
!= 10; *q
++ = *p
++);
1119 /* get the begin/end token pairs. Modify this as necessary for other token pairs. */
1120 if (is_subr
&& !cs_tokens_found
) {
1121 if (t1_buf_prefix(" RD") && t1_buf_suffix("NP", q
))
1122 { cs_token_choice
= 0; cs_tokens_found
= true; }
1123 else if (t1_buf_prefix(" -|") && t1_buf_suffix("|", q
))
1124 { cs_token_choice
= 1; cs_tokens_found
= true; }
1125 else if (t1_buf_prefix(" RD") && t1_buf_suffix("noaccess put", q
))
1126 { cs_token_choice
= 2; cs_tokens_found
= true; }
1127 else if (t1_buf_prefix(" -|") && t1_buf_suffix("noaccess put", q
))
1128 { cs_token_choice
= 3; cs_tokens_found
= true; }
1130 ptr
->len
= q
- t1_buf
;
1131 ptr
->cslen
= t1_cslen
;
1132 ptr
->data
= xtalloc(ptr
->len
, byte
);
1133 memcpy(ptr
->data
, t1_buf
, ptr
->len
);
1137 #define store_subr() cs_store(true)
1138 #define store_cs() cs_store(false)
1140 #define CC_STACK_SIZE 24
1142 static integer cc_stack
[CC_STACK_SIZE
], *stack_ptr
= cc_stack
;
1143 static cc_entry cc_tab
[CS_MAX
];
1144 static boolean is_cc_init
= false;
1148 if (stack_ptr - cc_stack < (N)) \
1152 #define stack_error(N) { \
1153 pdftex_warn("CharString: invalid access (%i) to stack (%i entries)", \
1154 N, stack_ptr - cc_stack); \
1159 static integer cc_get(integer index)
1162 if (stack_ptr + index < cc_stack )
1163 stack_error(stack_ptr - cc_stack + index);
1164 return *(stack_ptr + index);
1167 if (cc_stack + index >= stack_ptr)
1169 return cc_stack[index];
1174 #define cc_get(N) ((N) < 0 ? *(stack_ptr + (N)) : *(cc_stack + (N)))
1176 #define cc_push(V) *stack_ptr++ = V
1177 #define cc_clear() stack_ptr = cc_stack
1179 #define set_cc(N, B, A, C) \
1180 cc_tab[N].nargs = A; \
1181 cc_tab[N].bottom = B; \
1182 cc_tab[N].clear = C; \
1183 cc_tab[N].valid = true
1185 static void cc_init(void)
1190 for (i
= 0; i
< CS_MAX
; i
++)
1191 cc_tab
[i
].valid
= false;
1192 set_cc(CS_HSTEM
, true, 2, true);
1193 set_cc(CS_VSTEM
, true, 2, true);
1194 set_cc(CS_VMOVETO
, true, 1, true);
1195 set_cc(CS_RLINETO
, true, 2, true);
1196 set_cc(CS_HLINETO
, true, 1, true);
1197 set_cc(CS_VLINETO
, true, 1, true);
1198 set_cc(CS_RRCURVETO
, true, 6, true);
1199 set_cc(CS_CLOSEPATH
, false, 0, true);
1200 set_cc(CS_CALLSUBR
, false, 1, false);
1201 set_cc(CS_RETURN
, false, 0, false);
1203 set_cc(CS_ESCAPE, false, 0, false);
1205 set_cc(CS_HSBW
, true, 2, true);
1206 set_cc(CS_ENDCHAR
, false, 0, true);
1207 set_cc(CS_RMOVETO
, true, 2, true);
1208 set_cc(CS_HMOVETO
, true, 1, true);
1209 set_cc(CS_VHCURVETO
, true, 4, true);
1210 set_cc(CS_HVCURVETO
, true, 4, true);
1211 set_cc(CS_DOTSECTION
, false, 0, true);
1212 set_cc(CS_VSTEM3
, true, 6, true);
1213 set_cc(CS_HSTEM3
, true, 6, true);
1214 set_cc(CS_SEAC
, true, 5, true);
1215 set_cc(CS_SBW
, true, 4, true);
1216 set_cc(CS_DIV
, false, 2, false);
1217 set_cc(CS_CALLOTHERSUBR
, false, 0, false);
1218 set_cc(CS_POP
, false, 0, false);
1219 set_cc(CS_SETCURRENTPOINT
, true, 2, true);
1223 #define cs_getchar() cdecrypt(*data++, &cr)
1225 #define mark_subr(n) cs_mark(0, n)
1226 #define mark_cs(s) cs_mark(s, 0)
1228 static void cs_warn(const char *cs_name
, int subr
, const char *fmt
,...)
1230 char buf
[SMALL_BUF_SIZE
];
1232 va_start(args
, fmt
);
1233 vsprintf(buf
, fmt
, args
);
1236 pdftex_warn("Subr (%i): %s", (int)subr
, buf
);
1238 pdftex_warn("CharString (/%s): %s", cs_name
, buf
);
1241 static void cs_mark(const char *cs_name
, int subr
)
1247 static integer lastargOtherSubr3
= 3; /* the argument of last call to
1253 ptr
= subr_tab
+ subr
;
1258 if (cs_notdef
!= 0 &&
1259 (cs_name
== notdef
|| strcmp(cs_name
, notdef
) == 0))
1262 for (ptr
= cs_tab
; ptr
< cs_ptr
; ptr
++)
1263 if (strcmp(ptr
->name
, cs_name
) == 0)
1265 if (ptr
== cs_ptr
) {
1266 pdftex_warn("glyph `%s' undefined", cs_name
);
1269 if (ptr
->name
== notdef
)
1273 /* only marked CharString entries and invalid entries can be skipped;
1274 valid marked subrs must be parsed to keep the stack */
1275 if (!ptr
->valid
|| (ptr
->used
&& cs_name
!= 0))
1279 cs_len
= ptr
->cslen
;
1280 data
= ptr
->data
+ 4;
1281 for (i
= 0; i
< t1_lenIV
; i
++, cs_len
--)
1283 while (cs_len
> 0) {
1289 else if (b
<= 250) {
1291 a
= ((b
- 247) << 8) + 108 + cs_getchar();
1293 else if (b
<= 254) {
1295 a
= -((b
- 251) << 8) - 108 - cs_getchar();
1299 a
= (cs_getchar() & 0xff) << 24;
1300 a
|= (cs_getchar() & 0xff) << 16;
1301 a
|= (cs_getchar() & 0xff) << 8;
1302 a
|= (cs_getchar() & 0xff) << 0;
1303 if (sizeof(integer
) > 4 && (a
& 0x80000000))
1309 if (b
== CS_ESCAPE
) {
1310 b
= cs_getchar() + CS_1BYTE_MAX
;
1314 cs_warn(cs_name
, subr
, "command value out of range: %i", (int)b
);
1319 cs_warn(cs_name
, subr
, "command not valid: %i", (int)b
);
1323 if (stack_ptr
- cc_stack
< cc
->nargs
)
1324 cs_warn(cs_name
, subr
,
1325 "less arguments on stack (%i) than required (%i)",
1326 (int)(stack_ptr
- cc_stack
), (int)cc
->nargs
);
1327 else if (stack_ptr
- cc_stack
> cc
->nargs
)
1328 cs_warn(cs_name
, subr
,
1329 "more arguments on stack (%i) than required (%i)",
1330 (int)(stack_ptr
- cc_stack
), (int)cc
->nargs
);
1332 switch (cc
- cc_tab
) {
1337 if (!subr_tab
[a1
].valid
) {
1338 cs_warn(cs_name
, subr
,
1339 "cannot call subr (%i)", (int)a1
);
1347 case CS_CALLOTHERSUBR
:
1348 if (cc_get(-1) == 3)
1349 lastargOtherSubr3
= cc_get(-3);
1350 a1
= cc_get(-2) + 2;
1354 cc_push(lastargOtherSubr3
);
1355 /* the only case when we care about the value being pushed onto
1356 stack is when POP follows CALLOTHERSUBR (changing hints by
1364 mark_cs(standard_glyph_names
[a1
]);
1365 mark_cs(standard_glyph_names
[a2
]);
1374 cs_error
: /* an error occured during parsing */
1380 static void t1_subset_ascii_part(void)
1385 while (!t1_prefix("/Encoding")) {
1391 if (is_reencoded(fm_cur
))
1392 t1_glyph_names
= external_enc();
1394 t1_glyph_names
= t1_builtin_glyph_names
;
1395 update_builtin_enc(tex_font
, t1_glyph_names
);
1397 if (is_included(fm_cur
) && is_subsetted(fm_cur
))
1398 make_subset_tag(fm_cur
, t1_fontname_offset
);
1399 if (pdfmovechars
== 0 && t1_encoding
== ENC_STANDARD
)
1400 t1_puts("/Encoding StandardEncoding def\n");
1402 t1_puts("/Encoding 256 array\n0 1 255 {1 index exch /.notdef put} for\n");
1403 for (i
= 0, j
= 0; i
<= MAX_CHAR_CODE
; i
++) {
1404 if (is_used_char(i
) && t1_glyph_names
[i
] != notdef
) {
1406 t1_printf("dup %i /%s put\n", (int)t1_char(i
), t1_glyph_names
[i
]);
1409 /* We didn't mark anything for the Encoding array. */
1410 /* We add "dup 0 /.notdef put" for compatibility */
1411 /* with Acrobat 5.0. */
1413 t1_puts("dup 0 /.notdef put\n");
1414 t1_puts("readonly def\n");
1420 } while (t1_in_eexec
== 0);
1423 #define t1_subr_flush() t1_flush_cs(true)
1424 #define t1_cs_flush() t1_flush_cs(false)
1426 static void t1_flush_cs(boolean
);
1428 static void cs_init(void)
1430 cs_ptr
= cs_tab
= 0;
1431 cs_dict_start
= cs_dict_end
= 0;
1432 cs_count
= cs_size
= cs_size_pos
= 0;
1434 subr_array_start
= subr_array_end
= 0;
1435 subr_max
= subr_size
= subr_size_pos
= 0;
1438 static void init_cs_entry(cs_entry
*cs
)
1448 static void t1_mark_glyphs(void);
1450 static void t1_read_subrs(void)
1456 while (!(t1_charstrings() || t1_subrs())) {
1466 subr_size_pos
= strlen("/Subrs") + 1;
1467 /* subr_size_pos points to the number indicating dict size after "/Subrs" */
1468 subr_size
= t1_scan_num(t1_line
+ subr_size_pos
, 0);
1469 if (subr_size
== 0) {
1470 while (!t1_charstrings())
1474 subr_tab
= xtalloc(subr_size
, cs_entry
);
1475 for (ptr
= subr_tab
; ptr
- subr_tab
< subr_size
; ptr
++)
1477 subr_array_start
= xstrdup(t1_line
);
1483 /* mark the first four entries without parsing */
1484 for (i
= 0; i
< subr_size
&& i
< 4; i
++)
1485 subr_tab
[i
].used
= true;
1486 /* the end of the Subrs array might have more than one line so we need to
1487 concatnate them to subr_array_end. Unfortunately some fonts don't have
1488 the Subrs array followed by the CharStrings dict immediately (synthetic
1489 fonts). If we cannot find CharStrings in next POST_SUBRS_SCAN lines then
1490 we will treat the font as synthetic and ignore everything until next
1493 #define POST_SUBRS_SCAN 5
1496 for (i
= 0; i
< POST_SUBRS_SCAN
; i
++) {
1497 if (t1_charstrings())
1499 check_buf((t1_line_ptr
- t1_line
) + (s
- t1_buf
), T1_BUF_SIZE
);
1500 strcat(t1_buf
, t1_line
);
1501 s
+= t1_line_ptr
- t1_line
;
1504 subr_array_end
= xstrdup(t1_buf
);
1505 if (i
== POST_SUBRS_SCAN
) { /* CharStrings not found;
1506 suppose synthetic font */
1507 for (ptr
= subr_tab
; ptr
- subr_tab
< subr_size
; ptr
++)
1511 xfree(subr_array_start
);
1512 xfree(subr_array_end
);
1515 t1_synthetic
= true;
1516 while (!(t1_charstrings() || t1_subrs()))
1522 static void t1_flush_cs(boolean is_subr
)
1525 byte
*r
, return_cs
[T1_BUF_SIZE
];
1526 cs_entry
*tab
, *end_tab
, *ptr
;
1527 char *start_line
, *line_end
;
1528 int count
, size_pos
;
1529 unsigned short cr
, cs_len
;
1531 start_line
= subr_array_start
;
1532 line_end
= subr_array_end
;
1533 size_pos
= subr_size_pos
;
1535 count
= subr_max
+ 1;
1536 end_tab
= subr_tab
+ count
;
1539 start_line
= cs_dict_start
;
1540 line_end
= cs_dict_end
;
1541 size_pos
= cs_size_pos
;
1546 t1_line_ptr
= t1_line
;
1547 for (p
= start_line
; p
- start_line
< size_pos
;)
1548 *t1_line_ptr
++ = *p
++;
1551 sprintf(t1_line_ptr
, "%u", count
);
1552 strcat(t1_line_ptr
, p
);
1553 t1_line_ptr
= eol(t1_line
);
1559 if (t1_lenIV
>= 0) {
1560 for (cs_len
= 0, r
= return_cs
; cs_len
< t1_lenIV
; cs_len
++, r
++)
1561 *r
= cencrypt(0x00, &cr
);
1562 *r
= cencrypt(CS_RETURN
, &cr
);
1565 *return_cs
= CS_RETURN
;
1570 for (ptr
= tab
; ptr
< end_tab
; ptr
++) {
1574 sprintf(t1_line
, "dup %u %u", ptr
- tab
, ptr
->cslen
);
1576 sprintf(t1_line
, "/%s %u", ptr
->name
, ptr
->cslen
);
1577 p
= strend(t1_line
);
1578 memcpy(p
, ptr
->data
, ptr
->len
);
1579 t1_line_ptr
= p
+ ptr
->len
;
1584 sprintf(t1_line
, "dup %u %u %s ", ptr
- tab
, cs_len
,
1585 cs_token_pairs
[cs_token_choice
][0]);
1586 p
= strend(t1_line
);
1587 memcpy(p
, return_cs
, cs_len
);
1588 t1_line_ptr
= p
+ cs_len
;
1590 sprintf(t1_line
, " %s", cs_token_pairs
[cs_token_choice
][1]);
1591 t1_line_ptr
= eol(t1_line
);
1596 if (ptr
->name
!= 0 && ptr
->name
!= notdef
)
1599 sprintf(t1_line
, "%s", line_end
);
1600 t1_line_ptr
= eol(t1_line
);
1603 cs_token_choice
= -1;
1604 cs_tokens_found
= false;
1611 static void t1_mark_glyphs(void)
1614 char *charset
= extra_charset();
1617 if (t1_synthetic
|| embed_all_glyphs(tex_font
)) { /* mark everything */
1619 for (ptr
= cs_tab
; ptr
< cs_ptr
; ptr
++)
1622 if (subr_tab
!= 0) {
1623 for (ptr
= subr_tab
; ptr
- subr_tab
< subr_size
; ptr
++)
1626 subr_max
= subr_size
- 1;
1631 for (i
= 0; i
<= MAX_CHAR_CODE
; i
++)
1632 if (is_used_char(i
)) {
1633 if (t1_glyph_names
[i
] == notdef
)
1634 pdftex_warn("character %i is mapped to %s", i
, notdef
);
1636 mark_cs(t1_glyph_names
[i
]);
1640 g
= s
= charset
+ 1; /* skip the first '/' */
1643 while (*s
!= '/' && s
< r
)
1645 *s
= 0; /* terminate g by rewriting '/' to 0 */
1651 for (subr_max
= -1, ptr
= subr_tab
; ptr
- subr_tab
< subr_size
; ptr
++)
1652 if (ptr
->used
&& ptr
- subr_tab
> subr_max
)
1653 subr_max
= ptr
- subr_tab
;
1656 static void t1_subset_charstrings(void)
1659 cs_size_pos
= strstr(t1_line
, "/CharStrings") + strlen("/CharStrings")
1661 /* cs_size_pos points to the number indicating
1662 dict size after "/CharStrings" */
1663 cs_size
= t1_scan_num(t1_line
+ cs_size_pos
, 0);
1664 cs_ptr
= cs_tab
= xtalloc(cs_size
, cs_entry
);
1665 for (ptr
= cs_tab
; ptr
- cs_tab
< cs_size
; ptr
++)
1668 cs_dict_start
= xstrdup(t1_line
);
1674 cs_dict_end
= xstrdup(t1_line
);
1676 if (subr_tab
!= 0) {
1677 if (cs_token_choice
== -1)
1678 pdftex_fail("This Type 1 font uses mismatched subroutine begin/end token pairs.");
1681 for (cs_count
= 0, ptr
= cs_tab
; ptr
< cs_ptr
; ptr
++)
1687 static void t1_subset_end(void)
1689 if (t1_synthetic
) { /* copy to "dup /FontName get exch definefont pop" */
1690 while (!strstr(t1_line
, "definefont")) {
1694 while (!t1_end_eexec())
1695 t1_getline(); /* ignore the rest */
1696 t1_putline(); /* write "mark currentfile closefile" */
1698 else while (!t1_end_eexec()) { /* copy to "mark currentfile closefile" */
1703 while (!t1_cleartomark()) {
1707 if (!t1_synthetic
) /* don't check "{restore}if" for synthetic fonts */
1708 t1_check_end(); /* write "{restore}if" if found */
1714 read_encoding_only
= false;
1716 if (strcasecmp(strend(fm_fontfile(fm_cur
)) - 4, ".otf") == 0) {
1717 if (!is_included(fm_cur
) || is_subsetted(fm_cur
))
1718 pdftex_fail("OTF fonts must be included entirely");
1724 if (!is_included(fm_cur
)) { /* scan parameters from font file */
1725 if (!t1_open_fontfile("{"))
1728 t1_close_font_file("}");
1731 if (!is_subsetted(fm_cur
)) { /* include entire font */
1732 if (!t1_open_fontfile("<<"))
1735 t1_close_font_file(">>");
1738 /* partial downloading */
1739 if (!t1_open_fontfile("<"))
1741 t1_subset_ascii_part();
1746 t1_subset_charstrings();
1748 t1_close_font_file(">");
1752 boolean
t1_subset(char *fontfile
, char *encfile
, unsigned char *g
)
1755 cur_enc_name
= encfile
;
1756 for (i
= 0; i
<= MAX_CHAR_CODE
; i
++)
1757 ext_glyph_names
[i
] = notdef
;
1758 if (cur_enc_name
!= 0)
1759 load_enc(cur_enc_name
, ext_glyph_names
);
1761 cur_file_name
= fontfile
;
1764 for (i
= 0; i
<= MAX_CHAR_CODE
; i
++)
1765 if (ext_glyph_names
[i
] != notdef
)
1766 free(ext_glyph_names
[i
]);
1767 return 1 ; /* note: there *is* no unsuccessful return */
1769 boolean
t1_subset_2(char *fontfile
, unsigned char *g
, char *extraGlyphs
)
1772 cur_enc_name
= 0; /* PyX */
1773 for (i
= 0; i
<= MAX_CHAR_CODE
; i
++)
1774 ext_glyph_names
[i
] = notdef
;
1776 cur_file_name
= fontfile
;
1778 dvips_extra_charset
= extraGlyphs
;
1780 for (i
= 0; i
<= MAX_CHAR_CODE
; i
++)
1781 if (ext_glyph_names
[i
] != notdef
)
1782 free(ext_glyph_names
[i
]);
1783 return 1 ; /* note: there *is* no unsuccessful return */
1785 #endif /* not pdfTeX */