~ubuntu-branches/ubuntu/trusty/pyx/trusty

« back to all changes in this revision

Viewing changes to pyx/t1strip/writet1.c

  • Committer: Bazaar Package Importer
  • Author(s): Graham Wilson
  • Date: 2004-12-25 06:42:57 UTC
  • Revision ID: james.westby@ubuntu.com-20041225064257-31469ij5uysqq302
Tags: upstream-0.7.1
Import upstream version 0.7.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
Copyright (c) 1996-2002 Han The Thanh, <thanh@pdftex.org>
 
3
 
 
4
This file is part of pdfTeX.
 
5
It was adapted for the use in PyX by Andr� Wobst.
 
6
 
 
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.
 
11
 
 
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.
 
16
 
 
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
 
20
 
 
21
*/
 
22
#include "pyxadapt.h"   /* PyX */
 
23
 
 
24
#ifdef pdfTeX /* writet1 used with pdfTeX */
 
25
#include "ptexlib.h"           
 
26
#define t1_log(s)           tex_printf(s)
 
27
#define t1_open()           \
 
28
    open_input(&t1_file, kpse_type1_format, FOPEN_RBIN_MODE)
 
29
#define enc_open()      \
 
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) 
 
44
#define t1_char(c)          c
 
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;
 
50
 
 
51
#else /* writet1 used with dvips */
 
52
/* #include "ptexmac.h"   PyX */
 
53
/* #include "dvips.h"   PyX */
 
54
#undef  fm_extend
 
55
#define fm_extend(f)        0
 
56
#undef  fm_slant
 
57
#define fm_slant(f)         0
 
58
#undef  is_reencoded
 
59
#define is_reencoded(f)     (cur_enc_name != 0)
 
60
#undef  is_subsetted
 
61
#define is_subsetted(f)     true
 
62
#undef  is_included
 
63
#define is_included(f)      true
 
64
#undef  set_cur_file_name
 
65
#define set_cur_file_name(s)    cur_file_name = s
 
66
#define t1_open()           \
 
67
    ((t1_file = search(headerpath, cur_file_name, FOPEN_RBIN_MODE)) != NULL)
 
68
#define enc_open()           \
 
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
 
72
#define get_length1()
 
73
#define get_length2()
 
74
#define get_length3()
 
75
#define is_used_char(c)     (grid[c] == 1)
 
76
#define out_eexec_char      t1_outhex
 
77
#define save_offset()
 
78
#define end_last_eexec_line()       \
 
79
    hexline_length = HEXLINE_WIDTH; \
 
80
    end_hexline();                  \
 
81
    t1_eexec_encrypt = false
 
82
#define t1_log(s)
 
83
#define t1_scan_only()
 
84
#define t1_include()
 
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
 
89
#undef pdfmovechars
 
90
#ifdef SHIFTLOWCHARS
 
91
#define t1_char(c)          T1Char(c)
 
92
#define pdfmovechars      1
 
93
#else /* SHIFTLOWCHARS */
 
94
#define t1_char(c)          c
 
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";
 
109
#endif /* pdfTeX */
 
110
 
 
111
/* #include <kpathsea/c-vararg.h>   PyX */
 
112
/* #include <kpathsea/c-proto.h>   PyX */
 
113
 
 
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)
 
118
 
 
119
#define enc_getchar()   getc(enc_file)
 
120
#define enc_eof()       feof(enc_file)
 
121
#define enc_close()     xfclose(enc_file, cur_file_name)
 
122
 
 
123
#define valid_code(c)   (c >= 0 && c <= MAX_CHAR_CODE)
 
124
 
 
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
 
157
};
 
158
 
 
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;
 
163
 
 
164
/*
 
165
typedef char *extra_glyphs_entry;
 
166
static char **extra_glyphs_ptr, **extra_glyphs_tab;
 
167
static int extra_glyphs_max;
 
168
*/
 
169
 
 
170
#define T1_BUF_SIZE   0x4000
 
171
#define ENC_BUF_SIZE  1024
 
172
 
 
173
#define ENC_STANDARD  0
 
174
#define ENC_BUILTIN   1
 
175
 
 
176
#define CS_HSTEM            1
 
177
#define CS_VSTEM            3
 
178
#define CS_VMOVETO          4
 
179
#define CS_RLINETO          5
 
180
#define CS_HLINETO          6
 
181
#define CS_VLINETO          7
 
182
#define CS_RRCURVETO        8
 
183
#define CS_CLOSEPATH        9
 
184
#define CS_CALLSUBR         10
 
185
#define CS_RETURN           11
 
186
#define CS_ESCAPE           12
 
187
#define CS_HSBW             13
 
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)
 
194
 
 
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
 
206
 
 
207
typedef unsigned char byte;
 
208
 
 
209
typedef struct {
 
210
    byte nargs;     /* number of arguments */
 
211
    boolean bottom; /* take arguments from bottom of stack? */
 
212
    boolean clear;  /* clear stack? */
 
213
    boolean valid;
 
214
} cc_entry; /* CharString Command */
 
215
 
 
216
typedef struct {
 
217
    char *name;             /* glyph name (or notdef for Subrs entry) */
 
218
    byte *data;
 
219
    unsigned short len;     /* length of the whole string */
 
220
    unsigned short cslen;   /* length of the encoded part of the string */
 
221
    boolean used;
 
222
    boolean valid;
 
223
} cs_entry;
 
224
 
 
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];
 
231
 
 
232
static char *cs_start;
 
233
 
 
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;
 
237
 
 
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;
 
241
 
 
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] = {
 
245
  {"RD", "NP"},
 
246
  {"-|", "|"},
 
247
  {"RD", "noaccess put"},
 
248
  {"-|", "noaccess put"}
 
249
};
 
250
 
 
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;
 
254
 
 
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;
 
261
 
 
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")
 
269
 
 
270
#ifndef pdfTeX
 
271
static void pdftex_fail(char *fmt,...)
 
272
{
 
273
    va_list args;
 
274
    va_start(args, fmt);
 
275
    fputs("\nError: module writet1", stderr);
 
276
    if (cur_file_name)
 
277
        fprintf(stderr, " (file %s)", cur_file_name);
 
278
    fputs(": ", stderr);
 
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);
 
282
    va_end(args);
 
283
    exit(-1);
 
284
}
 
285
 
 
286
static void pdftex_warn(char *fmt,...)
 
287
{
 
288
    va_list args;
 
289
    va_start(args, fmt);
 
290
    fputs("\nWarning: module writet1 of dvips", stderr);
 
291
    if (cur_file_name)
 
292
        fprintf(stderr, " (file %s)", cur_file_name);
 
293
    fputs(": ", stderr);
 
294
    vsprintf(print_buf, fmt, args);
 
295
    fputs(print_buf, stderr);
 
296
    fputs("\n", stderr);
 
297
    va_end(args);
 
298
}
 
299
 
 
300
#define HEXLINE_WIDTH 64
 
301
 
 
302
static void end_hexline()
 
