Coverage Report

Created: 2025-08-28 07:06

/src/ghostpdl/devices/vector/gdevpsf2.c
Line
Count
Source (jump to first uncovered line)
1
/* Copyright (C) 2001-2025 Artifex Software, Inc.
2
   All Rights Reserved.
3
4
   This software is provided AS-IS with no warranty, either express or
5
   implied.
6
7
   This software is distributed under license and may not be copied,
8
   modified or distributed except as expressly authorized under the terms
9
   of the license contained in the file LICENSE in this distribution.
10
11
   Refer to licensing information at http://www.artifex.com or contact
12
   Artifex Software, Inc.,  39 Mesa Street, Suite 108A, San Francisco,
13
   CA 94129, USA, for further information.
14
*/
15
16
17
/* Write an embedded CFF font with either Type 1 or Type 2 CharStrings */
18
#include "math_.h"    /* for fabs */
19
#include "memory_.h"
20
#include "gx.h"
21
#include "gxarith.h"
22
#include "gscencs.h"
23
#include "gserrors.h"
24
#include "gsccode.h"
25
#include "gscrypt1.h"
26
#include "gsmatrix.h"
27
#include "gsutil.h"
28
#include "gxfixed.h"
29
#include "gxfont.h"
30
#include "gxfont1.h"
31
#include "gxfcid.h"
32
#include "stream.h"
33
#include "gdevpsf.h"
34
35
/* Define additional opcodes used in Dicts, but not in CharStrings. */
36
#define CD_LONGINT 29
37
#define CD_REAL 30
38
39
/* Define the count of standard strings. */
40
301k
#define NUM_STD_STRINGS 391
41
42
/* Define whether or not to skip writing an empty Subrs Index. */
43
#define SKIP_EMPTY_SUBRS
44
45
/* Define the structure for the string table. */
46
typedef struct cff_string_item_s {
47
    gs_const_string key;
48
    int index1;   /* index + 1, 0 means empty */
49
} cff_string_item_t;
50
typedef struct cff_string_table_s {
51
    cff_string_item_t *items;
52
    int count;
53
    int size;
54
    uint total;
55
    int reprobe;
56
} cff_string_table_t;
57
58
/* Define the state of the CFF writer. */
59
typedef struct cff_writer_s {
60
    int options;
61
    stream *strm;
62
    gs_font_base *pfont;  /* type1 or cid0 */
63
    glyph_data_proc_t glyph_data;
64
    gs_offset_t offset_size;
65
    gs_offset_t start_pos;
66
    cff_string_table_t std_strings;
67
    cff_string_table_t strings;
68
    gs_int_rect FontBBox;
69
} cff_writer_t;
70
typedef struct cff_glyph_subset_s {
71
    psf_outline_glyphs_t glyphs;
72
    int num_encoded;    /* glyphs.subset_data[1..num_e] are encoded */
73
    int num_encoded_chars;  /* Encoding has num_e_chars defined entries */
74
} cff_glyph_subset_t;
75
76
/* ---------------- Output utilities ---------------- */
77
78
/* ------ String tables ------ */
79
80
/* Initialize a string table. */
81
static void
82
cff_string_table_init(cff_string_table_t *pcst, cff_string_item_t *items,
83
                      int size)
84
29.9k
{
85
29.9k
    int reprobe = 17;
86
87
29.9k
    memset(items, 0, size * sizeof(*items));
88
29.9k
    pcst->items = items;
89
29.9k
    pcst->count = 0;
90
29.9k
    pcst->size = size;
91
30.8k
    while (reprobe != 1 && igcd(size, reprobe) != 1)
92
926
        reprobe = (reprobe * 2 + 1) % size;
93
29.9k
    pcst->total = 0;
94
29.9k
    pcst->reprobe = reprobe;
95
29.9k
}
96
97
/* Add a string to a string table. */
98
static int
99
cff_string_add(cff_string_table_t *pcst, const byte *data, uint size)
100
5.82M
{
101
5.82M
    int index;
102
103
5.82M
    if (pcst->count >= pcst->size)
104
0
        return_error(gs_error_limitcheck);
105
5.82M
    index = pcst->count++;
106
5.82M
    pcst->items[index].key.data = data;
107
5.82M
    pcst->items[index].key.size = size;
108
5.82M
    pcst->total += size;
109
5.82M
    return index;
110
5.82M
}
111
112
/* Look up a string, optionally adding it. */
113
/* Return 1 if the string was added. */
114
static int
115
cff_string_index(cff_string_table_t *pcst, const byte *data, uint size,
116
                 bool enter, int *pindex)
117
7.68M
{
118
    /****** FAILS IF TABLE FULL AND KEY MISSING ******/
119
7.68M
    int j = (size == 0 ? 0 : data[0] * 23 + data[size - 1] * 59 + size);
120
7.68M
    int index, c = 0;
121
122
20.8M
    while ((index = pcst->items[j %= pcst->size].index1) != 0) {
123
14.6M
        --index;
124
14.6M
        if (!bytes_compare(pcst->items[index].key.data,
125
14.6M
                           pcst->items[index].key.size, data, size)) {
126
1.55M
            *pindex = index;
127
1.55M
            return 0;
128
1.55M
        }
129
13.1M
        j += pcst->reprobe;
130
13.1M
        if (++c >= pcst->size)
131
0
            break;
132
13.1M
    }
133
6.12M
    if (!enter)
134
301k
        return_error(gs_error_undefined);
135
5.82M
    index = cff_string_add(pcst, data, size);
136
5.82M
    if (index < 0)
137
0
        return index;
138
5.82M
    pcst->items[j].index1 = index + 1;
139
5.82M
    *pindex = index;
140
5.82M
    return 1;
141
5.82M
}
142
143
/* Get the SID for a string or a glyph. */
144
static int
145
cff_string_sid(cff_writer_t *pcw, const byte *data, uint size)
146
1.60M
{
147
1.60M
    int index;
148
1.60M
    int code = cff_string_index(&pcw->std_strings, data, size, false, &index);
149
150
1.60M
    if (code < 0) {
151
301k
        code = cff_string_index(&pcw->strings, data, size, true, &index);
152
301k
        if (code < 0)
153
0
            return code;
154
301k
        index += NUM_STD_STRINGS;
155
301k
    }
156
1.60M
    return index;
157
1.60M
}
158
static int
159
cff_glyph_sid(cff_writer_t *pcw, gs_glyph glyph)
160
1.32M
{
161
1.32M
    gs_const_string str;
162
1.32M
    int code =
163
1.32M
        pcw->pfont->procs.glyph_name((gs_font *)pcw->pfont, glyph, &str);
164
165
1.32M
    if (code < 0)
166
0
        return code;
167
1.32M
    return cff_string_sid(pcw, str.data, str.size);
168
1.32M
}
169
170
/* ------ Low level ------ */
171
172
static void
173
put_card16(cff_writer_t *pcw, uint c16)
174
2.34M
{
175
2.34M
    sputc(pcw->strm, (byte)(c16 >> 8));
176
2.34M
    sputc(pcw->strm, (byte)c16);
177
2.34M
}
178
static int
179
offset_size(uint offset)
180
417k
{
181
417k
    int size = 1;
182
183
560k
    while (offset > 255)
184
142k
        offset >>= 8, ++size;
185
417k
    return size;
186
417k
}
187
static void
188
put_offset(cff_writer_t *pcw, int offset)
189
2.07M
{
190
2.07M
    int i;
191
192
5.42M
    for (i = pcw->offset_size - 1; i >= 0; --i)
193
3.34M
        sputc(pcw->strm, (byte)(offset >> (i * 8)));
194
2.07M
}
195
static int
196
put_bytes(stream * s, const byte *ptr, uint count)
197
557k
{
198
557k
    uint used;
199
200
557k
    sputs(s, ptr, count, &used);
201
557k
    return (int)used;
202
557k
}
203
static int
204
check_ioerror(stream * s)
205
235k
{
206
235k
    uint used = 0;
207
208
235k
    return sputs(s, (byte *)&used, 0, &used);
209
235k
}
210
211
/* ------ Data types ------ */
212
213
1.08M
#define CE_OFFSET 32
214
static void
215
cff_put_op(cff_writer_t *pcw, int op)
216
1.08M
{
217
1.08M
    if (op >= CE_OFFSET) {
218
346k
        sputc(pcw->strm, cx_escape);
219
346k
        sputc(pcw->strm, (byte)(op - CE_OFFSET));
220
346k
    } else
221
734k
        sputc(pcw->strm, (byte)op);
222
1.08M
}
223
static void
224
cff_put_int(cff_writer_t *pcw, int i)
225
2.88M
{
226
2.88M
    stream *s = pcw->strm;
227
228
2.88M
    if (i >= -107 && i <= 107)
229
2.03M
        sputc(s, (byte)(i + 139));
230
853k
    else if (i <= 1131 && i >= 0)
231
700k
        put_card16(pcw, (c_pos2_0 << 8) + i - 108);
232
152k
    else if (i >= -1131 && i < 0)
233
56.0k
        put_card16(pcw, (c_neg2_0 << 8) - i - 108);
234
96.9k
    else if (i >= -32768 && i <= 32767) {
235
21.7k
        sputc(s, c2_shortint);
236
21.7k
        put_card16(pcw, i & 0xffff);
237
75.1k
    } else {
238
75.1k
        sputc(s, CD_LONGINT);
239
75.1k
        put_card16(pcw, i >> 16);
240
75.1k
        put_card16(pcw, i & 0xffff);
241
75.1k
    }
242
2.88M
}
243
static void
244
cff_put_int_value(cff_writer_t *pcw, int i, int op)
245
426k
{
246
426k
    cff_put_int(pcw, i);
247
426k
    cff_put_op(pcw, op);
248
426k
}
249
static void
250
cff_put_int_if_ne(cff_writer_t *pcw, int i, int i_default, int op)
251
577k
{
252
577k
    if (i != i_default)
253
273k
        cff_put_int_value(pcw, i, op);
254
577k
}
255
static void
256
cff_put_bool(cff_writer_t *pcw, bool b)
257
2.48k
{
258
2.48k
    cff_put_int(pcw, (b ? 1 : 0));
259
2.48k
}
260
static void
261
cff_put_bool_value(cff_writer_t *pcw, bool b, int op)
262
2.48k
{
263
2.48k
    cff_put_bool(pcw, b);
264
2.48k
    cff_put_op(pcw, op);
265
2.48k
}
266
static void
267
cff_put_real(cff_writer_t *pcw, double f)
268
2.10M
{
269
2.10M
    if (f == (int)f)
270
2.09M
        cff_put_int(pcw, (int)f);
271
10.5k
    else {
272
        /* Use decimal representation. */
273
10.5k
        char str[50];
274
10.5k
        byte b = 0xff;
275
10.5k
        const char *p;
276
277
10.5k
        gs_snprintf(str, sizeof(str), "%g", f);
278
10.5k
        sputc(pcw->strm, CD_REAL);
279
79.1k
        for (p = str; ; ++p) {
280
79.1k
            int digit;
281
282
79.1k
            switch (*p) {
283
10.5k
            case 0:
284
10.5k
                goto done;
285
10.4k
            case '.':
286
10.4k
                digit = 0xa; break;
287
36
            case '+':
288
36
                continue;
289
5
            case '-':
290
5
                digit = 0xe; break;
291
36
            case 'e': case 'E':
292
36
                if (p[1] == '-')
293
0
                    digit = 0xc, ++p;
294
36
                else
295
36
                    digit = 0xb;
296
36
                break;
297
34.0k
            case '0': case '1': case '2': case '3': case '4':
298
57.6k
            case '5': case '6': case '7': case '8': case '9':
299
57.6k
                digit = *p - '0';
300
57.6k
                break;
301
432
            default:    /* can't happen */
302
432
                digit = 0xd;  /* invalid */
303
432
                break;
304
79.1k
            }
305
68.5k
            if (b == 0xff)
306
37.9k
                b = (digit << 4) + 0xf;
307
30.6k
            else {
308
30.6k
                sputc(pcw->strm, (byte)((b & 0xf0) + digit));
309
30.6k
                b = 0xff;
310
30.6k
            }
311
68.5k
        }
312
10.5k
    done:
313
10.5k
        sputc(pcw->strm, b);
314
10.5k
    }
315
2.10M
}
316
static void
317
cff_put_real_value(cff_writer_t *pcw, double f, int op)
318
128k
{
319
128k
    cff_put_real(pcw, f);
320
128k
    cff_put_op(pcw, op);
321
128k
}
322
static void
323
cff_put_real_if_ne(cff_writer_t *pcw, double f, double f_default, int op)
324
333k
{
325
333k
    if ((float)f != (float)f_default)
326
7.64k
        cff_put_real_value(pcw, f, op);
327
333k
}
328
static void
329
cff_put_real_deltarray(cff_writer_t *pcw, const float *pf, int count, int op)
330
362k
{
331
362k
    float prev = 0;
332
362k
    int i;
333
334
362k
    if (count <= 0)
335
189k
        return;
336
1.86M
    for (i = 0; i < count; ++i) {
337
1.69M
        float f = pf[i];
338
339
1.69M
        cff_put_real(pcw, f - prev);
340
1.69M
        prev = f;
341
1.69M
    }
342
172k
    cff_put_op(pcw, op);
343
172k
}
344
static int
345
cff_put_string(cff_writer_t *pcw, const byte *data, uint size)
346
282k
{
347
282k
    int sid = cff_string_sid(pcw, data, size);
348
349
282k
    if (sid < 0)
350
0
        return sid;
351
282k
    cff_put_int(pcw, sid);
352
282k
    return 0;
353
282k
}
354
static int
355
cff_put_string_value(cff_writer_t *pcw, const byte *data, uint size, int op)
356
279k
{
357
279k
    int code = cff_put_string(pcw, data, size);
358
359
279k
    if (code >= 0)
360
279k
        cff_put_op(pcw, op);
361
279k
    return code;
362
279k
}
363
static int
364
cff_extra_lenIV(const cff_writer_t *pcw, const gs_font_type1 *pfont)
365
1.39M
{
366
1.39M
    return (pcw->options & WRITE_TYPE2_NO_LENIV ?
367
1.39M
            max(pfont->data.lenIV, 0) : 0);
368
1.39M
}
369
static bool
370
cff_convert_charstrings(const cff_writer_t *pcw, const gs_font_base *pfont)
371
2.70M
{
372
2.70M
    return (pfont->FontType != ft_encrypted2 &&
373
2.70M
            (pcw->options & WRITE_TYPE2_CHARSTRINGS) != 0);
374
2.70M
}
375
static int
376
cff_put_CharString(cff_writer_t *pcw, const byte *data, uint size,
377
                   gs_font_type1 *pfont)
