~ubuntu-branches/ubuntu/jaunty/ghostscript/jaunty-updates

« back to all changes in this revision

Viewing changes to base/gdevpsf2.c

  • Committer: Bazaar Package Importer
  • Author(s): Till Kamppeter
  • Date: 2009-01-20 16:40:45 UTC
  • mfrom: (1.1.10 upstream)
  • Revision ID: james.westby@ubuntu.com-20090120164045-lnfhi0n30o5lwhwa
Tags: 8.64.dfsg.1~svn9377-0ubuntu1
* New upstream release (SVN rev 9377)
   o Fixes many bugs concerning PDF rendering, to make the PDF printing
     workflow correctly working.
   o Fixes long-standing bugs in many drivers, like input paper tray and
     duplex options not working for the built-in PCL 4, 5, 5c, 5e, and
     6/XL drivers, PDF input not working for bjc600, bjc800, and cups
     output devices, several options not working and uninitialized
     memory with cups output device.
   o Merged nearly all patches of the Ubuntu and Debian packages upstream.
   o Fixes LP: #317810, LP: #314439, LP: #314018.
* debian/patches/03_libpaper_support.dpatch,
  debian/patches/11_gs-cjk_font_glyph_handling_fix.dpatch,
  debian/patches/12_gs-cjk_vertical_writing_metrics_fix.dpatch,
  debian/patches/13_gs-cjk_cjkps_examples.dpatch,
  debian/patches/20_bbox_segv_fix.dpatch,
  debian/patches/21_brother_7x0_gdi_fix.dpatch,
  debian/patches/22_epsn_margin_workaround.dpatch,
  debian/patches/24_gs_man_fix.dpatch,
  debian/patches/25_toolbin_insecure_tmp_usage_fix.dpatch,
  debian/patches/26_assorted_script_fixes.dpatch,
  debian/patches/29_gs_css_fix.dpatch,
  debian/patches/30_ps2pdf_man_improvement.dpatch,
  debian/patches/31_fix-gc-sigbus.dpatch,
  debian/patches/34_ftbfs-on-hurd-fix.dpatch,
  debian/patches/35_disable_libcairo.dpatch,
  debian/patches/38_pxl-duplex.dpatch,
  debian/patches/39_pxl-resolution.dpatch,
  debian/patches/42_gs-init-ps-delaybind-fix.dpatch,
  debian/patches/45_bjc600-bjc800-pdf-input.dpatch,
  debian/patches/48_cups-output-device-pdf-duplex-uninitialized-memory-fix.dpatch,
  debian/patches/50_lips4-floating-point-exception.dpatch,
  debian/patches/52_cups-device-logging.dpatch,
  debian/patches/55_pcl-input-slot-fix.dpatch,
  debian/patches/57_pxl-input-slot-fix.dpatch,
  debian/patches/60_pxl-cups-driver-pdf.dpatch,
  debian/patches/62_onebitcmyk-pdf.dpatch,
  debian/patches/65_too-big-temp-files-1.dpatch,
  debian/patches/67_too-big-temp-files-2.dpatch,
  debian/patches/70_take-into-account-data-in-stream-buffer-before-refill.dpatch:
  Removed, applied upstream.
* debian/patches/01_docdir_fix_for_debian.dpatch,
  debian/patches/02_gs_man_fix_debian.dpatch,
  debian/patches/01_docdir-fix-for-debian.dpatch,
  debian/patches/02_docdir-fix-for-debian.dpatch: Renamed patches to
  make merging with Debian easier.
* debian/patches/32_improve-handling-of-media-size-changes-from-gv.dpatch, 
  debian/patches/33_bad-params-to-xinitimage-on-large-bitmaps.dpatch:
  regenerated for new source directory structure.
* debian/rules: Corrected paths to remove cidfmap (it is in Resource/Init/
  in GS 8.64) and to install headers (source paths are psi/ and base/ now).
* debian/rules: Remove all fontmaps, as DeFoMa replaces them.
* debian/local/pdftoraster/pdftoraster.c,
  debian/local/pdftoraster/pdftoraster.convs, debian/rules: Removed
  added pdftoraster filter and use the one which comes with Ghostscript.
* debian/ghostscript.links: s/8.63/8.64/

Show diffs side-by-side

added added

removed removed

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