303
{
 
304
    if (hexline_length == HEXLINE_WIDTH) {
 
305
        fputs("\n", bitfile);
 
306
        hexline_length = 0;
 
307
    }
 
308
}
 
309
 
 
310
static void t1_outhex(byte b)
 
311
{
 
312
    static char *hexdigits = "0123456789ABCDEF";
 
313
    t1_putchar(hexdigits[b/16]);
 
314
    t1_putchar(hexdigits[b%16]);
 
315
    hexline_length += 2;
 
316
    end_hexline();
 
317
}
 
318
#endif /* pdfTeX */
 
319
 
 
320
 
 
321
static void enc_getline(void)
 
322
{
 
323
    char *p;
 
324
    int c;
 
325
restart:
 
326
    if (enc_eof())
 
327
        pdftex_fail("unexpected end of file");
 
328
    p = enc_line;
 
329
    do {
 
330
        c = enc_getchar();
 
331
        append_char_to_buf(c, p, enc_line, ENC_BUF_SIZE);
 
332
    } while (c != 10);
 
333
    append_eol(p, enc_line, ENC_BUF_SIZE);
 
334
    if (p - enc_line <= 2 || *enc_line == '%')
 
335
        goto restart;
 
336
}
 
337
 
 
338
void load_enc(char *enc_name, char **glyph_names)
 
339
{
 
340
    char buf[ENC_BUF_SIZE], *p, *r;
 
341
    int names_count;
 
342
    set_cur_file_name(enc_name);
 
343
    if (!enc_open()) {
 
344
        pdftex_warn("cannot open encoding file for reading");
 
345
        cur_file_name = 0;
 
346
        return;
 
347
    }
 
348
    t1_log("{");
 
349
    t1_log(cur_file_name = full_file_name());
 
350
    enc_getline();
 
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);
 
354
    }
 
355
    names_count = 0;
 
356
    r++; /* skip '[' */
 
357
    skip(r, ' ');
 
358
    for (;;) {
 
359
        while (*r == '/') {
 
360
            for (p = buf, r++; *r != ' ' && *r != 10 && *r != ']' && *r != '/'; *p++ = *r++);
 
361
            *p = 0;
 
362
            skip(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);
 
368
            names_count++;
 
369
        }
 
370
        if (*r != 10 && *r != '%') {
 
371
            if (strncmp(r, "] def", strlen("] def")) == 0) 
 
372
                goto done;
 
373
            else {
 
374
                remove_eol(r, enc_line);
 
375
                pdftex_fail("invalid encoding vector: a name or `] def' expected: `%s'", enc_line);
 
376
            }
 
377
        }
 
378
        enc_getline();
 
379
        r = enc_line;
 
380
    }
 
381
done:
 
382
    enc_close();
 
383
    t1_log("}");
 
384
    cur_file_name = 0;
 
385
}
 
386
 
 
387
static void t1_check_pfa(void)
 
388
{
 
389
    int c = t1_getchar();
 
390
    if (c != 128)
 
391
        t1_pfa = true;
 
392
    else 
 
393
        t1_pfa = false;
 
394
    t1_ungetchar(c);
 
395
}
 
396
 
 
397
static int t1_getbyte(void)
 
398
{
 
399
    int c = t1_getchar();
 
400
    if (t1_pfa)
 
401
        return c;
 
402
    if (t1_block_length == 0) {
 
403
        if (c != 128)
 
404
            pdftex_fail("invalid marker");
 
405
        c = t1_getchar();
 
406
        if (c == 3) {
 
407
            while (!t1_eof())
 
408
                t1_getchar();
 
409
            return EOF;
 
410
        }
 
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;
 
415
        c = t1_getchar();
 
416
    }
 
417
    t1_block_length--;
 
418
    return c;
 
419
}
 
420
 
 
421
static int hexval(int c)
 
422
{
 
423
    if (c >= 'A' && c <= 'F')
 
424
        return c - 'A' + 10;
 
425
    else if (c >= 'a' && c <= 'f')
 
426
        return c - 'a' + 10;
 
427
    else if (c >= '0' && c <= '9')
 
428
        return c - '0';
 
429
    else
 
430
        return -1;
 
431
}
 
432
 
 
433
static byte edecrypt(byte cipher)
 
434
{
 
435
    byte plain;
 
436
    if (t1_pfa) {
 
437
        while (cipher == 10 || cipher == 13)
 
438
            cipher = t1_getbyte();
 
439
        last_hexbyte = cipher = (hexval(cipher) << 4) + hexval(t1_getbyte());
 
440
    }
 
441
    plain = (cipher^(t1_dr >> 8));
 
442
    t1_dr = (cipher + t1_dr)*t1_c1 + t1_c2;
 
443
    return plain;
 
444
}
 
445
 
 
446
static byte cdecrypt(byte cipher, unsigned short *cr)
 
447
{
 
448
    byte plain = (cipher^(*cr >> 8));
 
449
    *cr = (cipher + *cr)*t1_c1 + t1_c2;
 
450
    return plain;
 
451
}
 
452
 
 
453
static byte eencrypt(byte plain)
 
454
{
 
455
    byte cipher = (plain^(t1_er >> 8));
 
456
    t1_er = (cipher + t1_er)*t1_c1 + t1_c2;
 
457
    return cipher;
 
458
}
 
459
 
 
460
static byte cencrypt(byte plain, unsigned short *cr)
 
461
{
 
462
    byte cipher = (plain^(*cr >> 8));
 
463
    *cr = (cipher + *cr)*t1_c1 + t1_c2;
 
464
    return cipher;
 
465
}
 
466
 
 
467
static char *eol(char *s)
 
468
{
 
469
    char *p = strend(s);
 
470
    if (p - s > 1 && p[-1] != 10) {
 
471
        *p++ = 10;
 
472
        *p = 0;
 
473
    }
 
474
    return p;
 
475
}
 
476
 
 
477
static float t1_scan_num(char *p, char **r)
 
478
{
 
479
    float f;
 
480
    skip(p, ' ');
 
481
    if (sscanf(p, "%g", &f) != 1) {
 
482
        remove_eol(p, t1_line);
 
483
        pdftex_fail("a number expected: `%s'", t1_line);
 
484
    }
 
485
    if (r != 0) {
 
486
        for (; isdigit(*p) || *p == '.' || 
 
487
               *p == 'e' || *p == 'E' || *p == '+' || *p == '-'; p++);
 
488
        *r = p;
 
489
    }
 
490
    return f;
 
491
}
 
492
 
 
493
static boolean t1_suffix(const char *s) 
 
494
{
 
495
    char *s1 = t1_line_ptr - 1, 
 
496
         *s2 = strend(s) - 1;
 
497
    if (*s1 == 10)
 
498
        s1--;
 
499
    while (s1 >= t1_line && s2 >= s) {
 
500
        if (*s1-- != *s2--)
 
501
            return false;
 
502
    }
 
503
    return s1 >= t1_line - 1;
 
504
}
 
505
 
 
506
static boolean t1_buf_suffix(const char *s, char *r)
 