378
1.22M
{
379
1.22M
    int lenIV = pfont->data.lenIV;
380
1.22M
    stream *s = pcw->strm;
381
382
1.22M
    if (cff_convert_charstrings(pcw, (gs_font_base *)pfont)) {
383
1.03M
        gs_glyph_data_t gdata;
384
1.03M
        int code;
385
386
1.03M
        gdata.memory = pfont->memory;
387
1.03M
        gs_glyph_data_from_string(&gdata, data, size, NULL);
388
1.03M
        code = psf_convert_type1_to_type2(s, &gdata, pfont);
389
1.03M
        if (code < 0)
390
0
            return code;
391
1.03M
    } else if (lenIV < 0 || !(pcw->options & WRITE_TYPE2_NO_LENIV))
392
186k
        put_bytes(s, data, size);
393
0
    else if (size >= lenIV) {
394
        /* Remove encryption. */
395
0
        crypt_state state = crypt_charstring_seed;
396
0
        byte buf[50];   /* arbitrary */
397
0
        uint left, n;
398
399
0
        for (left = lenIV; left > 0; left -= n) {
400
0
            n = min(left, sizeof(buf));
401
0
            gs_type1_decrypt(buf, data + lenIV - left, n, &state);
402
0
        }
403
0
        for (left = size - lenIV; left > 0; left -= n) {
404
0
            n = min(left, sizeof(buf));
405
0
            gs_type1_decrypt(buf, data + size - left, n, &state);
406
0
            put_bytes(s, buf, n);
407
0
        }
408
0
    }
409
1.22M
    return 0;
410
1.22M
}
411
static uint
412
cff_Index_size(uint count, uint total)
413
223k
{
414
223k
    return (count == 0 ? 2 :
415
223k
            3 + offset_size(total + 1) * (count + 1) + total);
416
223k
}
417
static void
418
cff_put_Index_header(cff_writer_t *pcw, uint count, uint total)
419
353k
{
420
353k
    put_card16(pcw, count);
421
353k
    if (count > 0) {
422
239k
        pcw->offset_size = offset_size(total + 1);
423
239k
        sputc(pcw->strm, (byte)pcw->offset_size);
424
239k
        put_offset(pcw, 1);
425
239k
    }
426
353k
}
427
static void
428
cff_put_Index(cff_writer_t *pcw, const cff_string_table_t *pcst)
429
59.6k
{
430
59.6k
    uint j, offset;
431
432
59.6k
    if (pcst->count == 0) {
433
292
        put_card16(pcw, 0);
434
292
        return;
435
292
    }
436
59.3k
    cff_put_Index_header(pcw, pcst->count, pcst->total);
437
251k
    for (j = 0, offset = 1; j < pcst->count; ++j) {
438
192k
        offset += pcst->items[j].key.size;
439
192k
        put_offset(pcw, offset);
440
192k
    }
441
251k
    for (j = 0; j < pcst->count; ++j)
442
192k
        put_bytes(pcw->strm, pcst->items[j].key.data, pcst->items[j].key.size);
443
59.3k
}
444
445
/* ---------------- Main code ---------------- */
446
447
/* ------ Header ------ */
448
449
/* Write the header, setting offset_size. */
450
static int
451
cff_write_header(cff_writer_t *pcw, uint end_offset)
452
59.6k
{
453
59.6k
    pcw->offset_size = (end_offset > 0x7fff ? 3 : 2);
454
59.6k
    put_bytes(pcw->strm, (const byte *)"\001\000\004", 3);
455
59.6k
    sputc(pcw->strm, (byte)pcw->offset_size);
456
59.6k
    return 0;
457
59.6k
}
458
459
/* ------ Top Dict ------ */
460
461
/*
462
 * There are 3 variants of this: Type 1 / Type 2 font, CIDFontType 0
463
 * CIDFont, and FDArray entry for CIDFont.
464
 */
465
466
typedef enum {
467
    TOP_version = 0,
468
    TOP_Notice = 1,
469
    TOP_FullName = 2,
470
    TOP_FamilyName = 3,
471
    TOP_Weight = 4,
472
    TOP_FontBBox = 5,
473
    TOP_UniqueID = 13,
474
    TOP_XUID = 14,
475
    TOP_charset = 15,   /* (offset or predefined index) */
476
#define charset_ISOAdobe 0
477
#define charset_Expert 1
478
#define charset_ExpertSubset 2
479
74.4k
#define charset_DEFAULT 0
480
    TOP_Encoding = 16,    /* (offset or predefined index) */
481
#define Encoding_Standard 0
482
#define Encoding_Expert 1
483
73.6k
#define Encoding_DEFAULT 0
484
    TOP_CharStrings = 17, /* (offset) */
485
    TOP_Private = 18,   /* (offset) */
486
    TOP_Copyright = 32,
487
    TOP_isFixedPitch = 33,
488
#define isFixedPitch_DEFAULT false
489
    TOP_ItalicAngle = 34,
490
151k
#define ItalicAngle_DEFAULT 0
491
    TOP_UnderlinePosition = 35,
492
151k
#define UnderlinePosition_DEFAULT (-100)
493
    TOP_UnderlineThickness = 36,
494
151k
#define UnderlineThickness_DEFAULT 50
495
    TOP_PaintType = 37,
496
76.2k
#define PaintType_DEFAULT 0
497
    TOP_CharstringType = 38,
498
73.6k
#define CharstringType_DEFAULT 2
499
    TOP_FontMatrix = 39,  /* default is [0.001 0 0 0.001 0 0] */
500
    TOP_StrokeWidth = 40,
501
76.2k
#define StrokeWidth_DEFAULT 0
502
    TOP_ROS = 62,
503
    TOP_CIDFontVersion = 63,
504
#define CIDFontVersion_DEFAULT 0
505
    TOP_CIDFontRevision = 64,
506
#define CIDFontRevision_DEFAULT 0
507
    TOP_CIDFontType = 65,
508
#define CIDFontType_DEFAULT 0
509
    TOP_CIDCount = 66,
510
747
#define CIDCount_DEFAULT 8720
511
    TOP_UIDBase = 67,
512
    TOP_FDArray = 68,   /* (offset) */
513
    TOP_FDSelect = 69,    /* (offset) */
514
    TOP_FontName = 70   /* only used in FDArray "fonts" */
515
} Top_op;
516
517
static int
518
cff_get_Top_info_common(cff_writer_t *pcw, gs_font_base *pbfont,
519
                        bool full_info, gs_font_info_t *pinfo)
520
75.6k
{
521
75.6k
    pinfo->Flags_requested = FONT_IS_FIXED_WIDTH;
522
    /* Preset defaults */
523
75.6k
    pinfo->members = 0;
524
75.6k
    pinfo->Flags = pinfo->Flags_returned = 0;
525
75.6k
    pinfo->ItalicAngle = ItalicAngle_DEFAULT;
526
75.6k
    pinfo->UnderlinePosition = UnderlinePosition_DEFAULT;
527
75.6k
    pinfo->UnderlineThickness = UnderlineThickness_DEFAULT;
528
75.6k
    return pbfont->procs.font_info
529
75.6k
        ((gs_font *)pbfont, NULL,
530
75.6k
         (full_info ?
531
73.8k
          FONT_INFO_FLAGS | FONT_INFO_ITALIC_ANGLE |
532
73.8k
            FONT_INFO_UNDERLINE_POSITION |
533
73.8k
            FONT_INFO_UNDERLINE_THICKNESS : 0) |
534
75.6k
         (FONT_INFO_COPYRIGHT | FONT_INFO_NOTICE |
535
75.6k
          FONT_INFO_FAMILY_NAME | FONT_INFO_FULL_NAME),
536
75.6k
         pinfo);
537
75.6k
}
538
static void
539
cff_write_Top_common(cff_writer_t *pcw, gs_font_base *pbfont,
540
                     bool write_FontMatrix, const gs_font_info_t *pinfo)
