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 */