507
{
 
508
    char *s1 = r - 1,
 
509
         *s2 = strend(s) - 1;
 
510
    if (*s1 == 10)
 
511
        s1--;
 
512
    while (s1 >= t1_buf && s2 >= s) {
 
513
        if (*s1-- != *s2--)
 
514
            return false;
 
515
    }
 
516
    return s1 >= t1_buf - 1;
 
517
}
 
518
 
 
519
static void t1_getline(void) 
 
520
{
 
521
    int c, l, eexec_scan;
 
522
    char *p;
 
523
    static char eexec_str[] = "currentfile eexec";
 
524
    static int eexec_len = 17; /* strlen(eexec_str) */
 
525
restart:
 
526
    if (t1_eof())
 
527
        pdftex_fail("unexpected end of file");
 
528
    t1_line_ptr = t1_line;
 
529
    t1_cslen = 0;
 
530
    eexec_scan = 0;
 
531
    c = t1_getbyte();
 
532
    if (c == EOF)
 
533
        return;
 
534
    while (!t1_eof()) {
 
535
        if (t1_in_eexec == 1) 
 
536
            c = edecrypt(c);
 
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])
 
540
                eexec_scan++;
 
541
            else
 
542
                eexec_scan = -1;
 
543
        }
 
544
        if (c == 10 || (t1_pfa && eexec_scan == eexec_len && c == 32))
 
545
            break;
 
546
        if (t1_cs && t1_cslen == 0 && (t1_line_ptr - t1_line > 4) && 
 
547
           (t1_suffix(" RD ") || t1_suffix(" -| "))) {
 
548
            p = t1_line_ptr - 5;
 
549
            while (*p != ' ')
 
550
                p--;
 
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);
 
554
            while (l-- > 0)
 
555
                *t1_line_ptr++ = edecrypt(t1_getbyte());
 
556
        }
 
557
        c = t1_getbyte();
 
558
    }
 
559
    append_eol(t1_line_ptr, t1_line, T1_BUF_SIZE);
 
560
    if (t1_line_ptr - t1_line <= 1)
 
561
        goto restart;
 
562
    if (eexec_scan == eexec_len)
 
563
        t1_in_eexec = 1;
 
564
}
 
565
 
 
566
static void t1_putline(void) 
 
567
{
 
568
    char *p = t1_line;
 
569
    if (t1_line_ptr - t1_line <= 1)
 
570
        return;
 
571
    if (t1_eexec_encrypt)  {
 
572
        while (p < t1_line_ptr)
 
573
            out_eexec_char(eencrypt(*p++));
 
574
    }
 
575
    else 
 
576
        while (p < t1_line_ptr)
 
577
            t1_putchar(*p++);
 
578
}
 
579
 
 
580
static void t1_puts(const char *s)
 
581
{
 
582
    if (s != t1_line)
 
583
        strcpy(t1_line, s);
 
584
    t1_line_ptr = strend(t1_line);
 
585
    t1_putline();
 
586
}
 
587
 
 
588
static void t1_printf(const char *fmt,...)
 
589
{
 
590
    va_list args;
 
591
    va_start(args, fmt);
 
592
    vsprintf(t1_line, fmt, args);
 
593
    t1_puts(t1_line);                                    
 
594
    va_end(args);
 
595
}
 
596
 
 
597
static void t1_init_params(const char *open_name_prefix) 
 
598
{
 
599
    t1_log(open_name_prefix);
 
600
    t1_log(cur_file_name);
 
601
    t1_lenIV = 4;
 
602
    t1_dr = 55665;
 
603
    t1_er = 55665;
 
604
    t1_in_eexec = 0;
 
605
    t1_cs = false;
 
606
    t1_scan = true;
 
607
    t1_synthetic = false;
 
608
    t1_eexec_encrypt = false;
 
609
    t1_block_length = 0;
 
610
    t1_check_pfa();
 
611
}
 
612
 
 
613
static void t1_close_font_file(const char *close_name_suffix)
 
614
{
 
615
    t1_log(close_name_suffix);
 
616
    t1_close();
 
617
    cur_file_name = 0;
 
618
}
 
619
 
 
620
static void t1_check_block_len(boolean decrypt)
 
621
{
 
622
    int l, c;
 
623
    if (t1_block_length == 0)
 
624
       return;
 
625
    c = t1_getbyte();
 
626
    if (decrypt) 
 
627
        c = edecrypt(c);
 
628
    l = t1_block_length;
 
629
    if (!(l == 0 && (c == 10 || c == 13))) {
 
630
        pdftex_warn("%i bytes more than expected were ignored", l + 1);
 
631
        while (l-- > 0)
 
632
            t1_getbyte();
 
633
    }
 
634
}
 
635
 
 
636
static void t1_start_eexec(void)
 
637
{
 
638
    int i;
 
639
    if (is_included(fm_cur)) {
 
640
        get_length1();
 
641
        save_offset();
 
642
    }
 
643
    if (!t1_pfa)
 
644
        t1_check_block_len(false);
 
645
    for (t1_line_ptr = t1_line, i = 0; i < 4; i++) {
 
646
        edecrypt(t1_getbyte());
 
647
        *t1_line_ptr++ = 0;
 
648
    }
 
649
    t1_eexec_encrypt = true;
 
650
    if (is_included(fm_cur))
 
651
        t1_putline(); /* to put the first four bytes */
 
652
}
 
653
 
 
654
static void t1_stop_eexec(void)
 
655
{
 
656
    int c;
 
657
    if (is_included(fm_cur)) {
 
658
        get_length2();
 
659
        save_offset();
 
660
    }
 
661
    end_last_eexec_line();
 
662
    if (!t1_pfa)
 
663
        t1_check_block_len(true);
 
664
    else {
 
665
        c = edecrypt(t1_getbyte());
 
666
        if (!(c == 10 || c == 13)) {
 
667
            if (last_hexbyte == 0)
 
668
                t1_puts("00");
 
669
            else
 
670
                pdftex_warn("unexpected data after eexec");
 
671
        }
 
672
    }
 
673
    t1_cs = false;
 
674
    t1_in_eexec = 2;
 
675
}
 
676
 
 
677
#ifdef pdfTeX
 
678
static void t1_modify_fm(void)
 
679
{
 
680
 /*
 
681
  * font matrix is given as six numbers a0..a5, which stands for the matrix
 
682
  * 
 
683
  *           a0 a1 0
 
684
  *     M =   a2 a3 0
 
685
  *           a4 a5 1
 
686
  * 
 
687
  * ExtendFont is given as
 
688
  * 
 
689
  *           e 0 0
 
690
  *     E =   0 1 0
 
691
  *           0 0 1
 
692
  * 
 
693
  * SlantFont is given as
 
694
  * 
 
695
  *           1 0 0
 
696
  *     S =   s 1 0
 
697
  *           0 0 1
 
698
  * 
 
699
  * and the final transformation is
 
700
  * 
 
701
  *                    e*a0        e*a1       0
 
702
  *     F =  E.S.M  =  s*e*a0+a2   s*e*a1+a3  0
 
703
  *                    a4          a5         1
 
704
  */
 
705
    float e, s, a[6], b[6];
 
706
    int i, c;
 
707
    char *p, *q, *r;
 
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);
 