541
76.2k
{
542
    /*
543
     * The Adobe documentation doesn't make it at all clear that if the
544
     * FontMatrix is missing (defaulted) in a CFF CIDFont, all of the
545
     * FontMatrices of the subfonts in FDArray are multiplied by 1000.
546
     * (This is documented for ordinary CIDFonts, but not for CFF CIDFonts.)
547
     * Because of this, the FontMatrix for a CFF CIDFont must be written
548
     * even if if is the default.  write_FontMatrix controls this.
549
     */
550
    /* (version) */
551
76.2k
    if (pinfo->members & FONT_INFO_NOTICE)
552
72.6k
        cff_put_string_value(pcw, pinfo->Notice.data, pinfo->Notice.size,
553
72.6k
                             TOP_Notice);
554
76.2k
    if (pinfo->members & FONT_INFO_FULL_NAME)
555
70.9k
        cff_put_string_value(pcw, pinfo->FullName.data, pinfo->FullName.size,
556
70.9k
                             TOP_FullName);
557
76.2k
    if (pinfo->members & FONT_INFO_FAMILY_NAME)
558
70.7k
        cff_put_string_value(pcw, pinfo->FamilyName.data,
559
70.7k
                             pinfo->FamilyName.size, TOP_FamilyName);
560
76.2k
    if (pcw->FontBBox.p.x != 0 || pcw->FontBBox.p.y != 0 ||
561
76.2k
        pcw->FontBBox.q.x != 0 || pcw->FontBBox.q.y != 0
562
76.2k
        ) {
563
        /* An omitted FontBBox is equivalent to an empty one. */
564
        /*
565
         * Since Acrobat Reader 4 on Solaris doesn't like
566
         * an omitted FontBBox, we copy it here from
567
         * the font descriptor, because the base font
568
         * is allowed to omit it's FontBBox.
569
         */
570
67.5k
        cff_put_real(pcw, pcw->FontBBox.p.x);
571
67.5k
        cff_put_real(pcw, pcw->FontBBox.p.y);
572
67.5k
        cff_put_real(pcw, pcw->FontBBox.q.x);
573
67.5k
        cff_put_real(pcw, pcw->FontBBox.q.y);
574
67.5k
        cff_put_op(pcw, TOP_FontBBox);
575
67.5k
      }
576
76.2k
    if (uid_is_UniqueID(&pbfont->UID))
577
110
        cff_put_int_value(pcw, pbfont->UID.id, TOP_UniqueID);
578
76.1k
    else if (uid_is_XUID(&pbfont->UID) && (pcw->options & WRITE_TYPE2_XUID) != 0) {
579
0
        int j, k = uid_XUID_size(&pbfont->UID);
580
581
        /* Adobe products (specifically Acrobat but the same limitation is mentioned
582
         * in the PLRM) cannot handle XUIDs > 16 entries.
583
         */
584
0
        if (k > 16)
585
0
            k = 16;
586
0
        for (j = 0; j < uid_XUID_size(&pbfont->UID); ++j)
587
0
            cff_put_int(pcw, uid_XUID_values(&pbfont->UID)[j]);
588
0
        cff_put_op(pcw, TOP_XUID);
589
0
    }
590
    /*
591
     * Acrobat Reader 3 gives an error if a CFF font includes any of the
592
     * following opcodes.
593
     */
594
76.2k
    if (!(pcw->options & WRITE_TYPE2_AR3)) {
595
76.2k
        if (pinfo->members & FONT_INFO_COPYRIGHT)
596
64.7k
            cff_put_string_value(pcw, pinfo->Copyright.data,
597
64.7k
                                 pinfo->Copyright.size, TOP_Copyright);
598
76.2k
        if (pinfo->Flags & pinfo->Flags_returned & FONT_IS_FIXED_WIDTH)
599
1.03k
            cff_put_bool_value(pcw, true, TOP_isFixedPitch);
600
76.2k
        cff_put_real_if_ne(pcw, pinfo->ItalicAngle, ItalicAngle_DEFAULT,
601
76.2k
                           TOP_ItalicAngle);
602
76.2k
        cff_put_int_if_ne(pcw, pinfo->UnderlinePosition,
603
76.2k
                          UnderlinePosition_DEFAULT, TOP_UnderlinePosition);
604
76.2k
        cff_put_int_if_ne(pcw, pinfo->UnderlineThickness,
605
76.2k
                          UnderlineThickness_DEFAULT, TOP_UnderlineThickness);
606
76.2k
        cff_put_int_if_ne(pcw, pbfont->PaintType, PaintType_DEFAULT,
607
76.2k
                          TOP_PaintType);
608
76.2k
    }
609
76.2k
    {
610
76.2k
        static const gs_matrix fm_default = {
611
76.2k
            constant_matrix_body(0.001, 0, 0, 0.001, 0, 0)
612
76.2k
        };
613
614
76.2k
        if (write_FontMatrix ||
615
76.2k
            pbfont->FontMatrix.xx != fm_default.xx ||
616
76.2k
            pbfont->FontMatrix.xy != 0 || pbfont->FontMatrix.yx != 0 ||
617
76.2k
            pbfont->FontMatrix.yy != fm_default.yy ||
618
76.2k
            pbfont->FontMatrix.tx != 0 || pbfont->FontMatrix.ty != 0
619
76.2k
            ) {
620
2.95k
            cff_put_real(pcw, pbfont->FontMatrix.xx);
621
2.95k
            cff_put_real(pcw, pbfont->FontMatrix.xy);
622
2.95k
            cff_put_real(pcw, pbfont->FontMatrix.yx);
623
2.95k
            cff_put_real(pcw, pbfont->FontMatrix.yy);
624
2.95k
            cff_put_real(pcw, pbfont->FontMatrix.tx);
625
2.95k
            cff_put_real(pcw, pbfont->FontMatrix.ty);
626
2.95k
            cff_put_op(pcw, TOP_FontMatrix);
627
2.95k
        }
628
76.2k
    }
629
76.2k
    cff_put_real_if_ne(pcw, pbfont->StrokeWidth, StrokeWidth_DEFAULT,
630
76.2k
                       TOP_StrokeWidth);
631
76.2k
}
632
633
/* Type 1 or Type 2 font */
634
static void
635
cff_write_Top_font(cff_writer_t *pcw, uint Encoding_offset,
636
                   uint charset_offset, uint CharStrings_offset,
637
                   uint Private_offset, uint Private_size)
638
73.6k
{
639
73.6k
    gs_font_base *pbfont = (gs_font_base *)pcw->pfont;
640
73.6k
    gs_font_info_t info;
641
642
73.6k
    cff_get_Top_info_common(pcw, pbfont, true, &info);
643
73.6k
    cff_write_Top_common(pcw, pbfont, false, &info);
644
73.6k
    cff_put_int(pcw, Private_size);
645
73.6k
    cff_put_int_value(pcw, Private_offset, TOP_Private);
646
73.6k
    cff_put_int_value(pcw, CharStrings_offset, TOP_CharStrings);
647
73.6k
    cff_put_int_if_ne(pcw, charset_offset, charset_DEFAULT, TOP_charset);
648
73.6k
    cff_put_int_if_ne(pcw, Encoding_offset, Encoding_DEFAULT, TOP_Encoding);
649
73.6k
    {
650
73.6k
        int type = (pcw->options & WRITE_TYPE2_CHARSTRINGS ? 2 :
651
73.6k
                    pbfont->FontType == ft_encrypted2 ? 2 : 1);
652
653
73.6k
        cff_put_int_if_ne(pcw, type, CharstringType_DEFAULT,
654
73.6k
                          TOP_CharstringType);
655
73.6k
    }
656
73.6k
}
657
658
/* CIDFontType 0 CIDFont */
659
static void
660
cff_write_ROS(cff_writer_t *pcw, const gs_cid_system_info_t *pcidsi)
661
933
{
662
933
    cff_put_string(pcw, pcidsi->Registry.data, pcidsi->Registry.size);
663
933
    cff_put_string(pcw, pcidsi->Ordering.data, pcidsi->Ordering.size);
664
933
    cff_put_int_value(pcw, pcidsi->Supplement, TOP_ROS);
665
933
}
666
static void
667
cff_write_Top_cidfont(cff_writer_t *pcw, uint charset_offset,
668
                      uint CharStrings_offset, uint FDSelect_offset,
669
                      uint Font_offset, const gs_font_info_t *pinfo)
670
747
{
671
747
    gs_font_base *pbfont = (gs_font_base *)pcw->pfont;
672
747
    gs_font_cid0 *pfont = (gs_font_cid0 *)pbfont;
673
674
747
    cff_write_ROS(pcw, &pfont->cidata.common.CIDSystemInfo);
675
747
    cff_write_Top_common(pcw, pbfont, true, pinfo); /* full_info = true */
676
747
    cff_put_int_if_ne(pcw, charset_offset, charset_DEFAULT, TOP_charset);
677
747
    cff_put_int_value(pcw, CharStrings_offset, TOP_CharStrings);
678
    /*
679
     * CIDFontVersion and CIDFontRevision aren't used consistently,
680
     * so we don't currently write them.  CIDFontType is always 0.
681
     */
682
747
    cff_put_int_if_ne(pcw, pfont->cidata.common.CIDCount, CIDCount_DEFAULT,
683
747
                      TOP_CIDCount);
684
    /* We don't use UIDBase. */
685
747
    cff_put_int_value(pcw, Font_offset, TOP_FDArray);
686
747
    cff_put_int_value(pcw, FDSelect_offset, TOP_FDSelect);
687
747
}
688
689
/* FDArray Index for CIDFont (offsets only) */
690
static void
691
cff_write_FDArray_offsets(cff_writer_t *pcw, uint *FDArray_offsets,
692
                          int num_fonts)
693
747
{
694
747
    int j;
695
696
747
    cff_put_Index_header(pcw, num_fonts,
697
747
                         FDArray_offsets[num_fonts] - FDArray_offsets[0]);
698
2.19k
    for (j = 1; j <= num_fonts; ++j)
699
1.45k
        put_offset(pcw, FDArray_offsets[j] - FDArray_offsets[0] + 1);
700
747
}
701
702
/* FDArray entry for CIDFont */
703
static void
704
cff_write_Top_fdarray(cff_writer_t *pcw, gs_font_base *pbfont,
705
                      uint Private_offset, uint Private_size)
706
1.81k
{
707
1.81k
    const gs_font_name *pfname = &pbfont->font_name;
708
1.81k
    gs_font_info_t info;
709
710
1.81k
    cff_get_Top_info_common(pcw, pbfont, false, &info);
711
1.81k
    cff_write_Top_common(pcw, pbfont, true, &info);
712
1.81k
    cff_put_int(pcw, Private_size);
713
1.81k
    cff_put_int_value(pcw, Private_offset, TOP_Private);
714
1.81k
    if (pfname->size == 0)
715
318
        pfname = &pbfont->key_name;
716
1.81k
    if (pfname->size) {
717
1.49k
        cff_put_string(pcw, pfname->chars, pfname->size);
718
1.49k
        cff_put_op(pcw, TOP_FontName);
719
1.49k
    }
720
1.81k
}
721
722
/* ------ Private Dict ------ */
723
724
/* Defaults are noted in comments. */
725
typedef enum {
726
    PRIVATE_BlueValues = 6, /* (deltarray) */
727
    PRIVATE_OtherBlues = 7, /* (deltarray) */
728
    PRIVATE_FamilyBlues = 8,  /* (deltarray) */
729
    PRIVATE_FamilyOtherBlues = 9, /* (deltarray) */
730
    PRIVATE_StdHW = 10,
731
    PRIVATE_StdVW = 11,
732
    PRIVATE_Subrs = 19,   /* (offset, relative to Private Dict) */
733
    PRIVATE_defaultWidthX = 20,
734
5.80k
#define defaultWidthX_DEFAULT fixed_0
735
    PRIVATE_nominalWidthX = 21,
736
5.80k
#define nominalWidthX_DEFAULT fixed_0
737
    PRIVATE_BlueScale = 41,
738
60.3k
#define BlueScale_DEFAULT 0.039625
739
    PRIVATE_BlueShift = 42,
740
60.3k
#define BlueShift_DEFAULT 7
741
    PRIVATE_BlueFuzz = 43,
742
60.3k
#define BlueFuzz_DEFAULT 1
743
    PRIVATE_StemSnapH = 44, /* (deltarray) */
744
    PRIVATE_StemSnapV = 45, /* (deltarray) */
745
    PRIVATE_ForceBold = 46,
746
60.3k
#define ForceBold_DEFAULT false
747
    PRIVATE_ForceBoldThreshold = 47,
748
#define ForceBoldThreshold_DEFAULT 0
749
    PRIVATE_lenIV = 48,
750
0
#define lenIV_DEFAULT (-1)
751
    PRIVATE_LanguageGroup = 49,
752
60.3k
#define LanguageGroup_DEFAULT 0
753
    PRIVATE_ExpansionFactor = 50,
754
60.3k
#define ExpansionFactor_DEFAULT 0.06
755
    PRIVATE_initialRandomSeed = 51
756
5.80k
#define initialRandomSeed_DEFAULT 0
757
} Private_op;
758
759
const long default_defaultWidthX = defaultWidthX_DEFAULT; /* For gdevpsfx.c */
760
761
static void
762
cff_write_Private(cff_writer_t *pcw, uint Subrs_offset,
763
                  const gs_font_type1 *pfont)
