Coverage Report

Created: 2025-04-22 06:20

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