712
        }
 
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);
 
718
        p = q;
 
719
    }
 
720
    if (fm_extend(fm_cur) != 0)
 
721
        e = fm_extend(fm_cur)*1E-3;
 
722
    else
 
723
        e = 1;
 
724
    s = fm_slant(fm_cur)*1E-3;
 
725
    b[0] = e*a[0];
 
726
    b[1] = e*a[1];
 
727
    b[2] = s*e*a[0] + a[2];
 
728
    b[3] = s*e*a[1] + a[3];
 
729
    b[4] = a[4];
 
730
    b[5] = a[5];
 
731
    for (i = 0; i < 6; i++) {
 
732
        sprintf(r, "%G ", b[i]);
 
733
        r = strend(r);
 
734
    }
 
735
    if (c == '[') {
 
736
        while (*p != ']' && *p != 0)
 
737
            p++;
 
738
    }
 
739
    else {
 
740
        while (*p != '}' && *p != 0)
 
741
            p++;
 
742
    }
 
743
    if (*p == 0) {
 
744
        remove_eol(p, t1_line);
 
745
        pdftex_fail("FontMatrix: cannot find the corresponding character to '%c': `%s'",  c, t1_line);
 
746
    }
 
747
    strcpy(r, p);
 
748
    strcpy(t1_line, t1_buf);
 
749
    t1_line_ptr = eol(t1_line);
 
750
}
 
751
 
 
752
static void t1_modify_italic(void)
 
753
{
 
754
    float a;
 
755
    char *p, *r;
 
756
    if (fm_slant(fm_cur) == 0)
 
757
        return;
 
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;
 
768
}
 
769
 
 
770
static void t1_scan_keys(void)
 
771
{
 
772
    int i, k;
 
773
    char *p, *q, *r;
 
774
    key_entry *key;
 
775
    if (fm_extend(fm_cur) != 0 || fm_slant(fm_cur) != 0) {
 
776
        if (strncmp(t1_line + 1, "FontMatrix", strlen("FontMatrix")) == 0) {
 
777
            t1_modify_fm();
 
778
            return;
 
779
        }
 
780
        if (strncmp(t1_line + 1, "ItalicAngle", strlen("ItalicAngle")) == 0) {
 
781
            t1_modify_italic();
 
782
            return;
 
783
        }
 
784
    }
 
785
    for (key = font_keys; key - font_keys  < MAX_KEY_CODE; key++)
 
786
        if (strncmp(t1_line + 1, key->t1name, strlen(key->t1name)) == 0)
 
787
          break;
 
788
    if (key - font_keys == MAX_KEY_CODE)
 
789
        return;
 
790
    key->valid = true;
 
791
    p = t1_line + strlen(key->t1name) + 1;
 
792
    skip(p, ' ');
 
793
    if ((k = key - font_keys) == FONTNAME_CODE) {
 
794
        if (*p != '/') {
 
795
            remove_eol(p, t1_line);
 
796
            pdftex_fail("a name expected: `%s'", t1_line);
 
797
        }
 
798
        r = ++p; /* skip the slash */
 
799
        for (q = t1_buf; *p != ' ' && *p != 10; *q++ = *p++);
 
800
        *q = 0;
 
801
        if (fm_extend(fm_cur) != 0) {
 
802
            sprintf(q, "-Extend_%i", (int)fm_extend(fm_cur));
 
803
        }
 
804
        if (fm_slant(fm_cur) != 0) {
 
805
            sprintf(q, "-Slant_%i", (int)fm_slant(fm_cur));
 
806
        }
 
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);
 
810
            strcpy(t1_buf, p);
 
811
            sprintf(r, "******+%s%s", key->value.string, t1_buf);
 
812
            t1_line_ptr = eol(r);
 
813
        }
 
814
        return;
 
815
    }
 
816
    if ((k == STEMV_CODE ||  k == FONTBBOX1_CODE) &&
 
817
        (*p == '[' || *p == '{'))
 
818
        p++;
 
819
    if (k == FONTBBOX1_CODE) {
 
820
        for (i = 0; i < 4; i++) {
 
821
            key[i].value.num = t1_scan_num(p, &r);
 
822
            p = r;
 
823
        }
 
824
        return;
 
825
    }
 
826
    key->value.num = t1_scan_num(p, 0);
 
827
}
 
828
 
 
829
#endif /* pdfTeX */
 
830
 
 
831
static void t1_scan_param(void) 
 
832
{
 
833
    static const char *lenIV = "/lenIV";
 
834
    if (!t1_scan || *t1_line != '/')
 
835
        return;
 
836
    if (t1_prefix(lenIV)) {
 
837
        t1_lenIV = t1_scan_num(t1_line + strlen(lenIV), 0);
 
838
        return;
 
839
    }
 
840
    t1_scan_keys();
 
841
}
 
842
 
 
843
static void copy_glyph_names(char **glyph_names, int a, int b)
 
844
{
 
845
    if (glyph_names[b] != notdef) {
 
846
        free(glyph_names[b]);
 
847
        glyph_names[b] = xstrdup(notdef);
 
848
    }
 
849
    if (glyph_names[a] != notdef) {
 
850
        glyph_names[b] = xstrdup(glyph_names[a]);
 
851
    }
 
852
}
 
853
 
 
854
static void t1_builtin_enc(void)
 
855
{
 
856
    int i, a, b, c, counter = 0;
 
857
    char *r, *p;
 
858
   /*
 
859
    * At this moment "/Encoding" is the prefix of t1_line
 
860
    */
 
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);
 
867
                else
 
868
                    t1_builtin_glyph_names[i] = xstrdup(standard_glyph_names[i]);
 
869
            t1_encoding = ENC_STANDARD;
 
870
        }
 
871
        else 
 
872
            pdftex_fail("cannot subset font (unknown predefined encoding `%s')", 
 
873
                        t1_buf);
 
874
        return;
 
875
    }
 
876
    t1_encoding = ENC_BUILTIN;
 
877
   /*
 
878
    * At this moment "/Encoding" is the prefix of t1_line, and the encoding is
 
879
    * not a predefined encoding
 
880
    * 
 
881
    * We have two possible forms of Encoding vector. The first case is
 
882
    * 
 
883
    *     /Encoding [/a /b /c...] readonly def
 
884
    * 
 
885
    * and the second case can look like
 
886
    * 
 
887
    *     /Encoding 256 array 0 1 255 {1 index exch /.notdef put} for
 
888
    *     dup 0 /x put
 
889
    *     dup 1 /y put
 
890
    *     ...
 
891
    *     readonly def
 
892
    */
 
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;
 
897
        skip(r, ' ');
 