764
60.3k
{
765
60.3k
#define PUT_FLOAT_TABLE(member, op)\
766
362k
    cff_put_real_deltarray(pcw, pfont->data.member.values,\
767
362k
                           pfont->data.member.count, op)
768
769
60.3k
    PUT_FLOAT_TABLE(BlueValues, PRIVATE_BlueValues);
770
60.3k
    PUT_FLOAT_TABLE(OtherBlues, PRIVATE_OtherBlues);
771
60.3k
    PUT_FLOAT_TABLE(FamilyBlues, PRIVATE_FamilyBlues);
772
60.3k
    PUT_FLOAT_TABLE(FamilyOtherBlues, PRIVATE_FamilyOtherBlues);
773
60.3k
    if (pfont->data.StdHW.count > 0)
774
57.4k
        cff_put_real_value(pcw, pfont->data.StdHW.values[0], PRIVATE_StdHW);
775
60.3k
    if (pfont->data.StdVW.count > 0)
776
57.5k
        cff_put_real_value(pcw, pfont->data.StdVW.values[0], PRIVATE_StdVW);
777
60.3k
    if (Subrs_offset)
778
160
        cff_put_int_value(pcw, Subrs_offset, PRIVATE_Subrs);
779
60.3k
    if (pfont->FontType != ft_encrypted) {
780
5.80k
        if (pfont->data.defaultWidthX != defaultWidthX_DEFAULT)
781
3.04k
            cff_put_real_value(pcw, fixed2float(pfont->data.defaultWidthX),
782
3.04k
                               PRIVATE_defaultWidthX);
783
5.80k
        if (pfont->data.nominalWidthX != nominalWidthX_DEFAULT)
784
2.54k
            cff_put_real_value(pcw, fixed2float(pfont->data.nominalWidthX),
785
2.54k
                               PRIVATE_nominalWidthX);
786
5.80k
        cff_put_int_if_ne(pcw, pfont->data.initialRandomSeed,
787
5.80k
                          initialRandomSeed_DEFAULT,
788
5.80k
                          PRIVATE_initialRandomSeed);
789
5.80k
    }
790
60.3k
    cff_put_real_if_ne(pcw, pfont->data.BlueScale, BlueScale_DEFAULT,
791
60.3k
                       PRIVATE_BlueScale);
792
60.3k
    cff_put_real_if_ne(pcw, pfont->data.BlueShift, BlueShift_DEFAULT,
793
60.3k
                       PRIVATE_BlueShift);
794
60.3k
    cff_put_int_if_ne(pcw, pfont->data.BlueFuzz, BlueFuzz_DEFAULT,
795
60.3k
                      PRIVATE_BlueFuzz);
796
60.3k
    PUT_FLOAT_TABLE(StemSnapH, PRIVATE_StemSnapH);
797
60.3k
    PUT_FLOAT_TABLE(StemSnapV, PRIVATE_StemSnapV);
798
60.3k
    if (pfont->data.ForceBold != ForceBold_DEFAULT)
799
1.44k
        cff_put_bool_value(pcw, pfont->data.ForceBold,
800
1.44k
                           PRIVATE_ForceBold);
801
    /* (ForceBoldThreshold) */
802
60.3k
    if (!(pcw->options & WRITE_TYPE2_NO_LENIV))
803
0
        cff_put_int_if_ne(pcw, pfont->data.lenIV, lenIV_DEFAULT,
804
0
                          PRIVATE_lenIV);
805
60.3k
    cff_put_int_if_ne(pcw, pfont->data.LanguageGroup, LanguageGroup_DEFAULT,
806
60.3k
                      PRIVATE_LanguageGroup);
807
60.3k
    cff_put_real_if_ne(pcw, pfont->data.ExpansionFactor,
808
60.3k
                       ExpansionFactor_DEFAULT, PRIVATE_ExpansionFactor);
809
    /* initialRandomSeed was handled above */
810
811
60.3k
#undef PUT_FLOAT_TABLE
812
60.3k
}
813
814
/* ------ CharStrings Index ------ */
815
816
/* These are separate procedures only for readability. */
817
static int
818
cff_write_CharStrings_offsets(cff_writer_t *pcw, psf_glyph_enum_t *penum,
819
                              uint *pcount)
820
74.6k
{
821
74.6k
    gs_font_base *pfont = pcw->pfont;
822
74.6k
    int offset;
823
74.6k
    gs_glyph glyph;
824
74.6k
    uint count;
825
74.6k
    stream poss;
826
74.6k
    int code;
827
828
74.6k
    s_init(&poss, NULL);
829
74.6k
    psf_enumerate_glyphs_reset(penum);
830
74.6k
    for (glyph = GS_NO_GLYPH, count = 0, offset = 1;
831
1.46M
         (code = psf_enumerate_glyphs_next(penum, &glyph)) != 1;
832
1.39M
         ) {
833
1.39M
        gs_glyph_data_t gdata;
834
1.39M
        gs_font_type1 *pfd;
835
1.39M
        int gcode;
836
837
1.39M
        gdata.memory = pfont->memory;
838
1.39M
        if (code == 0 &&
839
1.39M
            (gcode = pcw->glyph_data(pfont, glyph, &gdata, &pfd)) >= 0
840
1.39M
            ) {
841
1.39M
            int extra_lenIV;
842
843
1.39M
            if (gdata.bits.size >= (extra_lenIV = cff_extra_lenIV(pcw, pfd))) {
844
1.39M
                if (cff_convert_charstrings(pcw, (gs_font_base *)pfd)) {
845
1.29M
                    swrite_position_only(&poss);
846
1.29M
                    code = psf_convert_type1_to_type2(&poss, &gdata, pfd);
847
1.29M
                    if (code < 0)
848
99
                        return code;
849
1.29M
                    offset += stell(&poss);
850
1.29M
                } else
851
101k
                    offset += gdata.bits.size - extra_lenIV;
852
1.39M
            }
853
1.39M
            gs_glyph_data_free(&gdata, "cff_write_CharStrings_offsets");
854
1.39M
            put_offset(pcw, offset);
855
1.39M
            count++;
856
1.39M
        }
857
1.39M
    }
858
74.5k
    *pcount = count;
859
74.5k
    return offset - 1;
860
74.6k
}
861
static void
862
cff_write_CharStrings(cff_writer_t *pcw, psf_glyph_enum_t *penum,
863
                      uint charstrings_count, uint charstrings_size)
864
59.6k
{
865
59.6k
    gs_font_base *pfont = pcw->pfont;
866
59.6k
    uint ignore_count;
867
59.6k
    gs_glyph glyph;
868
59.6k
    int code;
869
870
59.6k
    cff_put_Index_header(pcw, charstrings_count, charstrings_size);
871
59.6k
    cff_write_CharStrings_offsets(pcw, penum, &ignore_count);
872
59.6k
    psf_enumerate_glyphs_reset(penum);
873
59.6k
    for (glyph = GS_NO_GLYPH;
874
1.17M
         (code = psf_enumerate_glyphs_next(penum, &glyph)) != 1;
875
1.11M
         ) {
876
1.11M
        gs_glyph_data_t gdata;
877
1.11M
        gs_font_type1 *pfd;
878
879
1.11M
        gdata.memory = pfont->memory;
880
1.11M
        if (code == 0 &&
881
1.11M
            (code = pcw->glyph_data(pfont, glyph, &gdata, &pfd)) >= 0
882
1.11M
            ) {
883
1.11M
            cff_put_CharString(pcw, gdata.bits.data, gdata.bits.size, pfd);
884
1.11M
            gs_glyph_data_free(&gdata, "cff_write_CharStrings");
885
1.11M
        }
886
1.11M
    }
887
59.6k
}
888
889
/* ------ [G]Subrs Index ------ */
890
891
/*
892
 * Currently, we always write all the Subrs, even for subsets.
893
 * We will fix this someday.
894
 */
895
896
static uint
897
cff_write_Subrs_offsets(cff_writer_t *pcw, uint *pcount, gs_font_type1 *pfont,
898
                        bool global)
899
2.99k
{
900
2.99k
    int extra_lenIV = cff_extra_lenIV(pcw, pfont);
901
2.99k
    int j, offset;
902
2.99k
    int code;
903
2.99k
    gs_glyph_data_t gdata;
904
905
2.99k
    gdata.memory = pfont->memory;
906
2.99k
    for (j = 0, offset = 1;
907
134k
         (code = pfont->data.procs.subr_data(pfont, j, global, &gdata)) !=
908
134k
             gs_error_rangecheck;
909
131k
         ++j) {
910
131k
        if (code >= 0 && gdata.bits.size >= extra_lenIV)
911
131k
            offset += gdata.bits.size - extra_lenIV;
912
131k
        put_offset(pcw, offset);
913
131k
        if (code >= 0)
914
131k
            gs_glyph_data_free(&gdata, "cff_write_Subrs_offsets");
915
131k
    }
916
2.99k
    *pcount = j;
917
2.99k
    return offset - 1;
918
2.99k
}
919
920
static void
921
cff_write_Subrs(cff_writer_t *pcw, uint subrs_count, uint subrs_size,
922
                gs_font_type1 *pfont, bool global)