898
        for(;;) {
 
899
            while (*r == '/') {
 
900
                for (p = t1_buf, r++;
 
901
                     *r != 32 && *r != 10 && *r != ']' && *r != '/';
 
902
                     *p++ = *r++);
 
903
                *p = 0;
 
904
                skip(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);
 
910
                counter++;
 
911
            }
 
912
            if (*r != 10 && *r != '%') {
 
913
                if (str_prefix(r, "] def") || str_prefix(r, "] readonly def"))
 
914
                    break;
 
915
                else {
 
916
                    remove_eol(r, t1_line);
 
917
                    pdftex_fail("a name or `] def' or `] readonly def' expected: `%s'",
 
918
                                t1_line);
 
919
                }
 
920
            }
 
921
            t1_getline();
 
922
            r = t1_line;
 
923
        }
 
924
    }
 
925
    else { /* the second case */
 
926
        p = strchr(t1_line, 10); 
 
927
        for (;;) {
 
928
            if (*p == 10) {
 
929
                t1_getline();
 
930
                p = t1_line;
 
931
            }
 
932
            /*
 
933
             check for `dup <index> <glyph> put'
 
934
             */
 
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");
 
940
                skip(p, ' ');
 
941
            }
 
942
            /*
 
943
             check for `dup dup <to> exch <from> get put'
 
944
             */
 
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");
 
949
                skip(p, ' ');
 
950
            }
 
951
            /*
 
952
             check for `dup dup <from> <size> getinterval <to> exch putinterval'
 
953
             */
 
954
            else if (sscanf(p, "dup dup %i %i getinterval %i exch putinterval", 
 
955
                            &a, &c, &b) == 3 && 
 
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");
 
960
                skip(p, ' ');
 
961
            }
 
962
            /*
 
963
             check for `def' or `readonly def'
 
964
             */
 
965
            else if ((p == t1_line || (p > t1_line && p[-1] == ' ')) &&
 
966
                     strcmp(p, "def\n") == 0)
 
967
                return;
 
968
            /* 
 
969
             skip an unrecognizable word 
 
970
             */
 
971
            else {
 
972
                while (*p != ' ' && *p != 10)
 
973
                    p++;    
 
974
                skip(p, ' ');
 
975
            }
 
976
        }
 
977
    }
 
978
}
 
979
 
 
980
static void t1_check_end(void)
 
981
{
 
982
    if (t1_eof())
 
983
        return;
 
984
    t1_getline();
 
985
    if (t1_prefix("{restore}"))
 
986
        t1_putline();
 
987
}
 
988
 
 
989
#ifdef pdfTeX
 
990
static boolean t1_open_fontfile(const char *open_name_prefix)
 
991
{
 
992
    char *ex_ffname = 0;
 
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();
 
998
            goto open_ok;
 
999
        }
 
1000
    }
 
1001
    if (fm_cur->found)
 
1002
        t1_file = xfopen(cur_file_name = fm_cur->ff_name, FOPEN_RBIN_MODE);
 
1003
    else {
 
1004
        set_cur_file_name(fm_cur->ff_name);
 
1005
        if (!t1_open()) {
 
1006
            pdftex_warn("cannot open Type 1 font file for reading");
 
1007
            return false;
 
1008
        }
 
1009
        fix_ffname(fm_cur, cur_file_name = full_file_name());
 
1010
    }
 
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;
 
1014
        fm_extend(fm_cur) = 
 
1015
            roundxnoverd(fm_extend(fm_cur), 1000 + fm_cur->expansion, 1000);
 
1016
    }
 
1017
open_ok:
 
1018
    t1_init_params(open_name_prefix);
 
1019
    fontfile_found = true;
 
1020
    xfree(ex_ffname);
 
1021
    return true;
 
1022
}
 
1023
 
 
1024
boolean t1_read_enc(fm_entry *fm)
 
1025
{
 
1026
    read_encoding_only = true;
 
1027
    fm_cur = fm;
 
1028
    if (!t1_open_fontfile("{"))
 
1029
        return false;
 
1030
    fix_ffname(fm_cur, cur_file_name = full_file_name());
 
1031
    while (!t1_prefix("/Encoding"))
 
1032
        t1_getline();
 
1033
    t1_builtin_enc(); 
 
1034
    t1_close_font_file("}");
 
1035
    return true;
 
1036
}
 
1037
 
 
1038
static void t1_scan_only(void)
 
1039
{
 
1040
    do {
 
1041
        t1_getline();
 
1042
        t1_scan_param(); 
 
1043
    } while (t1_in_eexec == 0);
 
1044
    t1_start_eexec();
 
1045
    do {
 
1046
        t1_getline();
 
1047
        t1_scan_param();
 
1048
    } while (!(t1_charstrings() || t1_subrs()));
 
1049
}
 
1050
 
 
1051
static void t1_include(void)
 
1052
{
 
1053
    save_offset();
 
1054
    do {
 
1055
        t1_getline();
 
1056
        t1_scan_param();
 
1057
        t1_putline();
 
1058
    } while (t1_in_eexec == 0);
 
1059
    t1_start_eexec();
 
1060
    do {
 
1061
        t1_getline();
 
1062
        t1_scan_param();
 
1063
        t1_putline();
 
1064
    } while (!(t1_charstrings() || t1_subrs()));
 
1065
    t1_cs = true;
 
1066
    do {
 
1067
        t1_getline();
 
1068
        t1_putline();
 
1069
    } while (!t1_end_eexec());
 
1070
    t1_stop_eexec();
 
1071
    do {
 
1072
        t1_getline();
 
1073
        t1_putline();
 
1074
    } while (!t1_cleartomark());
 
1075
    t1_check_end(); /* write "{restore}if" if found */
 
1076
    get_length3();
 
1077
}
 
1078
 
 
1079
#else /* not pdfTeX */
 
1080
static boolean t1_open_fontfile(char *open_name_prefix)
 
1081
{
 
1082
    if (!t1_open())
 
1083
        return false;
 
1084
    t1_init_params(open_name_prefix);
 
1085
    return true;
 
1086
}
 
1087
#endif /* pdfTeX */
 
1088
 
 
1089
#define check_subr(subr) \
 
1090
    if (subr >= subr_size || subr < 0) \
 
1091
        pdftex_fail("Subrs array: entry index out of range (%i)",  subr);
 
1092
 
 
1093
static void cs_store(boolean is_subr)
 
1094
{
 
1095
    char *p, *q;
 
1096
    cs_entry *ptr;
 
1097
    int subr;
 
1098
    for (p = t1_line, q = t1_buf; *p != ' '; *q++ = *p++);
 
1099
    *q = 0;
 
1100
    if (is_subr) {
 
1101
        subr = t1_scan_num(p + 1, 0);
 
1102
        check_subr(subr);
 
1103
        ptr = subr_tab + subr;
 
1104
    }
 
1105
    else {
 
1106
        ptr = cs_ptr++;
 
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);
 
1111
        else
 
1112
            ptr->name = xstrdup(t1_buf + 1); 
 
1113
    }
 
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++);
 
1118
    *q++ = 10;
 
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; }
 
1129
    }
 
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);
 
1134
    ptr->valid = true;
 
1135
}
 
1136
 
 
1137
#define store_subr()    cs_store(true)
 
1138
#define store_cs()      cs_store(false)
 
1139
 
 
1140
#define CC_STACK_SIZE       24
 
1141
 
 
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;
 
1145
 
 
1146
 
 
1147
#define cc_pop(N)                       \
 
1148
    if (stack_ptr - cc_stack < (N))     \
 
1149
        stack_error(N);                 \
 
1150
    stack_ptr -= N
 
1151
 
 
1152
#define stack_error(N) {                \
 
1153
    pdftex_warn("CharString: invalid access (%i) to stack (%i entries)", \
 
1154
                 N, stack_ptr - cc_stack);                               \
 
1155
    goto cs_error;                    \
 
1156
}
 
1157
 
 
1158
/*
 
1159
static integer cc_get(integer index) 
 
1160
{
 
1161
    if (index <  0) {
 
1162
        if (stack_ptr + index < cc_stack )
 
1163
            stack_error(stack_ptr - cc_stack + index);
 
1164
        return *(stack_ptr + index);
 
1165
    }
 
1166
    else {
 
1167
        if (cc_stack  + index >= stack_ptr)
 
1168
            stack_error(index);
 
1169
        return cc_stack[index];
 
1170
    }
 
1171
}
 
1172
*/
 
1173
 
 
1174
#define cc_get(N)   ((N) < 0 ? *(stack_ptr + (N)) : *(cc_stack + (N)))
 
1175
 
 
1176
#define cc_push(V)  *stack_ptr++ = V
 
1177
#define cc_clear()  stack_ptr = cc_stack
 
1178
    
 
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
 
1184
    
 
1185
static void cc_init(void)
 
1186
{
 
1187
    int i;
 
1188
    if (is_cc_init)
 
1189
        return;
 
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);
 
1202
    /*
 
1203
    set_cc(CS_ESCAPE,          false,  0, false);
 
1204
    */
 
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);
 
1220
    is_cc_init = true;
 
1221
}
 
1222
 
 
1223
#define cs_getchar()    cdecrypt(*data++, &cr)
 
1224
 
 
1225
#define mark_subr(n)    cs_mark(0, n)
 
1226
#define mark_cs(s)      cs_mark(s, 0)
 
1227
 
 
1228
static void cs_warn(const char *cs_name, int subr, const char *fmt,...)
 
1229
{
 
1230
    char buf[SMALL_BUF_SIZE];
 
1231
    va_list args;
 
1232
    va_start(args, fmt);
 
1233
    vsprintf(buf, fmt, args);
 
1234
    va_end(args);
 
1235
    if (cs_name == 0)
 
1236
        pdftex_warn("Subr (%i): %s", (int)subr, buf);
 
1237
    else
 
1238
        pdftex_warn("CharString (/%s): %s", cs_name, buf);
 
1239
}
 
1240
 
 
1241
static void cs_mark(const char *cs_name, int subr)
 
1242
{
 
1243
    byte *data;
 
1244
    int i, b, cs_len;
 
1245
    integer a, a1, a2;
 
1246
    unsigned short cr;
 
1247
    static integer lastargOtherSubr3 = 3; /* the argument of last call to 
 
1248
                                             OtherSubrs[3] */
 
1249
    cs_entry *ptr;
 
1250
    cc_entry *cc;
 
1251
    if (cs_name == 0) {
 
1252
        check_subr(subr);
 
1253
        ptr = subr_tab + subr;
 
1254
        if (!ptr->valid)
 
1255
            return;
 
1256
    }
 
1257
    else {
 
1258
        if (cs_notdef != 0 && 
 
1259
            (cs_name == notdef || strcmp(cs_name, notdef) == 0))
 
1260
            ptr = cs_notdef;
 
1261
        else {
 
1262
            for (ptr = cs_tab; ptr < cs_ptr; ptr++)
 
1263
                if (strcmp(ptr->name, cs_name) == 0)
 
1264
                    break;
 
1265
            if (ptr == cs_ptr) {
 
1266
                pdftex_warn("glyph `%s' undefined", cs_name);
 
1267
                return;
 
1268
            }
 
1269
            if (ptr->name == notdef)
 
1270
                cs_notdef = ptr;
 
1271
        }
 
1272
    }
 
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))
 
1276
        return; 
 
1277
    ptr->used = true;
 
1278
    cr = 4330; 
 
1279
    cs_len = ptr->cslen;
 
1280
    data = ptr->data + 4;
 
1281
    for (i = 0; i < t1_lenIV; i++, cs_len--)
 
1282
        cs_getchar();
 
1283
    while (cs_len > 0) {
 
1284
        --cs_len;
 
1285
        b = cs_getchar();
 
1286
        if (b >= 32) {
 
1287
            if (b <= 246)
 
1288
                a = b - 139;
 
1289
            else if (b <= 250) {
 
1290
                --cs_len;
 
1291
                a = ((b - 247) << 8) + 108 + cs_getchar();
 
1292
            } 
 
1293
            else if (b <= 254) {
 
1294
                --cs_len;
 
1295
                a = -((b - 251) << 8) - 108 - cs_getchar();
 
1296
            } 
 
1297
            else {
 
1298
                cs_len -= 4;
 
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))
 
1304
                    a |= ~0x7FFFFFFF;
 
1305
            }
 
1306
            cc_push(a);
 
1307
        }
 
1308
        else {
 
1309
            if (b == CS_ESCAPE) {
 
1310
                b = cs_getchar() + CS_1BYTE_MAX;
 
1311
                cs_len--;
 
1312
            }
 
1313
            if (b >= CS_MAX) {
 
1314
                cs_warn(cs_name, subr, "command value out of range: %i", (int)b);
 
1315
                goto cs_error;
 
1316
            }
 
1317
            cc = cc_tab + b;
 
1318
            if (!cc->valid) {
 
1319
                cs_warn(cs_name, subr, "command not valid: %i", (int)b);
 
1320
                goto cs_error;
 
1321
            }
 
1322
            if (cc->bottom) {
 
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);
 
1331
            }
 
1332
            switch (cc - cc_tab) {
 
1333
            case CS_CALLSUBR:
 
1334
                a1 = cc_get(-1);
 
1335
                cc_pop(1);
 
1336
                mark_subr(a1);
 
1337
                if (!subr_tab[a1].valid) {
 
1338
                    cs_warn(cs_name, subr, 
 
1339
                            "cannot call subr (%i)", (int)a1);
 
1340
                    goto cs_error;
 
1341
                }
 
1342
                break;
 
1343
            case CS_DIV:
 
1344
                cc_pop(2);
 
1345
                cc_push(0);
 
1346
                break;
 
1347
            case CS_CALLOTHERSUBR:
 
1348
                if (cc_get(-1) == 3)
 
1349
                    lastargOtherSubr3 = cc_get(-3);
 
1350
                a1 = cc_get(-2) + 2;
 
1351
                cc_pop(a1);
 
1352
                break;
 
1353
            case CS_POP:
 
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
 
1357
                   OtherSubrs[3]) 
 
1358
                 */
 
1359
                break;
 
1360
            case CS_SEAC:
 
1361
                a1 = cc_get(3);
 
1362
                a2 = cc_get(4);
 