923
316
{
924
316
    int j;
925
316
    uint ignore_count;
926
316
    gs_glyph_data_t gdata;
927
316
    int code;
928
929
316
    gdata.memory = pfont->memory;
930
316
    cff_put_Index_header(pcw, subrs_count, subrs_size);
931
316
    cff_write_Subrs_offsets(pcw, &ignore_count, pfont, global);
932
316
    for (j = 0;
933
105k
         (code = pfont->data.procs.subr_data(pfont, j, global, &gdata)) !=
934
105k
             gs_error_rangecheck;
935
105k
         ++j) {
936
105k
        if (code >= 0) {
937
105k
            cff_put_CharString(pcw, gdata.bits.data, gdata.bits.size, pfont);
938
105k
            gs_glyph_data_free(&gdata, "cff_write_Subrs");
939
105k
        }
940
105k
    }
941
316
}
942
943
/* ------ Encoding/charset ------ */
944
945
static uint
946
cff_Encoding_size(cff_writer_t *pcw, cff_glyph_subset_t *pgsub)
947
14.7k
{
948
14.7k
    int j, code, max_enc = 0, nsupp = 0;
949
14.7k
    gs_font_type1 *pfont = (gs_font_type1 *)pcw->pfont;
950
14.7k
    byte used[255];
951
14.7k
    gs_const_string str;
952
953
14.7k
    memset(used, 0, 255);
954
3.79M
    for (j = 0; j < 256; ++j) {
955
3.78M
        gs_glyph glyph = pfont->procs.encode_char((gs_font *)pfont,
956
3.78M
                                                  (gs_char)j,
957
3.78M
                                                  GLYPH_SPACE_NAME);
958
3.78M
        int i;
959
960
3.78M
        if (glyph == GS_NO_GLYPH || glyph == pgsub->glyphs.notdef)
961
3.52M
            continue;
962
262k
        i = psf_sorted_glyphs_index_of(pgsub->glyphs.subset_data + 1,
963
262k
                                       pgsub->num_encoded, glyph);
964
262k
        if (i < 0)
965
0
            continue;   /* encoded but not in subset */
966
262k
        code = pcw->pfont->procs.glyph_name((gs_font *)pcw->pfont, glyph, &str);
967
262k
        if (code < 0)
968
0
            continue;
969
262k
        if (i >= sizeof(used) || used[i])
970
53
            nsupp++;
971
262k
        else {
972
262k
            used[i] = 1;
973
262k
            if (i > max_enc)
974
41.6k
                max_enc = i;
975
262k
        }
976
262k
    }
977
14.7k
    return 2 + (max_enc+1) + (3 * nsupp) + (nsupp > 0 ? 1 : 0);
978
14.7k
}
979
980
static int
981
cff_write_Encoding(cff_writer_t *pcw, cff_glyph_subset_t *pgsub)
982
58.9k
{
983
58.9k
    stream *s = pcw->strm;
984
    /* This procedure is only used for Type 1 / Type 2 fonts. */
985
58.9k
    gs_font_type1 *pfont = (gs_font_type1 *)pcw->pfont;
986
58.9k
    byte used[255], index[255], supplement[256];
987
58.9k
    int num_enc = min(pgsub->num_encoded, sizeof(index));
988
58.9k
    int nsupp = 0;
989
58.9k
    int j, code;
990
58.9k
    int max_enc = 0;
991
58.9k
    gs_const_string str;
992
993
58.9k
    memset(used, 0, num_enc);
994
58.9k
    memset(index, 0, sizeof(index));
995
15.1M
    for (j = 0; j < 256; ++j) {
996
15.0M
        gs_glyph glyph = pfont->procs.encode_char((gs_font *)pfont,
997
15.0M
                                                  (gs_char)j,
998
15.0M
                                                  GLYPH_SPACE_NAME);
999
15.0M
        int i;
1000
1001
15.0M
        if (glyph == GS_NO_GLYPH || glyph == pgsub->glyphs.notdef)
1002
14.0M
            continue;
1003
1.04M
        i = psf_sorted_glyphs_index_of(pgsub->glyphs.subset_data + 1,
1004
1.04M
                                       pgsub->num_encoded, glyph);
1005
1.04M
        if (i < 0)
1006
0
            continue;   /* encoded but not in subset */
1007
1.04M
        code = pcw->pfont->procs.glyph_name((gs_font *)pcw->pfont, glyph, &str);
1008
1.04M
        if (code < 0)
1009
0
            continue;
1010
1.04M
        if (i >= sizeof(used) || used[i])
1011
212
            supplement[nsupp++] = j;
1012
1.04M
        else {
1013
1.04M
            index[i] = j;
1014
1.04M
            used[i] = 1;
1015
1.04M
            if (i > max_enc)
1016
165k
                max_enc = i;
1017
1.04M
        }
1018
1.04M
    }
1019
58.9k
    sputc(s, (byte)(nsupp ? 0x80 : 0));
1020
58.9k
    sputc(s, (byte)max_enc+1);
1021
#ifdef DEBUG
1022
    { int num_enc_chars = pgsub->num_encoded_chars;
1023
1024
        if (nsupp != num_enc_chars - num_enc)
1025
            lprintf3("nsupp = %d, num_enc_chars = %d, num_enc = %d\n",
1026
                     nsupp, num_enc_chars, num_enc);
1027
        for (j = 0; j < num_enc; ++j)
1028
            if (!used[j])
1029
                lprintf2("glyph %d = 0x%lx not used\n", j,
1030
                         pgsub->glyphs.subset_data[j + 1]);
1031
    }
1032
#endif
1033
58.9k
    put_bytes(s, index, max_enc+1);
1034
58.9k
    if (nsupp) {
1035
        /* Write supplementary entries for multiply-encoded glyphs. */
1036
64
        sputc(s, (byte)nsupp);
1037
276
        for (j = 0; j < nsupp; ++j) {
1038
212
            byte chr = supplement[j];
1039
1040
212
            sputc(s, chr);
1041
212
            put_card16(pcw,
1042
212
                cff_glyph_sid(pcw,
1043
212
                              pfont->procs.encode_char((gs_font *)pfont,
1044
212
                                                       (gs_char)chr,
1045
212
                                                       GLYPH_SPACE_NAME)));
1046
212
        }
1047
64
    }
1048
58.9k
    return 0;
1049
58.9k
}
1050
1051
static int
1052
cff_write_charset(cff_writer_t *pcw, cff_glyph_subset_t *pgsub)
1053
58.9k
{
1054
58.9k
    int j, code;
1055
1056
58.9k
    sputc(pcw->strm, 0);
1057
1.10M
    for (j = 1; j < pgsub->glyphs.subset_size; j++) {
1058
1.04M
        code = cff_glyph_sid(pcw, pgsub->glyphs.subset_data[j]);
1059
1.04M
        if (code < 0)
1060
0
            continue;
1061
1.04M
        put_card16(pcw, code);
1062
1.04M
    }
1063
58.9k
    return 0;
1064
58.9k
}
1065
static int
1066
cff_write_cidset(cff_writer_t *pcw, psf_glyph_enum_t *penum)
1067
933
{
1068
933
    gs_glyph glyph;
1069
933
    int code;
1070
1071
933
    sputc(pcw->strm, 0);
1072
933
    psf_enumerate_glyphs_reset(penum);
1073
11.6k
    while ((code = psf_enumerate_glyphs_next(penum, &glyph)) == 0) {
1074
        /* Skip glyph 0 (the .notdef glyph), which is always first. */
1075
10.7k
        if (glyph != GS_MIN_CID_GLYPH)
1076
9.79k
            put_card16(pcw, (uint)(glyph - GS_MIN_CID_GLYPH));
1077
10.7k
    }
1078
933
    return min(code, 0);
1079
933
}
1080
1081
/* ------ FDSelect ------ */
1082
1083
/* Determine the size of FDSelect. */
1084
static uint
1085
cff_FDSelect_size(cff_writer_t *pcw, psf_glyph_enum_t *penum, uint *pformat)
1086
186
{
1087
186
    gs_font_cid0 *const pfont = (gs_font_cid0 *)pcw->pfont;
1088
186
    gs_font_base *const pbfont = (gs_font_base *)pfont;
1089
186
    gs_glyph glyph;
1090
186
    int prev = -1;
1091
186
    uint linear_size = 1, range_size = 5;
1092
186
    int code;
1093
1094
    /* Determine whether format 0 or 3 is more efficient. */
1095
186
    psf_enumerate_glyphs_reset(penum);
1096
2.32k
    while ((code = psf_enumerate_glyphs_next(penum, &glyph)) == 0) {
1097
2.14k
        int font_index;
1098
1099
2.14k
        code = pfont->cidata.glyph_data(pbfont, glyph, NULL, &font_index);
1100
2.14k
        if (code >= 0) {
1101
2.14k
            if (font_index != prev)
1102
275
                range_size += 3, prev = font_index;
1103
2.14k
            ++linear_size;
1104
2.14k
        }
1105
2.14k
    }
1106
186
    if (range_size < linear_size) {
1107
94
        *pformat = 3;
1108
94
        return range_size;
1109
94
    } else {
1110
92
        *pformat = 0;
1111
92
        return linear_size;
1112
92
    }
1113
186
}
1114
1115
/* Write FDSelect.  size and format were returned by cff_FDSelect_size. */
1116
static int
1117
cff_write_FDSelect(cff_writer_t *pcw, psf_glyph_enum_t *penum, uint size,
1118
                   int format)
1119
747
{
1120
747
    stream *s = pcw->strm;
1121
747
    gs_font_cid0 *const pfont = (gs_font_cid0 *)pcw->pfont;
1122
747
    gs_font_base *const pbfont = (gs_font_base *)pfont;
1123
747
    gs_glyph glyph;
1124
747
    int prev = -1;
1125
747
    uint cid_count = 0;
1126
747
    int code;
1127
1128
747
    spputc(s, (byte)format);
1129
747
    psf_enumerate_glyphs_reset(penum);
1130
747
    switch (format) {
1131
377
    case 3:     /* ranges */
1132
377
        put_card16(pcw, (size - 5) / 3);
1133
7.79k
        while ((code = psf_enumerate_glyphs_next(penum, &glyph)) == 0) {
1134
7.41k
            int font_index;
1135
1136
7.41k
            code = pfont->cidata.glyph_data(pbfont, glyph, NULL, &font_index);
1137
7.41k
            if (code >= 0) {
1138
7.41k
                if (font_index != prev) {
1139
681
                    put_card16(pcw, cid_count);
1140
681
                    sputc(s, (byte)font_index);
1141
681
                    prev = font_index;
1142
681
                }
1143
7.41k
                ++cid_count;
1144
7.41k
            }
1145
7.41k
        }
1146
377
        put_card16(pcw, cid_count);
1147
377
        break;
1148
370
    case 0:     /* linear table */
1149
1.54k
        while ((code = psf_enumerate_glyphs_next(penum, &glyph)) == 0) {
1150
1.17k
            int font_index;
1151
1152
1.17k
            code = pfont->cidata.glyph_data(pbfont, glyph, NULL, &font_index);
1153
1.17k
            if (code >= 0)
1154
1.17k
                sputc(s, (byte)font_index);
1155
1.17k
        }
1156
370
        break;
1157
0
    default:      /* not possible */
1158
0
        return_error(gs_error_rangecheck);
1159
747
    }
1160
747
    return 0;
1161
747
}
1162
1163
/* ------ Main procedure ------ */
1164
1165
/* Write the CFF definition of a Type 1 or Type 2 font. */
1166
int
1167
psf_write_type2_font(stream *s, gs_font_type1 *pfont, int options,
1168
                      gs_glyph *subset_glyphs, uint subset_size,
1169
                      const gs_const_string *alt_font_name,
1170
                      gs_int_rect *FontBBox)
1171
14.7k
{
1172
14.7k
    gs_font_base *const pbfont = (gs_font_base *)pfont;
1173
14.7k
    cff_writer_t writer;
1174
14.7k
    cff_glyph_subset_t subset;
1175
14.7k
    cff_string_item_t *std_string_items;
1176
14.7k
    cff_string_item_t *string_items;
1177
14.7k
    gs_const_string font_name;
1178
14.7k
    stream poss;
1179
14.7k
    uint charstrings_count, charstrings_size;
1180
14.7k
    uint subrs_count, subrs_size;
1181
14.7k
    uint gsubrs_count, gsubrs_size, encoding_size;
1182
14.7k
    int charset_size = -1;
1183
14.7k
    uint number_of_glyphs = 0, number_of_strings;
1184
    /*
1185
     * Set the offsets and sizes to the largest reasonable values
1186
     * (see below).
1187
     */
1188
14.7k
    uint
1189
14.7k
        Top_size = 0x7fffff,
1190
14.7k
        GSubrs_offset,
1191
14.7k
        Encoding_offset,
1192
14.7k
        charset_offset,
1193
14.7k
        CharStrings_offset,
1194
14.7k
        Private_offset,
1195
14.7k
        Private_size = 0x7fffff,
1196
14.7k
        Subrs_offset,
1197
14.7k
        End_offset = 0x7fffff;
1198
14.7k
    int j;
1199
14.7k
    psf_glyph_enum_t genum;
1200
14.7k
    gs_glyph glyph;
1201
14.7k
    long start_pos;
1202
14.7k
    uint offset;
1203
14.7k
    int code;
1204
1205
    /* Allocate the string tables. */
1206
14.7k
    psf_enumerate_glyphs_begin(&genum, (gs_font *)pfont,
1207
14.7k
                               NULL, 0, GLYPH_SPACE_NAME);
1208
292k
    while ((code = psf_enumerate_glyphs_next(&genum, &glyph)) != 1)
1209
277k
        number_of_glyphs++;
1210
14.7k
    subset.glyphs.subset_data = (gs_glyph *)gs_alloc_bytes(pfont->memory,
1211
14.7k
                    (size_t)number_of_glyphs * sizeof(glyph), "psf_write_type2_font");
1212
14.7k
    number_of_strings = number_of_glyphs + MAX_CFF_MISC_STRINGS;
1213
14.7k
    std_string_items = (cff_string_item_t *)gs_alloc_bytes(pfont->memory,
1214
14.7k
                    (MAX_CFF_STD_STRINGS + number_of_strings) * (size_t)sizeof(cff_string_item_t),
1215
14.7k
                    "psf_write_type2_font");
1216
14.7k
    if (std_string_items == NULL || subset.glyphs.subset_data == NULL) {
1217
0
        code = gs_note_error(gs_error_VMerror);
1218
0
        goto error;
1219
0
    }
1220
14.7k
    string_items = std_string_items + MAX_CFF_STD_STRINGS;
1221
1222
    /* Get subset glyphs. */
1223
14.7k
    code = psf_get_type1_glyphs(&subset.glyphs, pfont, subset_glyphs,
1224
14.7k
                              subset_size);
1225
14.7k
    if (code < 0)
1226
0
        goto error;
1227
14.7k
    if (subset.glyphs.notdef == GS_NO_GLYPH) {
1228
0
        code = gs_note_error(gs_error_rangecheck); /* notdef is required */
1229
0
        goto error;
1230
0
    }
1231
1232
    /* If we're writing Type 2 CharStrings, don't encrypt them. */
1233
14.7k
    if (options & WRITE_TYPE2_CHARSTRINGS) {
1234
14.7k
        options |= WRITE_TYPE2_NO_LENIV;
1235
14.7k
        if (pfont->FontType != ft_encrypted2)
1236
13.7k
            pfont->data.defaultWidthX = pfont->data.nominalWidthX = 0;
1237
14.7k
    }
1238
14.7k
    writer.options = options;
1239
14.7k
    s_init(&poss, NULL);
1240
14.7k
    swrite_position_only(&poss);
1241
14.7k
    writer.strm = &poss;
1242
14.7k
    writer.pfont = pbfont;
1243
14.7k
    writer.glyph_data = psf_type1_glyph_data;
1244
14.7k
    writer.offset_size = 1; /* arbitrary */
1245
14.7k
    writer.start_pos = stell(s);
1246
14.7k
    writer.FontBBox = *FontBBox;
1247
1248
    /* Initialize the enumeration of the glyphs. */
1249
14.7k
    psf_enumerate_glyphs_begin(&genum, (gs_font *)pfont,
1250
14.7k
                                subset.glyphs.subset_glyphs,
1251
14.7k
                                (subset.glyphs.subset_glyphs ?
1252
14.7k
                                 subset.glyphs.subset_size : 0),
1253
14.7k
                                GLYPH_SPACE_NAME);
1254
1255
    /* Shuffle the glyphs into the order .notdef, encoded, unencoded. */
1256
14.7k
    {
1257
14.7k
        gs_glyph encoded[256];
1258
14.7k
        int num_enc, num_enc_chars;
1259
1260
        /* Get the list of encoded glyphs. */
1261
3.79M
        for (j = 0, num_enc_chars = 0; j < 256; ++j) {
1262
3.78M
            glyph = pfont->procs.encode_char((gs_font *)pfont, (gs_char)j,
1263
3.78M
                                             GLYPH_SPACE_NAME);
1264
3.78M
            if (glyph != GS_NO_GLYPH && glyph != subset.glyphs.notdef &&
1265
3.78M
                (subset.glyphs.subset_glyphs == 0 ||
1266
262k
                 psf_sorted_glyphs_include(subset.glyphs.subset_data,
1267
0
                                            subset.glyphs.subset_size, glyph)))
1268
262k
                encoded[num_enc_chars++] = glyph;
1269
3.78M
        }
1270
14.7k
        subset.num_encoded_chars = num_enc_chars;
1271
14.7k
        subset.num_encoded = num_enc =
1272
14.7k
            psf_sort_glyphs(encoded, num_enc_chars);
1273
1274
        /* Get the complete list of glyphs if we don't have it already. */
1275
14.7k
        if (!subset.glyphs.subset_glyphs) {
1276
14.7k
            int num_glyphs = 0;
1277
1278
14.7k
            psf_enumerate_glyphs_reset(&genum);
1279
292k
            while ((code = psf_enumerate_glyphs_next(&genum, &glyph)) != 1)
1280
277k
                if (code == 0) {
1281
277k
                    if (num_glyphs == number_of_glyphs){
1282
0
                        code = gs_note_error(gs_error_limitcheck);
1283
0
                        goto error;
1284
0
                    }
1285
277k
                    subset.glyphs.subset_data[num_glyphs++] = glyph;
1286
277k
                }
1287
14.7k
            subset.glyphs.subset_size =
1288
14.7k
                psf_sort_glyphs(subset.glyphs.subset_data, num_glyphs);
1289
14.7k
            subset.glyphs.subset_glyphs = subset.glyphs.subset_data;
1290
14.7k
        }
1291
1292
        /* Move the unencoded glyphs to the top of the list. */
1293
        /*
1294
         * We could do this in time N rather than N log N with a two-finger
1295
         * algorithm, but it doesn't seem worth the trouble right now.
1296
         */
1297
14.7k
        {
1298
14.7k
            int from = subset.glyphs.subset_size;
1299
14.7k
            int to = from;
1300
1301
292k
            while (from > 0) {
1302
277k
                glyph = subset.glyphs.subset_data[--from];
1303
277k
                if (glyph != subset.glyphs.notdef &&
1304
277k
                    !psf_sorted_glyphs_include(encoded, num_enc, glyph))
1305
14
                    subset.glyphs.subset_data[--to] = glyph;
1306
277k
            }
1307
#ifdef DEBUG
1308
            if (to != num_enc + 1)
1309
                lprintf2("to = %d, num_enc + 1 = %d\n", to, num_enc + 1);
1310
#endif
1311
14.7k
        }
1312
1313
        /* Move .notdef and the encoded glyphs to the bottom of the list. */
1314
14.7k
        subset.glyphs.subset_data[0] = subset.glyphs.notdef;
1315
14.7k
        memcpy(subset.glyphs.subset_data + 1, encoded,
1316
14.7k
               sizeof(encoded[0]) * num_enc);
1317
14.7k
    }
1318
1319
    /* Set the font name. */
1320
14.7k
    if (alt_font_name)
1321
14.7k
        font_name = *alt_font_name;
1322
0
    else
1323
0
        font_name.data = pfont->font_name.chars,
1324
0
            font_name.size = pfont->font_name.size;
1325
1326
    /* Initialize the string tables. */
1327
14.7k
    cff_string_table_init(&writer.std_strings, std_string_items,
1328
14.7k
                          MAX_CFF_STD_STRINGS);
1329
5.79M
    for (j = 0; (glyph = gs_c_known_encode((gs_char)j,
1330
5.79M
                                ENCODING_INDEX_CFFSTRINGS)) != GS_NO_GLYPH;
1331
5.77M
         ++j) {
1332
5.77M
        gs_const_string str;
1333
5.77M
        int ignore;
1334
1335
5.77M
        gs_c_glyph_name(glyph, &str);
1336
5.77M
        cff_string_index(&writer.std_strings, str.data, str.size, true,
1337
5.77M
                         &ignore);
1338
5.77M
    }
1339
14.7k
    cff_string_table_init(&writer.strings, string_items, number_of_strings);
1340
1341
    /* Enter miscellaneous strings in the string table. */
1342
14.7k
    cff_write_Top_font(&writer, 0, 0, 0, 0, 0);
1343
1344
    /* Enter the glyph names in the string table. */
1345
    /* (Note that we have changed the glyph list.) */
1346
14.7k
    psf_enumerate_glyphs_begin(&genum, (gs_font *)pfont,
1347
14.7k
                               subset.glyphs.subset_data,
1348
14.7k
                               subset.glyphs.subset_size,
1349
14.7k
                               GLYPH_SPACE_NAME);
1350
292k
    while ((code = psf_enumerate_glyphs_next(&genum, &glyph)) != 1)
1351
277k
        if (code == 0) {
1352
277k
            code = cff_glyph_sid(&writer, glyph);
1353
277k
            if (code == gs_error_undefined)
1354
0
                continue;
1355
277k
            if (code < 0)
1356
0
                goto error;
1357
277k
            charset_size += 2;
1358
277k
        }
1359
1360
    /*
1361
     * The CFF specification says that the Encoding, charset, CharStrings,
1362
     * Private, and Local Subr sections may be in any order.  To minimize
1363
     * the risk of incompatibility with Adobe software, we produce them in
1364
     * the order just mentioned.
1365
     */
1366
1367
    /*
1368
     * Compute the size of the GSubrs Index, if not omitted.
1369
     */
1370
14.7k
    if ((options & WRITE_TYPE2_NO_GSUBRS) != 0 ||
1371
14.7k
        cff_convert_charstrings(&writer, pbfont) /* we expand all Subrs */
1372
14.7k
        )
1373
13.7k
        gsubrs_count = 0, gsubrs_size = 0;
1374
1.06k
    else
1375
1.06k
        gsubrs_size = cff_write_Subrs_offsets(&writer, &gsubrs_count,
1376
1.06k
                                              pfont, true);
1377
1378
    /*
1379
     * Compute the size of the Encoding.  For simplicity, we currently
1380
     * always store the Encoding explicitly.  Note that because CFF stores
1381
     * the Encoding in an "inverted" form, we need to count the number of
1382
     * glyphs that occur at more than one place in the Encoding.
1383
     */
1384
14.7k
    encoding_size = cff_Encoding_size(&writer, &subset);
1385
1386
    /* Compute the size of the CharStrings Index. */
1387
14.7k
    code = cff_write_CharStrings_offsets(&writer, &genum, &charstrings_count);
1388
14.7k
    if (code < 0)
1389
99
        goto error;
1390
14.6k
    charstrings_size = (uint)code;
1391
1392
    /* Compute the size of the (local) Subrs Index. */
1393
14.6k
#ifdef SKIP_EMPTY_SUBRS
1394
14.6k
    subrs_size =
1395
14.6k
        (cff_convert_charstrings(&writer, pbfont) ? 0 :
1396
14.6k
         cff_write_Subrs_offsets(&writer, &subrs_count, pfont, false));
1397
#else
1398
    if (cff_convert_charstrings(&writer, pbfont))
1399
        subrs_count = 0;  /* we expand all Subrs */
1400
    subrs_size = cff_write_Subrs_offsets(&writer, &subrs_count, pfont, false);
1401
#endif
1402
1403
    /*
1404
     * The offsets of the Private Dict and the CharStrings Index
1405
     * depend on the size of the Top Dict; the offset of the Subrs also
1406
     * depends on the size of the Private Dict.  However, the size of the
1407
     * Top Dict depends on the offsets of the CharStrings Index, the
1408
     * charset, and the Encoding, and on the offset and size of the Private
1409
     * Dict, because of the variable-length encoding of the offsets and
1410
     * size; for the same reason, the size of the Private Dict depends on
1411
     * the offset of the Subrs.  Fortunately, the relationship between the
1412
     * value of an offset or size and the size of its encoding is monotonic.
1413
     * Therefore, we start by assuming the largest reasonable value for all
1414
     * the sizes and iterate until everything converges.
1415
     */
1416
44.2k
 iter:
1417
44.2k
    swrite_position_only(&poss);
1418
44.2k
    writer.strm = &poss;
1419
1420
    /* Compute the offsets. */
1421
44.2k
    GSubrs_offset = 4 + cff_Index_size(1, font_name.size) +
1422
44.2k
        cff_Index_size(1, Top_size) +
1423
44.2k
        cff_Index_size(writer.strings.count, writer.strings.total);
1424
44.2k
    Encoding_offset = GSubrs_offset +
1425
44.2k
        cff_Index_size(gsubrs_count, gsubrs_size);
1426
44.2k
    charset_offset = Encoding_offset + encoding_size;
1427
44.2k
    CharStrings_offset = charset_offset + charset_size;
1428
44.2k
    Private_offset = CharStrings_offset +
1429
44.2k
        cff_Index_size(charstrings_count, charstrings_size);
1430
44.2k
    Subrs_offset = Private_size;  /* relative to Private Dict */
1431
1432
58.9k
 write:
1433
58.9k
    if(check_ioerror(writer.strm)) {
1434
0
        code = gs_note_error(gs_error_ioerror);
1435
0
        goto error;
1436
0
    }
1437
58.9k
    start_pos = stell(writer.strm);
1438
    /* Write the header, setting offset_size. */
1439
58.9k
    cff_write_header(&writer, End_offset);
1440
1441
    /* Write the names Index. */
1442
58.9k
    cff_put_Index_header(&writer, 1, font_name.size);
1443
58.9k
    put_offset(&writer, font_name.size + 1);
1444
58.9k
    put_bytes(writer.strm, font_name.data, font_name.size);
1445
1446
    /* Write the Top Index. */
1447
58.9k
    cff_put_Index_header(&writer, 1, Top_size);
1448
58.9k
    put_offset(&writer, Top_size + 1);
1449
58.9k
    offset = stell(writer.strm) - start_pos;
1450
58.9k
    cff_write_Top_font(&writer, Encoding_offset, charset_offset,
1451
58.9k
                       CharStrings_offset,
1452
58.9k
                       Private_offset, Private_size);
1453
58.9k
    Top_size = stell(writer.strm) - start_pos - offset;
1454
1455
    /* Write the strings Index. */
1456
58.9k
    cff_put_Index(&writer, &writer.strings);
1457
58.9k
    if(check_ioerror(writer.strm)){
1458
0
        code = gs_note_error(gs_error_ioerror);
1459
0
        goto error;
1460
0
    }
1461
1462
    /* Write the GSubrs Index, if any, checking the offset. */
1463
58.9k
    offset = stell(writer.strm) - start_pos;
1464
58.9k
    if_debug2m('l', s->memory, "[l]GSubrs = %u => %u\n", GSubrs_offset, offset);
1465
58.9k
    if (offset > GSubrs_offset) {
1466
0
        code = gs_note_error(gs_error_rangecheck);
1467
0
        goto error;
1468
0
    }
1469
58.9k
    GSubrs_offset = offset;
1470
58.9k
    if (gsubrs_count == 0 || cff_convert_charstrings(&writer, pbfont))
1471
58.8k
        cff_put_Index_header(&writer, 0, 0);
1472
92
    else
1473
92
        cff_write_Subrs(&writer, gsubrs_count, gsubrs_size, pfont, true);
1474
1475
    /* Write the Encoding. */
1476
58.9k
    cff_write_Encoding(&writer, &subset);
1477
1478
    /* Write the charset. */
1479
58.9k
    cff_write_charset(&writer, &subset);
1480
1481
    /* Write the CharStrings Index, checking the offset. */
1482
58.9k
    offset = stell(writer.strm) - start_pos;
1483
58.9k
    if (offset > CharStrings_offset) {
1484
0
        code = gs_note_error(gs_error_rangecheck);
1485
0
        goto error;
1486
0
    }
1487
58.9k
    CharStrings_offset = offset;
1488
58.9k
    cff_write_CharStrings(&writer, &genum, charstrings_count,
1489
58.9k
                          charstrings_size);
1490
58.9k
    if(check_ioerror(writer.strm)) {
1491
0
        code = gs_note_error(gs_error_ioerror);
1492
0
        goto error;
1493
0
    }
1494
1495
    /* Write the Private Dict, checking the offset. */
1496
58.9k
    offset = stell(writer.strm) - start_pos;
1497
58.9k
    if (offset > Private_offset) {
1498
0
        code = gs_note_error(gs_error_rangecheck);
1499
0
        goto error;
1500
0
    }
1501
58.9k
    Private_offset = offset;
1502
58.9k
    cff_write_Private(&writer, (subrs_size == 0 ? 0 : Subrs_offset), pfont);
1503
58.9k
    Private_size = stell(writer.strm) - start_pos - offset;
1504
1505
    /* Write the Subrs Index, checking the offset. */
1506
58.9k
    offset = stell(writer.strm) - (start_pos + Private_offset);
1507
58.9k
    if (offset > Subrs_offset) {
1508
0
        code = gs_note_error(gs_error_rangecheck);
1509
0
        goto error;
1510
0
    }
1511
58.9k
    Subrs_offset = offset;
1512
58.9k
    if (cff_convert_charstrings(&writer, pbfont))
1513
54.5k
        cff_put_Index_header(&writer, 0, 0);
1514
4.35k
    else if (subrs_size != 0)
1515
64
        cff_write_Subrs(&writer, subrs_count, subrs_size, pfont, false);
1516
1517
    /* Check the final offset. */
1518
58.9k
    if(check_ioerror(writer.strm)) {
1519
0
        code = gs_note_error(gs_error_ioerror);
1520
0
        goto error;
1521
0
    }
1522
58.9k
    offset = stell(writer.strm) - start_pos;
1523
58.9k
    if (offset > End_offset) {
1524
0
        code = gs_note_error(gs_error_rangecheck);
1525
0
        goto error;
1526
0
    }
1527
58.9k
    if (offset == End_offset) {
1528
        /* The iteration has converged.  Write the result. */
1529
29.3k
        if (writer.strm == &poss) {
1530
14.6k
            writer.strm = s;
1531
14.6k
            goto write;
1532
14.6k
        }
1533
29.5k
    } else {
1534
        /* No convergence yet. */
1535
29.5k
        End_offset = offset;
1536
29.5k
        goto iter;
1537
29.5k
    }
1538
1539
    /* All done. */
1540
14.6k
    gs_free_object(pfont->memory, std_string_items, "psf_write_type2_font");
1541
14.6k
    gs_free_object(pfont->memory, subset.glyphs.subset_data, "psf_write_type2_font");
1542
14.6k
    return 0;
1543
1544
99
error:
1545
99
    gs_free_object(pfont->memory, std_string_items, "psf_write_type2_font");
1546
99
    gs_free_object(pfont->memory, subset.glyphs.subset_data, "psf_write_type2_font");
1547
99
    subset.glyphs.subset_data = NULL;
1548
99
    return code;
1549
58.9k
}
1550
1551
/* Write the CFF definition of a CIDFontType 0 font (CIDFont). */
1552
static int
1553
cid0_glyph_data(gs_font_base *pbfont, gs_glyph glyph, gs_glyph_data_t *pgd,
1554
                gs_font_type1 **ppfont)