1363
                cc_clear();
 
1364
                mark_cs(standard_glyph_names[a1]);
 
1365
                mark_cs(standard_glyph_names[a2]);
 
1366
                break;
 
1367
            default:
 
1368
                if (cc->clear)
 
1369
                    cc_clear();
 
1370
            }
 
1371
        }
 
1372
    }
 
1373
    return;
 
1374
cs_error: /* an error occured during parsing */
 
1375
    cc_clear();
 
1376
    ptr->valid = false;
 
1377
    ptr->used = false;
 
1378
}
 
1379
 
 
1380
static void t1_subset_ascii_part(void)
 
1381
{
 
1382
    int i, j;
 
1383
    save_offset();
 
1384
    t1_getline();
 
1385
    while (!t1_prefix("/Encoding")) {
 
1386
        t1_scan_param();
 
1387
        t1_putline();
 
1388
        t1_getline();
 
1389
    }
 
1390
    t1_builtin_enc(); 
 
1391
    if (is_reencoded(fm_cur))
 
1392
        t1_glyph_names = external_enc();
 
1393
    else {
 
1394
        t1_glyph_names = t1_builtin_glyph_names;
 
1395
        update_builtin_enc(tex_font, t1_glyph_names); 
 
1396
    }
 
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");
 
1401
    else {
 
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) {
 
1405
                j++;
 
1406
                t1_printf("dup %i /%s put\n", (int)t1_char(i), t1_glyph_names[i]);
 
1407
            }
 
1408
        }
 
1409
        /* We didn't mark anything for the Encoding array. */
 
1410
        /* We add "dup 0 /.notdef put" for compatibility   */
 
1411
        /* with Acrobat 5.0.                               */
 
1412
        if (j == 0)
 
1413
            t1_puts("dup 0 /.notdef put\n");
 
1414
        t1_puts("readonly def\n");
 
1415
    }
 
1416
    do {
 
1417
        t1_getline();
 
1418
        t1_scan_param();
 
1419
        t1_putline();
 
1420
    } while (t1_in_eexec == 0);
 
1421
}
 
1422
 
 
1423
#define t1_subr_flush()  t1_flush_cs(true)
 
1424
#define t1_cs_flush()    t1_flush_cs(false)
 
1425
 
 
1426
static void t1_flush_cs(boolean);
 
1427
 
 
1428
static void cs_init(void)
 
1429
{
 
1430
    cs_ptr = cs_tab = 0;
 
1431
    cs_dict_start =  cs_dict_end = 0;
 
1432
    cs_count = cs_size = cs_size_pos = 0;
 
1433
    subr_tab = 0;
 
1434
    subr_array_start = subr_array_end = 0;
 
1435
    subr_max = subr_size = subr_size_pos = 0;
 
1436
}
 
1437
 
 
1438
static void init_cs_entry(cs_entry *cs)
 
1439
{
 
1440
    cs->data = 0;
 
1441
    cs->name = 0;
 
1442
    cs->len = 0;
 
1443
    cs->cslen = 0;
 
1444
    cs->used = false;
 
1445
    cs->valid = false;
 
1446
}
 
1447
 
 
1448
static void t1_mark_glyphs(void);
 
1449
 
 
1450
static void t1_read_subrs(void)
 
1451
{
 
1452
    int i;
 
1453
    char *s;
 
1454
    cs_entry *ptr;
 
1455
    t1_getline();
 
1456
    while (!(t1_charstrings() || t1_subrs())) {
 
1457
        t1_scan_param(); 
 
1458
        t1_putline();
 
1459
        t1_getline();
 
1460
    }
 
1461
found:
 
1462
    t1_cs = true;
 
1463
    t1_scan = false;
 
1464
    if (!t1_subrs())
 
1465
       return;
 
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())
 
1471
            t1_getline();
 
1472
        return;
 
1473
    }
 
1474
    subr_tab = xtalloc(subr_size, cs_entry);
 
1475
    for (ptr = subr_tab; ptr - subr_tab < subr_size; ptr++)
 
1476
        init_cs_entry(ptr);
 
1477
    subr_array_start = xstrdup(t1_line);
 
1478
    t1_getline();
 
1479
    while (t1_cslen) {
 
1480
        store_subr();
 
1481
        t1_getline();
 
1482
    }
 
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
 
1491
       Subrs is found
 
1492
     */
 
1493
#define POST_SUBRS_SCAN     5
 
1494
    s = t1_buf;
 
1495
    *t1_buf = 0;
 
1496
    for (i = 0; i < POST_SUBRS_SCAN; i++) {
 
1497
        if (t1_charstrings())
 
1498
               break;
 
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;
 
1502
        t1_getline();
 
1503
    }
 
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++)
 
1508
            if (ptr->valid)
 
1509
                xfree(ptr->data);
 
1510
        xfree(subr_tab);
 
1511
        xfree(subr_array_start);
 
1512
        xfree(subr_array_end);
 
1513
        cs_init();
 
1514
        t1_cs = false;
 
1515
        t1_synthetic = true;
 
1516
        while (!(t1_charstrings() || t1_subrs()))
 
1517
            t1_getline();
 
1518
        goto found;
 
1519
    }
 
1520
}
 
1521
 
 
1522
static void t1_flush_cs(boolean is_subr)
 
1523
{
 
1524
    char *p;
 
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;
 
1530
    if (is_subr) {
 
1531
        start_line = subr_array_start;
 
1532
        line_end = subr_array_end;
 
1533
        size_pos = subr_size_pos;
 
1534
        tab = subr_tab;
 
1535
        count = subr_max + 1;
 
1536
        end_tab = subr_tab + count;
 
1537
    }
 
1538
    else {
 
1539
        start_line = cs_dict_start;
 
1540
        line_end = cs_dict_end;
 
1541
        size_pos = cs_size_pos;
 
1542
        tab =  cs_tab;
 
1543
        end_tab = cs_ptr;
 
1544
        count = cs_count;
 
1545
    }
 
1546
    t1_line_ptr = t1_line;
 
1547
    for (p = start_line; p - start_line < size_pos;)
 
1548
        *t1_line_ptr++ = *p++;
 
1549
    while (isdigit(*p))
 
1550
        p++;
 
1551
    sprintf(t1_line_ptr, "%u", count);
 
1552
    strcat(t1_line_ptr, p);
 
1553
    t1_line_ptr = eol(t1_line);
 
1554
    t1_putline();
 
1555
 
 
1556
    if (is_subr) {
 
1557
        cr = 4330;
 
1558
        cs_len = 0;
 
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);
 
1563
        }
 
1564
        else {
 
1565
            *return_cs = CS_RETURN;
 
1566
        }
 
1567
        cs_len++;
 
1568
    }
 
1569
 
 
1570
    for (ptr = tab; ptr < end_tab; ptr++) {
 
1571
    
 
1572
        if (ptr->used) {
 
1573
            if (is_subr)
 
1574
                sprintf(t1_line, "dup %u %u", ptr - tab, ptr->cslen);
 
1575
            else
 
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;
 
1580
            t1_putline();
 
1581
        }
 
1582
        else {
 
1583
            if (is_subr) {
 
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;
 
1589
                t1_putline();
 
1590
                sprintf(t1_line, " %s", cs_token_pairs[cs_token_choice][1]);
 
1591
                t1_line_ptr = eol(t1_line);
 
1592
                t1_putline();
 
1593
            }
 
1594
        }
 
1595
        xfree(ptr->data);
 
1596
        if (ptr->name != 0 && ptr->name != notdef)
 
1597
            xfree(ptr->name);
 
1598
    }
 
1599
    sprintf(t1_line, "%s", line_end);
 
1600
    t1_line_ptr = eol(t1_line);
 
1601
    t1_putline();
 
1602
    if (is_subr) {
 
1603
        cs_token_choice = -1;
 
1604
        cs_tokens_found = false;
 
1605
    }
 
1606
    xfree(tab);
 
1607
    xfree(start_line);
 
1608
    xfree(line_end);
 
1609
}
 
1610
 
 
1611
static void t1_mark_glyphs(void)
 
1612
{
 
1613
    int i;
 
1614
    char *charset = extra_charset();
 
1615
    char *g, *s, *r;
 
1616
    cs_entry *ptr;
 
1617
    if (t1_synthetic || embed_all_glyphs(tex_font)) { /* mark everything */
 
1618
        if (cs_tab != 0)
 
1619
            for (ptr = cs_tab; ptr < cs_ptr; ptr++)
 
1620
                if (ptr->valid)
 
1621
                    ptr->used = true;
 
1622
        if (subr_tab != 0) {
 
1623
            for (ptr = subr_tab; ptr - subr_tab < subr_size; ptr++)
 
1624
                if (ptr->valid)
 
1625
                    ptr->used = true;
 
1626
            subr_max = subr_size - 1;
 
1627
        }
 
1628
        return;
 
1629
    }
 
1630
    mark_cs(notdef);
 
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);
 
1635
            else
 
1636
                mark_cs(t1_glyph_names[i]);
 
1637
        }
 
1638
    if (charset == 0)
 
1639
        goto set_subr_max;
 
1640
    g = s = charset + 1; /* skip the first '/' */
 
1641
    r = strend(g);
 
1642
    while (g < r) {
 
1643
        while (*s != '/' && s < r)
 
1644
            s++;
 
1645
        *s = 0; /* terminate g by rewriting '/' to 0 */
 
1646
        mark_cs(g);
 
1647
        g = s + 1;
 
1648
    }
 
1649
set_subr_max:
 
1650
    if (subr_tab != 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;
 
1654
}
 
1655
 
 
1656
static void t1_subset_charstrings(void)
 
1657
{
 
1658
    cs_entry *ptr;
 
1659
    cs_size_pos = strstr(t1_line, "/CharStrings") + strlen("/CharStrings") 
 
1660
                  - t1_line + 1; 
 
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++)
 
1666
        init_cs_entry(ptr);
 
1667
    cs_notdef = 0;
 
1668
    cs_dict_start = xstrdup(t1_line);
 
1669
    t1_getline();
 
1670
    while (t1_cslen) {
 
1671
        store_cs();
 
1672
        t1_getline();
 
1673
    }
 
1674
    cs_dict_end = xstrdup(t1_line);
 
1675
    t1_mark_glyphs();
 
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.");
 
1679
        t1_subr_flush();
 
1680
    }
 
1681
    for (cs_count = 0, ptr = cs_tab; ptr < cs_ptr; ptr++)
 
1682
        if (ptr->used)
 
1683
            cs_count++;
 
1684
    t1_cs_flush();
 
1685
}
 
1686
 
 
1687
static void t1_subset_end(void)
 
1688
{
 
1689
    if (t1_synthetic) { /* copy to "dup /FontName get exch definefont pop" */
 
1690
        while (!strstr(t1_line, "definefont")) {
 
1691
            t1_getline();
 
1692
            t1_putline();
 
1693
        }
 
1694
        while (!t1_end_eexec())
 
1695
            t1_getline();   /* ignore the rest */
 
1696
        t1_putline();       /* write "mark currentfile closefile" */
 
1697
    }
 
1698
    else while (!t1_end_eexec()) { /* copy to "mark currentfile closefile" */
 
1699
        t1_getline();
 
1700
        t1_putline();
 
1701
    }
 
1702
    t1_stop_eexec();
 
1703
    while (!t1_cleartomark()) {
 
1704
        t1_getline();
 
1705
        t1_putline();
 
1706
    }
 
1707
    if (!t1_synthetic)  /* don't check "{restore}if" for synthetic fonts */
 
1708
        t1_check_end(); /* write "{restore}if" if found */
 
1709
    get_length3();
 
1710
}
 
1711
 
 
1712
void writet1(void)
 
1713
{
 
1714
    read_encoding_only = false;
 
1715
#ifdef pdfTeX
 
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");
 
1719
        writeotf();
 
1720
        is_otf_font = true;
 
1721
        return;
 
1722
    }
 
1723
#endif
 
1724
    if (!is_included(fm_cur)) { /* scan parameters from font file */
 
1725
        if (!t1_open_fontfile("{"))
 
1726
            return;
 
1727
        t1_scan_only();
 
1728
        t1_close_font_file("}");
 
1729
        return;
 
1730
    }
 
1731
    if (!is_subsetted(fm_cur)) { /* include entire font */
 
1732
        if (!t1_open_fontfile("<<"))
 
1733
            return;
 
1734
        t1_include();
 
1735
        t1_close_font_file(">>");
 
1736
        return;
 
1737
    } 
 
1738
    /* partial downloading */
 
1739
    if (!t1_open_fontfile("<"))
 
1740
        return;
 
1741
    t1_subset_ascii_part();
 
1742
    t1_start_eexec();
 
1743
    cc_init();
 
1744
    cs_init();
 
1745
    t1_read_subrs();
 
1746
    t1_subset_charstrings();
 
1747
    t1_subset_end();
 
1748
    t1_close_font_file(">");
 
1749
}
 
1750
 
 
1751
#ifndef pdfTeX
 
1752
boolean t1_subset(char *fontfile, char *encfile, unsigned char *g)
 
1753
{
 
1754
    int i;
 
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);
 
1760
    grid = g;
 
1761
    cur_file_name = fontfile;
 
1762
    hexline_length = 0;
 
1763
    writet1();
 
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 */
 
1768
}
 
1769
boolean t1_subset_2(char *fontfile, unsigned char *g, char *extraGlyphs)
 
1770
{
 
1771
    int i;
 
1772
    cur_enc_name = 0; /* PyX */
 
1773
    for (i = 0; i <= MAX_CHAR_CODE; i++)
 
1774
        ext_glyph_names[i] = notdef;
 
1775
    grid = g;
 
1776
    cur_file_name = fontfile;
 
1777
    hexline_length = 0;
 
1778
    dvips_extra_charset = extraGlyphs ;
 
1779
    writet1();
 
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 */
 
1784
}
 
1785
#endif /* not pdfTeX */