1555
21.4k
{
1556
21.4k
    gs_font_cid0 *const pfont = (gs_font_cid0 *)pbfont;
1557
21.4k
    int font_index;
1558
21.4k
    int code = pfont->cidata.glyph_data(pbfont, glyph, pgd, &font_index);
1559
1560
21.4k
    if (code >= 0)
1561
21.4k
        *ppfont = pfont->cidata.FDArray[font_index];
1562
21.4k
    return code;
1563
21.4k
}
1564
#ifdef DEBUG
1565
static int
1566
offset_error(const char *msg)
1567
{
1568
    if_debug1('l', "[l]%s offset error\n", msg);
1569
    return_error(gs_error_rangecheck);
1570
}
1571
#else
1572
#  define offset_error(msg) gs_error_rangecheck
1573
#endif
1574
int
1575
psf_write_cid0_font(stream *s, gs_font_cid0 *pfont, int options,
1576
                    const byte *subset_cids, uint subset_size,
1577
                    const gs_const_string *alt_font_name)
1578
186
{
1579
    /*
1580
     * CIDFontType 0 fonts differ from ordinary Type 1 / Type 2 fonts
1581
     * as follows:
1582
     *   The TOP Dict starts with a ROS operator.
1583
     *   The TOP Dict must include FDArray and FDSelect operators.
1584
     *   The TOP Dict may include CIDFontVersion, CIDFontRevision,
1585
     *     CIDFontType, CIDCount, and UIDBase operators.
1586
     *   The TOP Dict must not include an Encoding operator.
1587
     *   The charset is defined in terms of CIDs rather than SIDs.
1588
     *   FDArray references a Font Index in which each element is a Dict
1589
     *     defining a font without charset, Encoding, or CharStrings.
1590
     *   FDSelect references a structure mapping CIDs to font numbers.
1591
     */
1592
186
    gs_font_base *const pbfont = (gs_font_base *)pfont;
1593
186
    cff_writer_t writer;
1594
186
    cff_string_item_t std_string_items[500]; /* 391 entries used */
1595
    /****** HOW TO DETERMINE THE SIZE OF STRINGS? ******/
1596
186
    cff_string_item_t string_items[500 /* character names */ +
1597
186
                                   40 /* misc. values */];
1598
186
    gs_const_string font_name;
1599
186
    stream poss;
1600
186
    uint charstrings_count, charstrings_size;
1601
186
    uint gsubrs_count, gsubrs_size;
1602
186
    uint charset_size, fdselect_size, fdselect_format;
1603
186
    uint subrs_count[256], subrs_size[256];
1604
    /*
1605
     * Set the offsets and sizes to the largest reasonable values
1606
     * (see below).
1607
     */
1608
186
    uint
1609
186
        Top_size = 0x7fffff,
1610
186
        GSubrs_offset = 0x1ffffff,
1611
186
        charset_offset = 0x1ffffff,
1612
186
        FDSelect_offset = 0x1ffffff,
1613
186
        CharStrings_offset = 0x1ffffff,
1614
186
        Font_offset = 0x1ffffff,
1615
186
        FDArray_offsets[257],
1616
186
        Private_offsets[257],
1617
186
        Subrs_offsets[257],
1618
186
        End_offset = 0x1ffffff;
1619
186
    int j;
1620
186
    psf_glyph_enum_t genum;
1621
186
    gs_font_info_t info;
1622
186
    long start_pos;
1623
186
    uint offset;
1624
186
    int num_fonts = pfont->cidata.FDArray_size;
1625
186
    int code;
1626
1627
186
    if (num_fonts > 256)
1628
0
        return_error(gs_error_invalidfont);
1629
1630
186
    memset(&subrs_count, 0x00, 256 * sizeof(uint));
1631
186
    memset(&subrs_size, 0x00, 256 * sizeof(uint));
1632
1633
    /* Initialize the enumeration of the glyphs. */
1634
186
    psf_enumerate_cids_begin(&genum, (gs_font *)pfont, subset_cids,
1635
186
                             subset_size);
1636
1637
    /* Check that the font can be written. */
1638
186
    code = psf_check_outline_glyphs((gs_font_base *)pfont, &genum,
1639
186
                                    cid0_glyph_data);
1640
186
    if (code < 0)
1641
0
        return code;
1642
    /* The .notdef glyph (glyph 0) must be included. */
1643
186
    if (subset_cids && subset_size > 0 && !(subset_cids[0] & 0x80))
1644
0
        return_error(gs_error_rangecheck);
1645
1646
186
    writer.options = options;
1647
186
    s_init(&poss, NULL);
1648
186
    swrite_position_only(&poss);
1649
186
    writer.strm = &poss;
1650
186
    writer.pfont = pbfont;
1651
186
    writer.glyph_data = cid0_glyph_data;
1652
186
    writer.offset_size = 1; /* arbitrary */
1653
186
    writer.start_pos = stell(s);
1654
186
    writer.FontBBox.p.x = writer.FontBBox.p.y = 0;
1655
186
    writer.FontBBox.q.x = writer.FontBBox.q.y = 0;
1656
1657
    /* Set the font name. */
1658
186
    if (alt_font_name)
1659
186
        font_name = *alt_font_name;
1660
0
    else if (pfont->font_name.size)
1661
0
        font_name.data = pfont->font_name.chars,
1662
0
            font_name.size = pfont->font_name.size;
1663
0
    else
1664
0
        font_name.data = pfont->key_name.chars,
1665
0
            font_name.size = pfont->key_name.size;
1666
1667
    /* Initialize the string tables. */
1668
186
    cff_string_table_init(&writer.std_strings, std_string_items,
1669
186
                          countof(std_string_items));
1670
186
    cff_string_table_init(&writer.strings, string_items,
1671
186
                          countof(string_items));
1672
1673
    /* Make all entries in the string table. */
1674
186
    cff_write_ROS(&writer, &pfont->cidata.common.CIDSystemInfo);
1675
548
    for (j = 0; j < num_fonts; ++j) {
1676
362
        gs_font_type1 *pfd = pfont->cidata.FDArray[j];
1677
1678
362
        cff_write_Top_fdarray(&writer, (gs_font_base *)pfd, 0, 0);
1679
362
    }
1680
1681
    /*
1682
     * The CFF specification says that sections after the initial Indexes
1683
     * may be in any order.  To minimize the risk of incompatibility with
1684
     * Adobe software, we produce them in the order illustrated in the
1685
     * specification.
1686
     */
1687
1688
    /* Initialize the offset arrays. */
1689
734
    for (j = 0; j <= num_fonts; ++j)
1690
548
        FDArray_offsets[j] = Private_offsets[j] = Subrs_offsets[j] =
1691
548
            0x7effffff / num_fonts * j + 0x1000000;
1692
1693
    /*
1694
     * Compute the size of the GSubrs Index, if not omitted.
1695
     * Arbitrarily use FDArray[0] to access the GSubrs and to determine
1696
     * the CharString type.
1697
     */
1698
186
    if ((options & WRITE_TYPE2_NO_GSUBRS) != 0 ||
1699
186
        cff_convert_charstrings(&writer,
1700
186
                        (const gs_font_base *)pfont->cidata.FDArray[0])
1701
                                /* we expand all Subrs */
1702
186
        )
1703
0
        gsubrs_count = 0, gsubrs_size = 0;
1704
186
    else
1705
186
        gsubrs_size = cff_write_Subrs_offsets(&writer, &gsubrs_count,
1706
186
                                              pfont->cidata.FDArray[0], true);
1707
1708
    /*
1709
     * Compute the size of the charset.  For simplicity, we currently
1710
     * always store the charset explicitly.
1711
     */
1712
186
    swrite_position_only(&poss);
1713
186
    cff_write_cidset(&writer, &genum);
1714
186
    charset_size = stell(&poss);
1715
1716
    /* Compute the size of the FDSelect strucure. */
1717
186
    fdselect_size = cff_FDSelect_size(&writer, &genum, &fdselect_format);
1718
1719
    /* Compute the size of the CharStrings Index. */
1720
    /* Compute the size of the CharStrings Index. */
1721
186
    code = cff_write_CharStrings_offsets(&writer, &genum, &charstrings_count);
1722
186
    if (code < 0)
1723
0
        return code;
1724
186
    charstrings_size = (uint)code;
1725
1726
    /* Compute the size of the (local) Subrs Indexes. */
1727
548
    for (j = 0; j < num_fonts; ++j) {
1728
362
        gs_font_type1 *pfd = pfont->cidata.FDArray[j];
1729
1730
362
#ifdef SKIP_EMPTY_SUBRS
1731
362
        subrs_size[j] =
1732
362
            (cff_convert_charstrings(&writer, (gs_font_base *)pfd) ? 0 :
1733
362
             cff_write_Subrs_offsets(&writer, &subrs_count[j], pfd, false));
1734
#else
1735
        if (cff_convert_charstrings(&writer, (gs_font_base *)pfd))
1736
            subrs_count[j] = 0;  /* we expand all Subrs */
1737
        subrs_size[j] = cff_write_Subrs_offsets(&writer, &subrs_count[j], pfd, false);
1738
#endif
1739
362
    }
1740
1741
    /* Get the font_info once, since it may be expensive. */
1742
186
    cff_get_Top_info_common(&writer, (gs_font_base *)pfont, true, &info);
1743
1744
    /*
1745
     * The offsets of the Private Dict and the CharStrings Index
1746
     * depend on the size of the Top Dict; the offset of the Subrs also
1747
     * depends on the size of the Private Dict.  However, the size of the
1748
     * Top Dict depends on the offsets of the CharStrings Index and the
1749
     * charset, and on the offset and size of the Private Dict,
1750
     * because of the variable-length encoding of the offsets and
1751
     * size; for the same reason, the size of the Private Dict depends on
1752
     * the offset of the Subrs.  Fortunately, the relationship between the
1753
     * value of an offset or size and the size of its encoding is monotonic.
1754
     * Therefore, we start by assuming the largest reasonable value for all
1755
     * the sizes and iterate until everything converges.
1756
     */
1757
561
 iter:
1758
561
    swrite_position_only(&poss);
1759
561
    writer.strm = &poss;
1760
1761
    /* Compute the offsets. */
1762
561
    GSubrs_offset = 4 + cff_Index_size(1, font_name.size) +
1763
561
        cff_Index_size(1, Top_size) +
1764
561
        cff_Index_size(writer.strings.count, writer.strings.total);
1765
561
    charset_offset = GSubrs_offset +
1766
561
        cff_Index_size(gsubrs_count, gsubrs_size);
1767
561
    FDSelect_offset = charset_offset + charset_size;
1768
561
    CharStrings_offset = FDSelect_offset + fdselect_size;
1769
561
    if_debug4m('l', s->memory,
1770
561
               "[l]GSubrs at %u, charset at %u, FDSelect at %u, CharStrings at %u\n",
1771
561
               GSubrs_offset, charset_offset, FDSelect_offset, CharStrings_offset);
1772
1773
747
 write:
1774
747
    start_pos = stell(writer.strm);
1775
747
    if_debug1m('l', s->memory, "[l]start_pos = %ld\n", start_pos);
1776
    /* Write the header, setting offset_size. */
1777
747
    cff_write_header(&writer, End_offset);
1778
1779
    /* Write the names Index. */
1780
747
    cff_put_Index_header(&writer, 1, font_name.size);
1781
747
    put_offset(&writer, font_name.size + 1);
1782
747
    put_bytes(writer.strm, font_name.data, font_name.size);
1783
1784
    /* Write the Top Index. */
1785
747
    cff_put_Index_header(&writer, 1, Top_size);
1786
747
    put_offset(&writer, Top_size + 1);
1787
747
    offset = stell(writer.strm) - start_pos;
1788
747
    cff_write_Top_cidfont(&writer, charset_offset, CharStrings_offset,
1789
747
                          FDSelect_offset, Font_offset, &info);
1790
747
    Top_size = stell(writer.strm) - start_pos - offset;
1791
747
    if_debug1m('l', s->memory, "[l]Top_size = %u\n", Top_size);
1792
1793
    /* Write the strings Index. */
1794
747
    cff_put_Index(&writer, &writer.strings);
1795
1796
    /* Write the GSubrs Index, if any, checking the offset. */
1797
747
    offset = stell(writer.strm) - start_pos;
1798
747
    if_debug2m('l', s->memory, "[l]GSubrs = %u => %u\n", GSubrs_offset, offset);
1799
747
    if (offset > GSubrs_offset)
1800
0
        return_error(gs_error_rangecheck);
1801
747
    GSubrs_offset = offset;
1802
747
    if (gsubrs_count == 0 ||
1803
747
        cff_convert_charstrings(&writer,
1804
64
                        (const gs_font_base *)pfont->cidata.FDArray[0])
1805
747
        )
1806
683
        cff_put_Index_header(&writer, 0, 0);
1807
64
    else
1808
64
        cff_write_Subrs(&writer, gsubrs_count, gsubrs_size,
1809
64
                        pfont->cidata.FDArray[0], true);
1810
1811
    /* Write the charset. */
1812
747
    if_debug1m('l', s->memory, "[l]charset = %"PRId64"\n", (int64_t)(stell(writer.strm) - start_pos));
1813
747
    cff_write_cidset(&writer, &genum);
1814
1815
    /* Write the FDSelect structure, checking the offset. */
1816
747
    offset = stell(writer.strm) - start_pos;
1817
747
    if_debug2m('l', s->memory, "[l]FDSelect = %u => %u\n", FDSelect_offset, offset);
1818
747
    if (offset > FDSelect_offset)
1819
0
        return_error(offset_error("FDselect"));
1820
747
    FDSelect_offset = offset;
1821
747
    cff_write_FDSelect(&writer, &genum, fdselect_size, fdselect_format);
1822
1823
    /* Write the CharStrings Index, checking the offset. */
1824
747
    offset = stell(writer.strm) - start_pos;
1825
747
    if_debug2m('l', s->memory, "[l]CharStrings = %u => %u\n", CharStrings_offset, offset);
1826
747
    if (offset > CharStrings_offset)
1827
0
        return_error(offset_error("CharStrings"));
1828
747
    CharStrings_offset = offset;
1829
747
    cff_write_CharStrings(&writer, &genum, charstrings_count,
1830
747
                          charstrings_size);
1831
1832
    /* Write the Font Dict Index. */
1833
747
    offset = stell(writer.strm) - start_pos;
1834
747
    if_debug2m('l', s->memory, "[l]Font = %u => %u\n", Font_offset, offset);
1835
747
    if (offset > Font_offset)
1836
0
        return_error(offset_error("Font"));
1837
747
    Font_offset = offset;
1838
747
    cff_write_FDArray_offsets(&writer, FDArray_offsets, num_fonts);
1839
747
    offset = stell(writer.strm) - start_pos;
1840
747
    if_debug2m('l', s->memory, "[l]FDArray[0] = %u => %u\n", FDArray_offsets[0], offset);
1841
747
    if (offset > FDArray_offsets[0])
1842
0
        return_error(offset_error("FDArray[0]"));
1843
747
    FDArray_offsets[0] = offset;
1844
2.19k
    for (j = 0; j < num_fonts; ++j) {
1845
1.45k
        gs_font_type1 *pfd = pfont->cidata.FDArray[j];
1846
1847
        /* If we're writing Type 2 CharStrings, don't encrypt them. */
1848
1.45k
        if (options & WRITE_TYPE2_CHARSTRINGS) {
1849
1.45k
            options |= WRITE_TYPE2_NO_LENIV;
1850
1.45k
            if (pfd->FontType != ft_encrypted2)
1851
0
                pfd->data.defaultWidthX = pfd->data.nominalWidthX = 0;
1852
1.45k
        }
1853
1.45k
        cff_write_Top_fdarray(&writer, (gs_font_base *)pfd, Private_offsets[j],
1854
1.45k
                              Private_offsets[j + 1] - Private_offsets[j]);
1855
1.45k
        offset = stell(writer.strm) - start_pos;
1856
1.45k
        if_debug3m('l', s->memory, "[l]FDArray[%d] = %u => %u\n", j + 1,
1857
1.45k
                   FDArray_offsets[j + 1], offset);
1858
1.45k
        if (offset > FDArray_offsets[j + 1])
1859
0
            return_error(offset_error("FDArray"));
1860
1.45k
        FDArray_offsets[j + 1] = offset;
1861
1.45k
    }
1862
1863
    /* Write the Private Dicts, checking the offset. */
1864
2.19k
    for (j = 0; ; ++j) {
1865
2.19k
        gs_font_type1 *pfd;
1866
1867
2.19k
        offset = stell(writer.strm) - start_pos;
1868
2.19k
        if_debug3m('l', s->memory, "[l]Private[%d] = %u => %u\n",
1869
2.19k
                   j, Private_offsets[j], offset);
1870
2.19k
        if (offset > Private_offsets[j])
1871
0
            return_error(offset_error("Private"));
1872
2.19k
        Private_offsets[j] = offset;
1873
2.19k
        if (j == num_fonts)
1874
747
            break;
1875
1.45k
        pfd = pfont->cidata.FDArray[j];
1876
1.45k
        cff_write_Private(&writer,
1877
1.45k
                          (subrs_size[j] == 0 ? 0 : Subrs_offsets[j]), pfd);
1878
1.45k
    }
1879
1880
    /* Write the Subrs Indexes, checking the offsets. */
1881
2.19k
    for (j = 0; ; ++j) {
1882
2.19k
        gs_font_type1 *pfd;
1883
1884
2.19k
        offset = stell(writer.strm) - (start_pos + Private_offsets[j]);
1885
2.19k
        if_debug3m('l', s->memory, "[l]Subrs[%d] = %u => %u\n",
1886
2.19k
                   j, Subrs_offsets[j], offset);
1887
2.19k
        if (offset > Subrs_offsets[j])
1888
0
            return_error(offset_error("Subrs"));
1889
2.19k
        Subrs_offsets[j] = offset;
1890
2.19k
        if (j == num_fonts)
1891
747
            break;
1892
1.45k
        pfd = pfont->cidata.FDArray[j];
1893
1.45k
        if (cff_convert_charstrings(&writer, (gs_font_base *)pfd))
1894
0
            cff_put_Index_header(&writer, 0, 0);
1895
1.45k
        else if (subrs_size[j] != 0)
1896
96
            cff_write_Subrs(&writer, subrs_count[j], subrs_size[j], pfd, false);
1897
1.45k
    }
1898
1899
    /* Check the final offset. */
1900
747
    offset = stell(writer.strm) - start_pos;
1901
747
    if_debug2m('l', s->memory, "[l]End = %u => %u\n", End_offset, offset);
1902
747
    if (offset > End_offset)
1903
0
        return_error(offset_error("End"));
1904
747
    if (offset == End_offset) {
1905
        /* The iteration has converged.  Write the result. */
1906
372
        if (writer.strm == &poss) {
1907
186
            writer.strm = s;
1908
186
            goto write;
1909
186
        }
1910
375
    } else {
1911
        /* No convergence yet. */
1912
375
        End_offset = offset;
1913
375
        goto iter;
1914
375
    }
1915
1916
    /* All done. */
1917
186
    return 0;
1918
747
}