Coverage Report

Created: 2025-06-10 07:27

/src/ghostpdl/devices/gxfcopy.c
Line
Count
Source (jump to first uncovered line)
1
/* Copyright (C) 2001-2025 Artifex Software, Inc.
2
   All Rights Reserved.
3
4
   This software is provided AS-IS with no warranty, either express or
5
   implied.
6
7
   This software is distributed under license and may not be copied,
8
   modified or distributed except as expressly authorized under the terms
9
   of the license contained in the file LICENSE in this distribution.
10
11
   Refer to licensing information at http://www.artifex.com or contact
12
   Artifex Software, Inc.,  39 Mesa Street, Suite 108A, San Francisco,
13
   CA 94129, USA, for further information.
14
*/
15
16
17
/* Font copying for high-level output */
18
#include "memory_.h"
19
#include "gx.h"
20
#include <stdlib.h>   /* for qsort */
21
#include "gscencs.h"
22
#include "gserrors.h"
23
#include "gsline.h"   /* for BuildChar */
24
#include "gspaint.h"    /* for BuildChar */
25
#include "gspath.h"   /* for gs_moveto in BuildChar */
26
#include "gsstruct.h"
27
#include "gsutil.h"
28
#include "gschar.h"
29
#include "stream.h"
30
#include "gxfont.h"
31
#include "gxfont1.h"
32
#include "gxfont42.h"
33
#include "gxchar.h"
34
#include "gxfcid.h"
35
#include "gxfcopy.h"
36
#include "gxfcache.h"   /* for gs_font_dir_s */
37
#include "gxgstate.h"   /* for Type 1 glyph_outline */
38
#include "gxtext.h"   /* for BuildChar */
39
#include "gxtype1.h"    /* for Type 1 glyph_outline */
40
#include "gzstate.h"    /* for path for BuildChar */
41
#include "gdevpsf.h"
42
#include "smd5.h"   /* Create MD5 hash of Subrs when comparing fonts */
43
44
#define GLYPHS_SIZE_IS_PRIME 1 /* Old code = 0, new code = 1. */
45
46
/* ================ Types and structures ================ */
47
48
typedef struct gs_copied_glyph_s gs_copied_glyph_t;
49
typedef struct gs_copied_font_data_s gs_copied_font_data_t;
50
51
typedef struct gs_copied_font_procs_s {
52
    int (*finish_copy_font)(gs_font *font, gs_font *copied);
53
    int (*copy_glyph)(gs_font *font, gs_glyph glyph, gs_font *copied,
54
                      int options);
55
    int (*add_encoding)(gs_font *copied, gs_char chr, gs_glyph glyph);
56
    int (*named_glyph_slot)(gs_copied_font_data_t *cfdata, gs_glyph glyph,
57
                            gs_copied_glyph_t **pslot);
58
    /* Font procedures */
59
    font_proc_encode_char((*encode_char));
60
    font_proc_glyph_info((*glyph_info));
61
    font_proc_glyph_outline((*glyph_outline));
62
    int (*uncopy_glyph)(gs_font *font, gs_glyph glyph, gs_font *copied,
63
                      int options);
64
} gs_copied_font_procs_t;
65
66
/*
67
 * We need to store the Subrs data for Type 1/2 and CIDFontType 0 fonts,
68
 * and the GlobalSubrs data for all but Type 1.
69
 */
70
typedef struct gs_subr_info_s {
71
    byte *data;   /* Subr data */
72
    int count;
73
    uint *starts; /* [count+1] Subr[i] = data[starts[i]..starts[i+1]] */
74
} gs_subr_info_t;
75
76
/*
77
 * The glyphs for copied fonts are stored explicitly in a table indexed by
78
 * glyph number.
79
 * For Type 1 fonts, the glyph numbers are parallel to the hashed name table.
80
 * For TrueType fonts, the glyph number is the TrueType GID.
81
 * For CIDFontType 0 fonts, the glyph number is the CID.
82
 * For CIDFontType 2 fonts, the glyph number is the TrueType GID;
83
 * a separate CIDMap array maps CIDs to GIDs.
84
 */
85
struct gs_copied_glyph_s {
86
    gs_const_string gdata;  /* vector data */
87
0
#define HAS_DATA 1    /* entry is in use */
88
                                /* HAS_SBW* are only used for TT-based fonts */
89
0
#define HAS_SBW0 2    /* has hmtx */
90
#define HAS_SBW1 4    /* has vmtx */
91
    byte used;      /* non-zero iff this entry is in use */
92
                                /* (if not, gdata.{data,size} = 0) */
93
    int order_index;            /* Index for the ordered glyph set. */
94
};
95
/*
96
 * We use a special GC descriptor to avoid large GC overhead.
97
 */
98
gs_private_st_composite(st_gs_copied_glyph_element, gs_copied_glyph_t,
99
                        "gs_copied_glyph_t[]", copied_glyph_element_enum_ptrs,
100
                        copied_glyph_element_reloc_ptrs);
101
0
static ENUM_PTRS_WITH(copied_glyph_element_enum_ptrs, gs_copied_glyph_t *pcg)
102
0
     if (index < size / (uint)sizeof(gs_copied_glyph_t))
103
0
         return ENUM_CONST_STRING(&pcg[index].gdata);
104
0
     return 0;
105
0
ENUM_PTRS_END
106
0
static RELOC_PTRS_WITH(copied_glyph_element_reloc_ptrs, gs_copied_glyph_t *pcg)
107
0
{
108
0
    uint count = size / (uint)sizeof(gs_copied_glyph_t);
109
0
    gs_copied_glyph_t *p = pcg;
110
111
0
    for (; count > 0; --count, ++p)
112
0
        if (p->gdata.size > 0)
113
0
            RELOC_CONST_STRING_VAR(p->gdata);
114
0
}
115
0
RELOC_PTRS_END
116
117
/*
118
 * Type 1 and TrueType fonts also have a 'names' table, parallel to the
119
 * 'glyphs' table.
120
 * For Type 1 fonts, this is a hash table; glyph numbers are assigned
121
 * arbitrarily, according to the hashed placement of the names.
122
 * For TrueType fonts, this is indexed by GID.
123
 * The strings in this table are either those returned by the font's
124
 * glyph_name procedure, which we assume are garbage-collected, or those
125
 * associated with the known encodings, which we assume are immutable.
126
 */
127
typedef struct gs_copied_glyph_name_s {
128
    gs_glyph glyph;   /* key (for comparison and glyph_name only) */
129
    gs_const_string str;  /* glyph name */
130
} gs_copied_glyph_name_t;
131
/*
132
 * We use the same special GC descriptor as above for 'names'.
133
 */
134
gs_private_st_composite(st_gs_copied_glyph_name_element,
135
                        gs_copied_glyph_name_t,
136
                        "gs_copied_glyph_name_t[]",
137
                        copied_glyph_name_enum_ptrs,
138
                        copied_glyph_name_reloc_ptrs);
139
0
static ENUM_PTRS_WITH(copied_glyph_name_enum_ptrs, gs_copied_glyph_name_t *pcgn)
140
0
     if (index < size / (uint)sizeof(gs_copied_glyph_name_t)) {
141
0
         const gs_copied_glyph_name_t *const p = &pcgn[index];
142
143
0
         return (p->str.size == 0 ||
144
0
                 gs_is_c_glyph_name(p->str.data, p->str.size) ?
145
0
                 ENUM_CONST_STRING2(0, 0) :
146
0
                 ENUM_CONST_STRING(&p->str));
147
0
     }
148
0
     return 0;
149
     /* We should mark glyph name here, but we have no access to
150
        the gs_font_dir instance. Will mark in gs_copied_font_data_enum_ptrs.
151
      */
152
0
ENUM_PTRS_END
153
0
static RELOC_PTRS_WITH(copied_glyph_name_reloc_ptrs, gs_copied_glyph_name_t *pcgn)
154
0
{
155
0
    uint count = size / (uint)sizeof(gs_copied_glyph_name_t);
156
0
    gs_copied_glyph_name_t *p = pcgn;
157
158
0
    for (; count > 0; --count, ++p)
159
0
        if (p->str.size > 0 && !gs_is_c_glyph_name(p->str.data, p->str.size))
160
0
            RELOC_CONST_STRING_VAR(p->str);
161
0
}
162
0
RELOC_PTRS_END
163
164
/*
165
 * To accommodate glyphs with multiple names, there is an additional
166
 * 'extra_names' table.  Since this is rare, this table uses linear search.
167
 */
168
typedef struct gs_copied_glyph_extra_name_s gs_copied_glyph_extra_name_t;
169
struct gs_copied_glyph_extra_name_s {
170
    gs_copied_glyph_name_t name;
171
    uint gid;     /* index in glyphs table */
172
    gs_copied_glyph_extra_name_t *next;
173
};
174
BASIC_PTRS(gs_copied_glyph_extra_name_ptrs) {
175
    GC_STRING_ELT(gs_copied_glyph_extra_name_t, name.str),
176
    GC_OBJ_ELT(gs_copied_glyph_extra_name_t, next)
177
};
178
gs_private_st_basic(st_gs_copied_glyph_extra_name,
179
                    gs_copied_glyph_extra_name_t,
180
                    "gs_copied_glyph_extra_name_t",
181
                    gs_copied_glyph_extra_name_ptrs,
182
                    gs_copied_glyph_extra_name_data);
183
184
/*
185
 * The client_data of copied fonts points to an instance of
186
 * gs_copied_font_data_t.
187
 */
188
struct gs_copied_font_data_s {
189
    gs_font_info_t info;  /* from the original font, must be first */
190
    const gs_copied_font_procs_t *procs;
191
    gs_copied_glyph_t *glyphs;  /* [glyphs_size] */
192
    uint glyphs_size;   /* (a power of 2 or a prime number for Type 1/2) */
193
    uint num_glyphs;    /* The number of glyphs copied. */
194
    gs_glyph notdef;    /* CID 0 or .notdef glyph */
195
    /*
196
     * We don't use a union for the rest of the data, because some of the
197
     * cases overlap and it's just not worth the trouble.
198
     */
199
    gs_copied_glyph_name_t *names; /* (Type 1/2, TrueType) [glyphs_size] */
200
    gs_copied_glyph_extra_name_t *extra_names; /* (TrueType) */
201
    byte *data;     /* (TrueType and CID fonts) copied data */
202
    uint data_size;   /* (TrueType and CID fonts) */
203
    gs_glyph *Encoding;   /* (Type 1/2 and Type 42) [256] */
204
    ushort *CIDMap;   /* (CIDFontType 2) [CIDCount] */
205
    gs_subr_info_t subrs; /* (Type 1/2 and CIDFontType 0) */
206
    gs_subr_info_t global_subrs; /* (Type 2 and CIDFontType 0) */
207
    gs_font_cid0 *parent; /* (Type 1 subfont) => parent CIDFontType 0 */
208
    gs_font_dir *dir;
209
    bool ordered;
210
};
211
extern_st(st_gs_font_info);
212
static
213
0
ENUM_PTRS_WITH(gs_copied_font_data_enum_ptrs, gs_copied_font_data_t *cfdata)
214
    /* See comments in gs_copy_font() below regarding the enumeration of names
215
     * and the font's 'dir' member
216
     */
217
0
    if (index == 12 && cfdata->dir != NULL) {
218
0
        gs_copied_glyph_name_t *names = cfdata->names;
219
0
        gs_copied_glyph_extra_name_t *en = cfdata->extra_names;
220
0
        int i;
221
222
0
        if (names != NULL)
223
0
            for (i = 0; i < cfdata->glyphs_size; ++i)
224
0
                if (names[i].glyph < gs_c_min_std_encoding_glyph)
225
0
                    cfdata->dir->ccache.mark_glyph(mem, names[i].glyph, NULL);
226
0
        for (; en != NULL; en = en->next)
227
0
            if (en->name.glyph < gs_c_min_std_encoding_glyph)
228
0
                cfdata->dir->ccache.mark_glyph(mem, en->name.glyph, NULL);
229
0
    }
230
0
    return ENUM_USING(st_gs_font_info, &cfdata->info, sizeof(gs_font_info_t), index - 12);
231
0
    ENUM_PTR3(0, gs_copied_font_data_t, glyphs, names, extra_names);
232
0
    ENUM_PTR3(3, gs_copied_font_data_t, data, Encoding, CIDMap);
233
0
    ENUM_PTR3(6, gs_copied_font_data_t, subrs.data, subrs.starts, global_subrs.data);
234
0
    ENUM_PTR3(9, gs_copied_font_data_t, global_subrs.starts, parent, dir);
235
0
ENUM_PTRS_END
236
237
0
static RELOC_PTRS_WITH(gs_copied_font_data_reloc_ptrs, gs_copied_font_data_t *cfdata)
238
0
{
239
0
    RELOC_PTR3(gs_copied_font_data_t, glyphs, names, extra_names);
240
0
    RELOC_PTR3(gs_copied_font_data_t, data, Encoding, CIDMap);
241
0
    RELOC_PTR3(gs_copied_font_data_t, subrs.data, subrs.starts, global_subrs.data);
242
0
    RELOC_PTR3(gs_copied_font_data_t, global_subrs.starts, parent, dir);
243
0
    RELOC_USING(st_gs_font_info, &cfdata->info, sizeof(gs_font_info_t));
244
0
}
245
0
RELOC_PTRS_END
246
247
gs_private_st_composite(st_gs_copied_font_data, gs_copied_font_data_t, "gs_copied_font_data_t",\
248
    gs_copied_font_data_enum_ptrs, gs_copied_font_data_reloc_ptrs);
249
250
static inline gs_copied_font_data_t *
251
cf_data(const gs_font *font)
252
0
{
253
0
    return (gs_copied_font_data_t *)font->client_data;
254
0
}
255
256
/* ================ Procedures ================ */
257
258
/* ---------------- Private utilities ---------------- */
259
260
/* Copy a string.  Return 0 or gs_error_VMerror. */
261
static int
262
copy_string(gs_memory_t *mem, gs_const_string *pstr, client_name_t cname)
263
0
{
264
0
    const byte *data = pstr->data;
265
0
    uint size = pstr->size;
266
0
    byte *str;
267
268
0
    if (data == 0)
269
0
        return 0;   /* empty string */
270
0
    str = gs_alloc_string(mem, size, cname);
271
0
    pstr->data = str;
272
0
    if (str == 0)
273
0
        return_error(gs_error_VMerror);
274
0
    memcpy(str, data, size);
275
0
    return 0;
276
0
}
277
278
/* Free a copied string. */
279
static void
280
uncopy_string(gs_memory_t *mem, gs_const_string *pstr, client_name_t cname)
281
0
{
282
0
    if (pstr->data)
283
0
        gs_free_const_string(mem, pstr->data, pstr->size, cname);
284
0
}
285
286
/*
287
 * Allocate an Encoding for a Type 1 or Type 42 font.
288
 */
289
static int
290
copied_Encoding_alloc(gs_font *copied)
291
0
{
292
0
    gs_copied_font_data_t *const cfdata = cf_data(copied);
293
0
    gs_glyph *Encoding = (gs_glyph *)
294
0
        gs_alloc_byte_array(copied->memory, 256, sizeof(*cfdata->Encoding),
295
0
                            "copy_font_type1(Encoding)");
296
0
    int i;
297
298
0
    if (Encoding == 0)
299
0
        return_error(gs_error_VMerror);
300
0
    for (i = 0; i < 256; ++i)
301
0
        Encoding[i] = GS_NO_GLYPH;
302
0
    cfdata->Encoding = Encoding;
303
0
    return 0;
304
0
}
305
306
/*
307
 * Allocate and set up data copied from a TrueType or CID font.
308
 * stell(*s) + extra is the length of the data.
309
 */
310
static int
311
copied_data_alloc(gs_font *copied, stream *s, uint extra, int code)
312
0
{
313
0
    gs_copied_font_data_t *const cfdata = cf_data(copied);
314
0
    uint len = stell(s);
315
0
    byte *fdata;
316
317
0
    if (code < 0)
318
0
        return code;
319
0
    fdata = gs_alloc_bytes(copied->memory, len + extra, "copied_data_alloc");
320
0
    if (fdata == 0)
321
0
        return_error(gs_error_VMerror);
322
0
    s_init(s, copied->memory);
323
0
    swrite_string(s, fdata, len);
324
0
    cfdata->data = fdata;
325
0
    cfdata->data_size = len + extra;
326
0
    return 0;
327
0
}
328
329
/*
330
 * Copy Subrs or GSubrs from a font.
331
 */
332
static int
333
copy_subrs(gs_font_type1 *pfont, bool global, gs_subr_info_t *psi,
334
           gs_memory_t *mem)
335
0
{
336
0
    int i, code;
337
0
    uint size;
338
0
    gs_glyph_data_t gdata;
339
0
    byte *data;
340
0
    uint *starts;
341
342
0
    gdata.memory = pfont->memory;
343
    /* Scan the font to determine the size of the subrs. */
344
0
    for (i = 0, size = 0;
345
0
         (code = pfont->data.procs.subr_data(pfont, i, global, &gdata)) !=
346
0
             gs_error_rangecheck;
347
0
         ++i) {
348
0
        if (code >= 0) {
349
0
            size += gdata.bits.size;
350
0
            gs_glyph_data_free(&gdata, "copy_subrs");
351
0
        }
352
0
    }
353
0
    if (size == 0)
354
0
        data = 0, starts = 0, i = 0;
355
0
    else {
356
        /* Allocate the copy. */
357
0
        data = gs_alloc_bytes(mem, size, "copy_subrs(data)");
358
0
        starts = (uint *)gs_alloc_byte_array(mem, i + 1, sizeof(*starts),
359
0
                                             "copy_subrs(starts)");
360
0
        if (data == 0 || starts == 0) {
361
0
            gs_free_object(mem, starts, "copy_subrs(starts)");
362
0
            gs_free_object(mem, data, "copy_subrs(data)");
363
0
            return_error(gs_error_VMerror);
364
0
        }
365
366
        /* Copy the data. */
367
0
        for (i = 0, size = 0;
368
0
             (code = pfont->data.procs.subr_data(pfont, i, global, &gdata)) !=
369
0
                 gs_error_rangecheck;
370
0
             ++i) {
371
0
            starts[i] = size;
372
0
            if (code >= 0) {
373
0
                memcpy(data + size, gdata.bits.data, gdata.bits.size);
374
0
                size += gdata.bits.size;
375
0
                gs_glyph_data_free(&gdata, "copy_subrs");
376
0
            }
377
0
        }
378
0
        starts[i] = size;
379
0
    }
380
381
0
    psi->data = data;
382
0
    psi->starts = starts;
383
0
    psi->count = i;
384
0
    return 0;
385
0
}
386
387
/*
388
 * Return a pointer to the definition of a copied glyph, accessed either by
389
 * name or by glyph number.  If the glyph is out of range, return
390
 * gs_error_rangecheck; if the glyph is in range but undefined, store a
391
 * pointer to the slot where it would be added, which will have gdata.data
392
 * == 0, and return gs_error_undefined; if the glyph is defined, store the
393
 * pointer and return 0.
394
 *
395
 * NOTE:
396
 * The interim variable (idx) is used here as a workaround for what appears
397
 * to be a compiler optimiser bug in VS2019 - using "glyph - GS_MIN_CID_GLYPH"
398
 * directly to index into the cfdata->glyphs array results in a pointer value
399
 * in *pslot which is complete nonsense. Using the variable to store the
400
 * calculated value results in working code.
401
 */
402
static int
403
copied_glyph_slot(gs_copied_font_data_t *cfdata, gs_glyph glyph,
404
                  gs_copied_glyph_t **pslot)
405
0
{
406
0
    uint gsize = cfdata->glyphs_size;
407
0
    unsigned int idx;
408
409
0
    *pslot = 0;
410
0
    if (glyph >= GS_MIN_GLYPH_INDEX) {
411
        /* CIDFontType 2 uses glyph indices for slots.  */
412
0
        idx = (unsigned int)(glyph - GS_MIN_GLYPH_INDEX);
413
0
        if (idx >= gsize)
414
0
            return_error(gs_error_rangecheck);
415
0
        *pslot = &cfdata->glyphs[idx];
416
0
    } else if (glyph >= GS_MIN_CID_GLYPH) {
417
        /* CIDFontType 0 uses CIDS for slots.  */
418
0
        idx = (unsigned int)(glyph - GS_MIN_CID_GLYPH);
419
0
        if (idx >= gsize)
420
0
            return_error(gs_error_rangecheck);
421
0
        *pslot = &cfdata->glyphs[idx];
422
0
    } else if (cfdata->names == 0)
423
0
        return_error(gs_error_rangecheck);
424
0
    else {
425
0
        int code = cfdata->procs->named_glyph_slot(cfdata, glyph, pslot);
426
427
0
        if (code < 0)
428
0
            return code;
429
0
    }
430
0
    if (!(*pslot)->used)
431
0
        return_error(gs_error_undefined);
432
0
    return 0;
433
0
}
434
static int
435
named_glyph_slot_none(gs_copied_font_data_t *cfdata, gs_glyph glyph,
436
                        gs_copied_glyph_t **pslot)
437
0
{
438
0
    return_error(gs_error_rangecheck);
439
0
}
440
static int
441
named_glyph_slot_hashed(gs_copied_font_data_t *cfdata, gs_glyph glyph,
442
                        gs_copied_glyph_t **pslot)
443
0
{
444
0
    uint gsize = cfdata->glyphs_size;
445
0
    gs_copied_glyph_name_t *names = cfdata->names;
446
0
    uint hash = (uint)glyph % gsize;
447
    /*
448
     * gsize is either a prime number or a power of 2.
449
     * If it is prime, any positive reprobe below gsize guarantees that we
450
     * will touch every slot.
451
     * If it is a power of 2, any odd reprobe guarantees that we
452
     * will touch every slot.
453
     */
454
0
    uint hash2 = ((uint)glyph / gsize * 2 + 1) % gsize;
455
0
    uint tries = gsize;
456
457
0
    while (names[hash].str.data != 0 && names[hash].glyph != glyph) {
458
0
        hash = (hash + hash2) % gsize;
459
0
        if (!tries)
460
0
    return_error(gs_error_undefined);
461
0
        tries--;
462
0
    }
463
0
    *pslot = &cfdata->glyphs[hash];
464
0
    return 0;
465
0
}
466
static int
467
named_glyph_slot_linear(gs_copied_font_data_t *cfdata, gs_glyph glyph,
468
                        gs_copied_glyph_t **pslot)
469
0
{
470
0
    {
471
0
        gs_copied_glyph_name_t *names = cfdata->names;
472
0
        int i;
473
474
0
        for (i = 0; i < cfdata->glyphs_size; ++i)
475
0
            if (names[i].glyph == glyph) {
476
0
                *pslot = &cfdata->glyphs[i];
477
0
                return 0;
478
0
            }
479
0
    }
480
    /* This might be a glyph with multiple names.  Search extra_names. */
481
0
    {
482
0
        gs_copied_glyph_extra_name_t *extra_name = cfdata->extra_names;
483
484
0
        for (; extra_name != 0; extra_name = extra_name->next)
485
0
            if (extra_name->name.glyph == glyph) {
486
0
                *pslot = &cfdata->glyphs[extra_name->gid];
487
0
                return 0;
488
0
            }
489
0
    }
490
0
    return_error(gs_error_rangecheck);
491
0
}
492
493
/*
494
 * Add glyph data to the glyph table.  This handles copying the vector
495
 * data, detecting attempted redefinitions, and freeing temporary glyph
496
 * data.  The glyph must be an integer, an index in the glyph table.
497
 * Return 1 if the glyph was already defined, 0 if newly added (or an
498
 * error per options).
499
 */
500
static int
501
copy_glyph_data(gs_font *font, gs_glyph glyph, gs_font *copied, int options,
502
                gs_glyph_data_t *pgdata, const byte *prefix, int prefix_bytes)
503
0
{
504
0
    gs_copied_font_data_t *const cfdata = cf_data(copied);
505
0
    uint size = pgdata->bits.size;
506
0
    gs_copied_glyph_t *pcg = 0;
507
0
    int code = copied_glyph_slot(cfdata, glyph, &pcg);
508
509
0
    if (cfdata->ordered)
510
0
        return_error(gs_error_unregistered); /* Must not happen. */
511
0
    switch (code) {
512
0
    case 0:     /* already defined */
513
0
        if ((options & COPY_GLYPH_NO_OLD) ||
514
0
            pcg->gdata.size != prefix_bytes + size ||
515
0
            (prefix_bytes > 0 && memcmp(pcg->gdata.data, prefix, prefix_bytes)) ||
516
0
            (size > 0 && memcmp(pcg->gdata.data + prefix_bytes,
517
0
                   pgdata->bits.data, size))
518
0
            )
519
0
            code = gs_note_error(gs_error_invalidaccess);
520
0
        else
521
0
            code = 1;
522
0
        break;
523
0
    case gs_error_undefined:
524
0
        if (options & COPY_GLYPH_NO_NEW)
525
0
            code = gs_note_error(gs_error_undefined);
526
0
        else if (pcg == NULL)
527
0
            code = gs_note_error(gs_error_undefined);
528
0
        else {
529
0
            uint str_size = prefix_bytes + size;
530
531
0
            code = 0;
532
0
            if (str_size > 0) {
533
0
                byte *str = gs_alloc_string(copied->memory, str_size,
534
0
                                            "copy_glyph_data(data)");
535
536
0
                if (str == 0)
537
0
                    code = gs_note_error(gs_error_VMerror);
538
0
                else {
539
0
                    if (prefix_bytes)
540
0
                        memcpy(str, prefix, prefix_bytes);
541
0
                    memcpy(str + prefix_bytes, pgdata->bits.data, size);
542
0
                    pcg->gdata.data = str;
543
0
                }
544
0
            }
545
0
            if (code >= 0) {
546
0
                pcg->gdata.size = str_size;
547
0
                pcg->used = HAS_DATA;
548
0
                pcg->order_index = -1;
549
0
                code = 0;
550
0
                cfdata->num_glyphs++;
551
0
            }
552
0
        }
553
0
    default:
554
0
        break;
555
0
    }
556
0
    gs_glyph_data_free(pgdata, "copy_glyph_data");
557
0
    return code;
558
0
}
559
560
/*
561
 * Copy a glyph name into the names table.
562
 */
563
static int
564
copy_glyph_name(gs_font *font, gs_glyph glyph, gs_font *copied,
565
                gs_glyph copied_glyph)
566
0
{
567
0
    gs_glyph known_glyph;
568
0
    gs_copied_font_data_t *const cfdata = cf_data(copied);
569
0
    gs_copied_glyph_t *pcg;
570
0
    int code = copied_glyph_slot(cfdata, copied_glyph, &pcg);
571
0
    gs_copied_glyph_name_t *pcgn;
572
0
    gs_const_string str;
573
574
0
    if (cfdata->ordered)
575
0
        return_error(gs_error_unregistered); /* Must not happen. */
576
0
    if (code < 0 ||
577
0
        (code = font->procs.glyph_name(font, glyph, &str)) < 0
578
0
        )
579
0
        return code;
580
    /* Try to share a permanently allocated known glyph name. */
581
0
    if ((known_glyph = gs_c_name_glyph(str.data, str.size)) != GS_NO_GLYPH)
582
0
        gs_c_glyph_name(known_glyph, &str);
583
0
    else if ((code = copy_string(copied->memory, &str, "copy_glyph_name")) < 0)
584
0
        return code;
585
0
    pcgn = cfdata->names + (pcg - cfdata->glyphs);
586
0
    if (pcgn->glyph != GS_NO_GLYPH &&
587
0
        (pcgn->str.size != str.size ||
588
0
         memcmp(pcgn->str.data, str.data, str.size))
589
0
        ) {
590
        /* This is a glyph with multiple names.  Add an extra_name entry. */
591
0
        gs_copied_glyph_extra_name_t *extra_name =
592
0
            gs_alloc_struct(copied->memory, gs_copied_glyph_extra_name_t,
593
0
                            &st_gs_copied_glyph_extra_name,
594
0
                            "copy_glyph_name(extra_name)");
595
596
0
        if (extra_name == 0)
597
0
            return_error(gs_error_VMerror);
598
0
        memset(extra_name, 0x00, sizeof(gs_copied_glyph_extra_name_t));
599
0
        extra_name->next = cfdata->extra_names;
600
0
        extra_name->gid = pcg - cfdata->glyphs;
601
0
        cfdata->extra_names = extra_name;
602
0
        pcgn = &extra_name->name;
603
0
    }
604
0
    if (pcgn->str.size != 0 && !gs_is_c_glyph_name(pcgn->str.data, pcgn->str.size))
605
0
        gs_free_string(copied->memory, (byte *)pcgn->str.data, pcgn->str.size, "Free copied glyph name");
606
0
    pcgn->glyph = glyph;
607
0
    pcgn->str = str;
608
0
    return 0;
609
0
}
610
611
/*
612
 * Find the .notdef glyph in a font.
613
 */
614
static gs_glyph
615
find_notdef(gs_font_base *font)
616
0
{
617
0
    int index = 0;
618
0
    gs_glyph glyph;
619
620
0
    while (font->procs.enumerate_glyph((gs_font *)font, &index,
621
0
                                       GLYPH_SPACE_NAME, &glyph),
622
0
           index != 0)
623
0
        if (gs_font_glyph_is_notdef(font, glyph))
624
0
            return glyph;
625
0
    return GS_NO_GLYPH;   /* best we can do */
626
0
}
627
628
/*
629
 * Add an Encoding entry to a character-indexed font (Type 1/2/42).
630
 */
631
static int
632
copied_char_add_encoding(gs_font *copied, gs_char chr, gs_glyph glyph)
633
0
{
634
0
    gs_copied_font_data_t *const cfdata = cf_data(copied);
635
0
    gs_glyph *Encoding = cfdata->Encoding;
636
0
    gs_copied_glyph_t *pslot;
637
0
    int code;
638
639
0
    if (cfdata->ordered)
640
0
        return_error(gs_error_unregistered); /* Must not happen. */
641
0
    if (Encoding == 0)
642
0
        return_error(gs_error_invalidaccess);
643
0
    if (chr >= 256 || glyph >= GS_MIN_CID_GLYPH)
644
0
        return_error(gs_error_rangecheck);
645
0
    code = copied_glyph_slot(cfdata, glyph, &pslot);
646
0
    if (code < 0)
647
0
        return code;
648
0
    if (Encoding[chr] != glyph && Encoding[chr] != GS_NO_GLYPH)
649
0
        return_error(gs_error_invalidaccess);
650
0
    Encoding[chr] = glyph;
651
0
    return 0;
652
0
}
653
654
/* Don't allow adding an Encoding entry. */
655
static int
656
copied_no_add_encoding(gs_font *copied, gs_char chr, gs_glyph glyph)
657
0
{
658
0
    return_error(gs_error_invalidaccess);
659
0
}
660
661
/* ---------------- Font procedures ---------------- */
662
663
static int
664
copied_font_info(gs_font *font, const gs_point *pscale, int members,
665
                 gs_font_info_t *info)
666
0
{
667
0
    if (pscale != 0)
668
0
        return_error(gs_error_rangecheck);
669
0
    *info = cf_data(font)->info;
670
0
    return 0;
671
0
}
672
673
static gs_glyph
674
copied_encode_char(gs_font *copied, gs_char chr, gs_glyph_space_t glyph_space)
675
0
{
676
0
    gs_copied_font_data_t *const cfdata = cf_data(copied);
677
0
    const gs_glyph *Encoding = cfdata->Encoding;
678
679
0
    if (chr >= 256 || Encoding == 0)
680
0
        return GS_NO_GLYPH;
681
0
    return Encoding[chr];
682
0
}
683
684
static int
685
copied_enumerate_glyph(gs_font *font, int *pindex,
686
                       gs_glyph_space_t glyph_space, gs_glyph *pglyph)
687
0
{
688
0
    gs_copied_font_data_t *const cfdata = cf_data(font);
689
690
0
    if (cfdata->ordered) {
691
0
        if (*pindex >= cfdata->num_glyphs)
692
0
            *pindex = 0;
693
0
        else {
694
0
            int i = cfdata->glyphs[*pindex].order_index;
695
696
0
            *pglyph = cfdata->names[i].glyph;
697
0
            ++(*pindex);
698
0
        }
699
0
        return 0;
700
0
    }
701
0
    for (; *pindex < cfdata->glyphs_size; ++*pindex)
702
0
        if (cfdata->glyphs[*pindex].used) {
703
0
            *pglyph =
704
0
                (glyph_space == GLYPH_SPACE_NAME && cfdata->names != 0 ?
705
0
                 cfdata->names[*pindex].glyph :
706
                 /* CIDFontType 0 uses CIDS as slot indices; CIDFontType 2 uses GIDs. */
707
0
                 *pindex + (glyph_space == GLYPH_SPACE_NAME
708
0
                            ? GS_MIN_CID_GLYPH : GS_MIN_GLYPH_INDEX));
709
0
            ++(*pindex);
710
0
            return 0;
711
0
        }
712
0
    *pindex = 0;
713
0
    return 0;
714
0
}
715
716
static int
717
copied_glyph_name(gs_font *font, gs_glyph glyph, gs_const_string *pstr)
718
0
{
719
0
    gs_copied_font_data_t *const cfdata = cf_data(font);
720
0
    gs_copied_glyph_t *pcg;
721
722
0
    if (glyph >= GS_MIN_CID_GLYPH)
723
0
        return_error(gs_error_rangecheck);
724
0
    if (copied_glyph_slot(cfdata, glyph, &pcg) < 0)
725
0
        return_error(gs_error_undefined);
726
0
    *pstr = cfdata->names[pcg - cfdata->glyphs].str;
727
0
    return 0;
728
0
}
729
730
static int
731
copied_build_char(gs_show_enum *pte, gs_gstate *pgs, gs_font *font,
732
                  gs_char chr, gs_glyph glyph)
733
0
{
734
0
    int wmode = font->WMode;
735
0
    int code;
736
0
    gs_glyph_info_t info;
737
0
    double wxy[6];
738
0
    double sbw_stub[4]; /* Currently glyph_outline retrieves sbw only with type 1,2,9 fonts. */
739
740
0
    if (glyph == GS_NO_GLYPH) {
741
0
        glyph = font->procs.encode_char(font, chr, GLYPH_SPACE_INDEX);
742
0
        if (glyph == GS_NO_GLYPH)
743
0
            glyph = cf_data(font)->notdef;
744
0
    }
745
    /*
746
     * Type 1/2 outlines don't require a current point, but TrueType
747
     * outlines do.  We might want to fix this someday....
748
     */
749
0
    if ((code = gs_moveto(pgs, 0.0, 0.0)) < 0 ||
750
0
        (code = font->procs.glyph_info(font, glyph, NULL,
751
0
                                       (GLYPH_INFO_WIDTH << wmode) |
752
0
                                       GLYPH_INFO_BBOX |
753
0
                                       GLYPH_INFO_OUTLINE_WIDTHS,
754
0
                                       &info)) < 0
755
0
        )
756
0
        return code;
757
0
    wxy[0] = info.width[wmode].x;
758
0
    wxy[1] = info.width[wmode].y;
759
0
    wxy[2] = info.bbox.p.x;
760
0
    wxy[3] = info.bbox.p.y;
761
0
    wxy[4] = info.bbox.q.x;
762
0
    wxy[5] = info.bbox.q.y;
763
0
    if ((code = gs_setcachedevice_double(pte, pte->pgs, wxy)) < 0 ||
764
0
        (code = font->procs.glyph_outline(font, wmode, glyph, &ctm_only(pgs),
765
0
                                          pgs->path, sbw_stub)) < 0
766
0
        )
767
0
        return code;
768
0
    if (font->PaintType != 0) {
769
0
        gs_setlinewidth(pgs, font->StrokeWidth);
770
0
        return gs_stroke(pgs);
771
0
    } else {
772
0
        return gs_fill(pgs);
773
0
    }
774
0
}
775
776
static inline bool
777
compare_arrays(const float *v0, int l0, const float *v1, int l1)
778
0
{
779
0
    if (l0 != l1)
780
0
        return false;
781
0
    if (memcmp(v0, v1, l0 * sizeof(v0[0])))
782
0
        return false;
783
0
    return true;
784
0
}
785
786
0
#define compare_tables(a, b) compare_arrays(a.values, a.count, b.values, b.count)
787
788
static int
789
compare_glyphs(const gs_font *cfont, const gs_font *ofont, gs_glyph *glyphs,
790
                           int num_glyphs, int glyphs_step, int level)
791
0
{
792
    /*
793
     * Checking widths because we can synthesize fonts from random fonts
794
     * having same FontName and FontType.
795
     * We must request width explicitely because Type 42 stores widths
796
     * separately from outline data. We could skip it for Type 1, which doesn't.
797
     * We don't care of Metrics, Metrics2 because copied font never has them.
798
     */
799
0
    int i, WMode = ofont->WMode;
800
0
    int members = (GLYPH_INFO_WIDTH0 << WMode) | GLYPH_INFO_OUTLINE_WIDTHS | GLYPH_INFO_NUM_PIECES;
801
0
    gs_matrix mat;
802
0
    gs_copied_font_data_t *const cfdata = cf_data(cfont);
803
0
    int num_new_glyphs = 0;
804
805
0
    gs_make_identity(&mat);
806
0
    for (i = 0; i < num_glyphs; i++) {
807
0
        gs_glyph glyph = *(gs_glyph *)((byte *)glyphs + i * glyphs_step);
808
0
        gs_glyph pieces0[40], *pieces = pieces0;
809
0
        gs_glyph_info_t info0, info1;
810
0
        int code0, code1, code2, code;
811
812
0
        memset(&info0, 0x00, sizeof(gs_glyph_info_t));
813
0
        code0 = ofont->procs.glyph_info((gs_font *)ofont, glyph, &mat, members, &info0);
814
0
        memset(&info1, 0x00, sizeof(gs_glyph_info_t));
815
0
        code1 = cfont->procs.glyph_info((gs_font *)cfont, glyph, &mat, members, &info1);
816
817
0
        if (code0 == gs_error_undefined)
818
0
            continue;
819
0
        if (code1 == gs_error_undefined) {
820
0
            num_new_glyphs++;
821
0
            if (num_new_glyphs > cfdata->glyphs_size - cfdata->num_glyphs)
822
0
                return 0;
823
0
            continue;
824
0
        }
825
0
        if (code0 < 0)
826
0
            return code0;
827
0
        if (code1 < 0)
828
0
            return code1;
829
0
        if (info0.num_pieces != info1.num_pieces)
830
0
            return 0;
831
0
        if (info0.num_pieces > 0) {
832
0
            if(level > 5)
833
0
                return_error(gs_error_rangecheck); /* abnormal glyph recursion */
834
0
            if (info0.num_pieces > countof(pieces0) / 2) {
835
0
                pieces = (gs_glyph *)gs_alloc_bytes(cfont->memory,
836
0
                    sizeof(gs_glyph) * info0.num_pieces * 2, "compare_glyphs");
837
0
                if (pieces == 0)
838
0
                    return_error(gs_error_VMerror);
839
0
            }
840
0
            info0.pieces = pieces;
841
0
            info1.pieces = pieces + info0.num_pieces;
842
0
            code0 = ofont->procs.glyph_info((gs_font *)ofont, glyph, &mat,
843
0
                                    GLYPH_INFO_PIECES, &info0);
844
0
            code1 = cfont->procs.glyph_info((gs_font *)cfont, glyph, &mat,
845
0
                                    GLYPH_INFO_PIECES, &info1);
846
0
            if (code0 >= 0 && code1 >= 0) {
847
0
                code2 = memcmp(info0.pieces, info1.pieces, info0.num_pieces * sizeof(*pieces));
848
0
                if (!code2)
849
0
                    code = compare_glyphs(cfont, ofont, pieces, info0.num_pieces, glyphs_step, level + 1);
850
0
                else
851
0
                    code = 0; /* Quiet compiler. */
852
0
            } else
853
0
                code2 = code = 0;
854
0
            if (pieces != pieces0)
855
0
                gs_free_object(cfont->memory, pieces, "compare_glyphs");
856
0
            if (code0 == gs_error_undefined)
857
0
                continue;
858
0
            if (code1 == gs_error_undefined) {
859
0
                num_new_glyphs++;
860
0
                if (num_new_glyphs > cfdata->glyphs_size - cfdata->num_glyphs)
861
0
                    return 0;
862
0
                continue;
863
0
            }
864
0
            if (code0 < 0)
865
0
                return code0;
866
0
            if (code1 < 0)
867
0
                return code1;
868
0
            if (code2 || code == 0) {
869
0
                return 0;
870
0
            }
871
0
        } else {
872
0
            gs_glyph_data_t gdata0, gdata1;
873
874
0
            switch(cfont->FontType) {
875
0
                case ft_encrypted:
876
0
                case ft_encrypted2: {
877
0
                    gs_font_type1 *font0 = (gs_font_type1 *)cfont;
878
0
                    gs_font_type1 *font1 = (gs_font_type1 *)ofont;
879
880
0
                    gdata0.memory = font0->memory;
881
0
                    gdata1.memory = font1->memory;
882
0
                    code0 = font0->data.procs.glyph_data(font0, glyph, &gdata0);
883
0
                    code1 = font1->data.procs.glyph_data(font1, glyph, &gdata1);
884
0
                    break;
885
0
                }
886
0
                case ft_TrueType:
887
0
                case ft_CID_TrueType: {
888
0
                    gs_font_type42 *font0 = (gs_font_type42 *)cfont;
889
0
                    gs_font_type42 *font1 = (gs_font_type42 *)ofont;
890
0
                    uint glyph_index0 = font0->data.get_glyph_index(font0, glyph);
891
0
                    uint glyph_index1 = font1->data.get_glyph_index(font1, glyph);
892
893
0
                    gdata0.memory = font0->memory;
894
0
                    gdata1.memory = font1->memory;
895
0
                    code0 = font0->data.get_outline(font0, glyph_index0, &gdata0);
896
0
                    code1 = font1->data.get_outline(font1, glyph_index1, &gdata1);
897
0
                    break;
898
0
                }
899
0
                case ft_CID_encrypted: {
900
0
                    gs_font_cid0 *font0 = (gs_font_cid0 *)cfont;
901
0
                    gs_font_cid0 *font1 = (gs_font_cid0 *)ofont;
902
0
                    int fidx0, fidx1;
903
904
0
                    gdata0.memory = font0->memory;
905
0
                    gdata1.memory = font1->memory;
906
0
                    code0 = font0->cidata.glyph_data((gs_font_base *)font0, glyph, &gdata0, &fidx0);
907
0
                    code1 = font1->cidata.glyph_data((gs_font_base *)font1, glyph, &gdata1, &fidx1);
908
0
                    break;
909
0
                }
910
0
                default:
911
0
                    return_error(gs_error_unregistered); /* unimplemented */
912
0
            }
913
0
            if (code0 < 0) {
914
0
                if (code1 >= 0)
915
0
                    gs_glyph_data_free(&gdata1, "compare_glyphs");
916
0
                return code0;
917
0
            }
918
0
            if (code1 < 0) {
919
0
                if (code0 >= 0)
920
0
                    gs_glyph_data_free(&gdata0, "compare_glyphs");
921
0
                return code1;
922
0
            }
923
0
            if (gdata0.bits.size != gdata1.bits.size)
924
0
                return 0;
925
0
            if (memcmp(gdata0.bits.data, gdata0.bits.data, gdata0.bits.size))
926
0
                return 0;
927
0
            gs_glyph_data_free(&gdata0, "compare_glyphs");
928
0
            gs_glyph_data_free(&gdata1, "compare_glyphs");
929
0
        }
930
0
    }
931
0
    return 1;
932
0
}
933
934
/* ---------------- Individual FontTypes ---------------- */
935
936
/* ------ Type 1 ------ */
937
938
static int
939
copied_type1_glyph_data(gs_font_type1 * pfont, gs_glyph glyph,
940
                        gs_glyph_data_t *pgd)
941
0
{
942
0
    gs_copied_font_data_t *const cfdata = cf_data((gs_font *)pfont);
943
0
    gs_copied_glyph_t *pslot;
944
0
    int code = copied_glyph_slot(cfdata, glyph, &pslot);
945
946
0
    if (code < 0)
947
0
        return code;
948
0
    gs_glyph_data_from_string(pgd, pslot->gdata.data, pslot->gdata.size,
949
0
                              NULL);
950
0
    return 0;
951
0
}
952
953
static int
954
copied_type1_subr_data(gs_font_type1 * pfont, int subr_num, bool global,
955
                       gs_glyph_data_t *pgd)
956
0
{
957
0
    gs_copied_font_data_t *const cfdata = cf_data((gs_font *)pfont);
958
0
    const gs_subr_info_t *psi =
959
0
        (global ? &cfdata->global_subrs : &cfdata->subrs);
960
961
0
    if (subr_num < 0 || subr_num >= psi->count)
962
0
        return_error(gs_error_rangecheck);
963
0
    gs_glyph_data_from_string(pgd, psi->data + psi->starts[subr_num],
964
0
                              psi->starts[subr_num + 1] -
965
0
                                psi->starts[subr_num],
966
0
                              NULL);
967
0
    return 0;
968
0
}
969
970
static int
971
copied_type1_seac_data(gs_font_type1 * pfont, int ccode,
972
                       gs_glyph * pglyph, gs_const_string *gstr, gs_glyph_data_t *pgd)
973
0
{
974
    /*
975
     * This can only be invoked if the components have already been
976
     * copied to their proper positions, so it is simple.
977
     */
978
0
    gs_glyph glyph = gs_c_known_encode((gs_char)ccode, ENCODING_INDEX_STANDARD);
979
0
    gs_glyph glyph1;
980
0
    int code;
981
982
0
    if (glyph == GS_NO_GLYPH)
983
0
        return_error(gs_error_rangecheck);
984
0
    code = gs_c_glyph_name(glyph, gstr);
985
0
    if (code < 0)
986
0
        return code;
987
0
    code = pfont->dir->global_glyph_code((gs_font *)pfont, gstr, &glyph1);
988
0
    if (code < 0)
989
0
        return code;
990
0
    if (pglyph)
991
0
        *pglyph = glyph1;
992
0
    if (pgd)
993
0
        return copied_type1_glyph_data(pfont, glyph1, pgd);
994
0
    else
995
0
        return 0;
996
0
}
997
998
static int
999
copied_type1_push_values(void *callback_data, const fixed *values, int count)
1000
0
{
1001
0
    return_error(gs_error_unregistered);
1002
0
}
1003
1004
static int
1005
copied_type1_pop_value(void *callback_data, fixed *value)
1006
0
{
1007
0
    return_error(gs_error_unregistered);
1008
0
}
1009
1010
static int
1011
copy_font_type1(gs_font *font, gs_font *copied)
1012
0
{
1013
0
    gs_font_type1 *font1 = (gs_font_type1 *)font;
1014
0
    gs_font_type1 *copied1 = (gs_font_type1 *)copied;
1015
0
    gs_copied_font_data_t *const cfdata = cf_data(copied);
1016
0
    int code;
1017
1018
0
    cfdata->notdef = find_notdef((gs_font_base *)font);
1019
0
    code = copied_Encoding_alloc(copied);
1020
0
    if (code < 0)
1021
0
        return code;
1022
0
    if ((code = copy_subrs(font1, false, &cfdata->subrs, copied->memory)) < 0 ||
1023
0
        (code = copy_subrs(font1, true, &cfdata->global_subrs, copied->memory)) < 0
1024
0
        ) {
1025
0
        gs_free_object(copied->memory, cfdata->Encoding,
1026
0
                       "copy_font_type1(Encoding)");
1027
0
        return code;
1028
0
    }
1029
    /*
1030
     * We don't need real push/pop procedures, because we can't do anything
1031
     * useful with fonts that have non-standard OtherSubrs anyway.
1032
     */
1033
0
    copied1->data.procs.glyph_data = copied_type1_glyph_data;
1034
0
    copied1->data.procs.subr_data = copied_type1_subr_data;
1035
0
    copied1->data.procs.seac_data = copied_type1_seac_data;
1036
0
    copied1->data.procs.push_values = copied_type1_push_values;
1037
0
    copied1->data.procs.pop_value = copied_type1_pop_value;
1038
0
    copied1->data.proc_data = 0;
1039
0
    return 0;
1040
0
}
1041
1042
static int
1043
uncopy_glyph_type1(gs_font *font, gs_glyph glyph, gs_font *copied, int options)
1044
0
{
1045
0
    gs_copied_glyph_t *pcg = NULL;
1046
0
    gs_copied_font_data_t *cfdata = cf_data(copied);
1047
1048
0
    (void)copied_glyph_slot(cfdata, glyph, &pcg);
1049
0
    if (pcg != NULL) {
1050
0
        if (pcg->gdata.data != NULL) {
1051
0
            gs_free_string(copied->memory, (byte *)pcg->gdata.data, pcg->gdata.size, "Free copied glyph name");
1052
0
            pcg->gdata.size = 0;
1053
0
            pcg->gdata.data = NULL;
1054
0
        }
1055
0
        pcg->used = 0;
1056
0
        cfdata->num_glyphs--;
1057
0
    }
1058
0
    return 0;
1059
0
}
1060
1061
static int
1062
copy_glyph_type1(gs_font *font, gs_glyph glyph, gs_font *copied, int options)
1063
0
{
1064
0
    gs_glyph_data_t gdata;
1065
0
    gs_font_type1 *font1 = (gs_font_type1 *)font;
1066
0
    int code;
1067
0
    int rcode;
1068
1069
0
    gdata.memory = font->memory;
1070
0
    code = font1->data.procs.glyph_data(font1, glyph, &gdata);
1071
0
    if (code < 0)
1072
0
        return code;
1073
0
    code = copy_glyph_data(font, glyph, copied, options, &gdata, NULL, 0);
1074
0
    if (code < 0)
1075
0
        return code;
1076
0
    rcode = code;
1077
0
    if (code == 0)
1078
0
        code = copy_glyph_name(font, glyph, copied, glyph);
1079
0
    return (code < 0 ? code : rcode);
1080
0
}
1081
1082
static int
1083
copied_type1_glyph_outline(gs_font *font, int WMode, gs_glyph glyph,
1084
                           const gs_matrix *pmat, gx_path *ppath, double sbw[4])
1085
0
{   /*
1086
     * 'WMode' may be inherited from an upper font.
1087
     * We ignore in because Type 1,2 charstrings do not depend on it.
1088
     */
1089
1090
    /*
1091
     * This code duplicates much of zcharstring_outline in zchar1.c.
1092
     * This is unfortunate, but we don't see a simple way to refactor the
1093
     * code to avoid it.
1094
     */
1095
0
    gs_glyph_data_t gdata;
1096
0
    gs_font_type1 *const pfont1 = (gs_font_type1 *)font;
1097
0
    int code;
1098
0
    const gs_glyph_data_t *pgd = &gdata;
1099
0
    gs_type1_state cis;
1100
0
    gs_gstate ggs;
1101
1102
0
    memset(&cis, 0x00, sizeof(cis));
1103
1104
0
    gdata.memory = pfont1->memory;
1105
0
    code = pfont1->data.procs.glyph_data(pfont1, glyph, &gdata);
1106
0
    if (code < 0)
1107
0
        return code;
1108
0
    if (pgd->bits.size <= max(pfont1->data.lenIV, 0))
1109
0
        return_error(gs_error_invalidfont);
1110
    /* Initialize just enough of the gs_gstate. */
1111
0
    if (pmat)
1112
0
        gs_matrix_fixed_from_matrix(&ggs.ctm, pmat);
1113
0
    else {
1114
0
        gs_matrix imat;
1115
1116
0
        gs_make_identity(&imat);
1117
0
        gs_matrix_fixed_from_matrix(&ggs.ctm, &imat);
1118
0
    }
1119
0
    ggs.flatness = 0;
1120
0
    code = gs_type1_interp_init(&cis, &ggs, ppath, NULL, NULL, true, 0,
1121
0
                                pfont1);
1122
0
    if (code < 0)
1123
0
        return code;
1124
0
    cis.no_grid_fitting = true;
1125
    /* Continue interpreting. */
1126
0
    for (;;) {
1127
0
        int value;
1128
1129
0
        code = pfont1->data.interpret(&cis, pgd, &value);
1130
0
        switch (code) {
1131
0
        case 0:   /* all done */
1132
            /* falls through */
1133
0
        default:    /* code < 0, error */
1134
0
            return code;
1135
0
        case type1_result_callothersubr: /* unknown OtherSubr */
1136
0
            return_error(gs_error_rangecheck); /* can't handle it */
1137
0
        case type1_result_sbw: /* [h]sbw, just continue */
1138
0
            pgd = 0;
1139
0
            type1_cis_get_metrics(&cis, sbw);
1140
0
        }
1141
0
    }
1142
0
}
1143
1144
static const gs_copied_font_procs_t copied_procs_type1 = {
1145
    copy_font_type1, copy_glyph_type1, copied_char_add_encoding,
1146
    named_glyph_slot_hashed,
1147
    copied_encode_char, gs_type1_glyph_info, copied_type1_glyph_outline,
1148
    uncopy_glyph_type1
1149
};
1150
1151
static void hash_subrs(gs_font_type1 *pfont)
1152
0
{
1153
0
    gs_type1_data *d0 = &pfont->data;
1154
0
    gs_glyph_data_t gdata0;
1155
0
    gs_md5_state_t md5;
1156
0
    int i, exit = 0;
1157
1158
0
    gs_md5_init(&md5);
1159
0
    gdata0.memory = pfont->memory;
1160
    /* Scan the font to hash the global subrs. */
1161
0
    for (i = 0; !exit; i++) {
1162
0
        int code0 = pfont->data.procs.subr_data((gs_font_type1 *)pfont,
1163
0
                                                i, true, &gdata0);
1164
0
        if (code0 == gs_error_rangecheck)
1165
            /* rangecheck means we ran out of /Subrs */
1166
0
            exit = true;
1167
0
        if (code0 == gs_error_typecheck)
1168
            /* typecheck means that we may have encoutnered a null object
1169
             * for a Subr, we ignore this subr, but carry on hashing, as there
1170
             * may be more Subrs.
1171
             */
1172
0
            continue;
1173
0
        if (code0 < 0)
1174
0
            break;
1175
0
        else {
1176
0
            gs_md5_append(&md5, gdata0.bits.data, gdata0.bits.size);
1177
0
            gs_glyph_data_free(&gdata0, "hash_type1_subrs");
1178
0
        }
1179
0
    }
1180
    /* For a 'belt and braces' approach, we also record the number of local
1181
     * and global /Subrs, and compare these below as well. Shifting the global
1182
     * subrs up means that we can avoid an accidental co-incidence where simply
1183
     * summing the two sets together might give the same result for different fonts.
1184
     */
1185
0
    d0->num_subrs = i << 16;
1186
0
    exit = 0;
1187
    /* Scan the font to hash the local subrs. */
1188
0
    for (i = 0; !exit; i++) {
1189
0
        int code0 = pfont->data.procs.subr_data((gs_font_type1 *)pfont,
1190
0
                                                i, false, &gdata0);
1191
0
        if (code0 == gs_error_rangecheck)
1192
            /* rangecheck means we ran out of /Subrs */
1193
0
            exit = true;
1194
0
        if (code0 == gs_error_typecheck)
1195
            /* typecheck means that we may have encoutnered a null object
1196
             * for a Subr, we ignore this subr, but carry on hashing, as there
1197
             * may be more Subrs.
1198
             */
1199
0
            continue;
1200
0
        if (code0 < 0)
1201
0
            break;
1202
0
        else {
1203
0
            gs_md5_append(&md5, gdata0.bits.data, gdata0.bits.size);
1204
0
            gs_glyph_data_free(&gdata0, "hash_type1_subrs");
1205
0
        }
1206
0
    }
1207
0
    gs_md5_finish(&md5, d0->hash_subrs);
1208
0
    d0->num_subrs += i;
1209
0
}
1210
1211
static bool
1212
same_type1_hinting(const gs_font_type1 *cfont, const gs_font_type1 *ofont)
1213
0
{
1214
0
    const gs_type1_data *d0 = &cfont->data, *d1 = &ofont->data;
1215
0
    int *hash0 = (int *)&d0->hash_subrs;
1216
0
    int *hash1 = (int *)&d1->hash_subrs;
1217
1218
0
    if (d0->lenIV != d1->lenIV)
1219
0
        return false;
1220
    /*
1221
    if (d0->defaultWidthX != d1->defaultWidthX)
1222
        return false;
1223
    if (d0->nominalWidthX != d1->nominalWidthX)
1224
        return false;
1225
    */
1226
0
    if (d0->BlueFuzz != d1->BlueFuzz)
1227
0
        return false;
1228
0
    if (d0->BlueScale != d1->BlueScale)
1229
0
        return false;
1230
0
    if (d0->BlueShift != d1->BlueShift)
1231
0
        return false;
1232
0
    if (d0->ExpansionFactor != d1->ExpansionFactor)
1233
0
        return false;
1234
0
    if (d0->ForceBold != d1->ForceBold)
1235
0
        return false;
1236
0
    if (!compare_tables(d0->FamilyBlues, d1->FamilyBlues))
1237
0
        return false;
1238
0
    if (!compare_tables(d0->FamilyOtherBlues, d1->FamilyOtherBlues))
1239
0
        return false;
1240
0
    if (d0->LanguageGroup != d1->LanguageGroup)
1241
0
        return false;
1242
0
    if (!compare_tables(d0->OtherBlues, d1->OtherBlues))
1243
0
        return false;
1244
0
    if (d0->RndStemUp != d1->RndStemUp)
1245
0
        return false;
1246
0
    if (!compare_tables(d0->StdHW, d1->StdHW))
1247
0
        return false;
1248
0
    if (!compare_tables(d0->StemSnapH, d1->StemSnapH))
1249
0
        return false;
1250
0
    if (!compare_tables(d0->StemSnapV, d1->StemSnapV))
1251
0
        return false;
1252
0
    if (!compare_tables(d0->WeightVector, d1->WeightVector))
1253
0
        return false;
1254
0
    if (hash0[0] == 0x00 && hash0[1] == 0x00 && hash0[2] == 0x00 && hash0[3] == 0x00)
1255
0
        hash_subrs((gs_font_type1 *)cfont);
1256
0
    if (hash1[0] == 0x00 && hash1[1] == 0x00 && hash1[2] == 0x00 && hash1[3] == 0x00)
1257
0
        hash_subrs((gs_font_type1 *)ofont);
1258
0
    if (memcmp(d0->hash_subrs, d1->hash_subrs, 16) != 0 || d0->num_subrs != d1->num_subrs)
1259
0
        return false;
1260
1261
    /*
1262
     *  We ignore differences in OtherSubrs because pdfwrite
1263
     *  must build without PS interpreter and therefore copied font
1264
     *  have no storage for them.
1265
     */
1266
0
    return true;
1267
0
}
1268
1269
/* ------ Type 42 ------ */
1270
1271
static int
1272
copied_type42_string_proc(gs_font_type42 *font, ulong offset, uint len,
1273
                          const byte **pstr)
1274
0
{
1275
0
    gs_copied_font_data_t *const cfdata = font->data.proc_data;
1276
1277
0
    if (offset + len > cfdata->data_size)
1278
0
        return_error(gs_error_rangecheck);
1279
0
    *pstr = cfdata->data + offset;
1280
0
    return 0;
1281
0
}
1282
1283
static int
1284
copied_type42_get_outline(gs_font_type42 *font, uint glyph_index,
1285
                          gs_glyph_data_t *pgd)
1286
0
{
1287
0
    gs_copied_font_data_t *const cfdata = font->data.proc_data;
1288
0
    gs_copied_glyph_t *pcg;
1289
1290
0
    if (glyph_index >= cfdata->glyphs_size)
1291
0
        return_error(gs_error_rangecheck);
1292
0
    pcg = &cfdata->glyphs[glyph_index];
1293
0
    if (!pcg->used)
1294
0
        gs_glyph_data_from_null(pgd);
1295
0
    else
1296
0
        gs_glyph_data_from_string(pgd, pcg->gdata.data, pcg->gdata.size, NULL);
1297
0
    return 0;
1298
0
}
1299
1300
static int
1301
copied_type42_get_metrics(gs_font_type42 * pfont, uint glyph_index,
1302
                          gs_type42_metrics_options_t options, float *sbw)
1303
0
{
1304
    /* Check whether we have metrics for this (glyph,wmode) pair. */
1305
0
    gs_copied_font_data_t *const cfdata = pfont->data.proc_data;
1306
0
    gs_copied_glyph_t *pcg;
1307
0
    int wmode = gs_type42_metrics_options_wmode(options);
1308
1309
0
    if (glyph_index >= cfdata->glyphs_size)
1310
0
        return_error(gs_error_rangecheck);
1311
0
    pcg = &cfdata->glyphs[glyph_index];
1312
0
    if (!(pcg->used & (HAS_SBW0 << wmode)))
1313
0
        return_error(gs_error_undefined);
1314
0
    return gs_type42_default_get_metrics(pfont, glyph_index, options, sbw);
1315
0
}
1316
1317
static uint
1318
copied_type42_get_glyph_index(gs_font_type42 *font, gs_glyph glyph)
1319
0
{
1320
0
    gs_copied_font_data_t *const cfdata = cf_data((gs_font *)font);
1321
0
    gs_copied_glyph_t *pcg;
1322
0
    int code = copied_glyph_slot(cfdata, glyph, &pcg);
1323
1324
0
    if (code < 0)
1325
0
        return GS_NO_GLYPH;
1326
0
    return pcg - cfdata->glyphs;
1327
0
}
1328
1329
static int
1330
copy_font_type42(gs_font *font, gs_font *copied)
1331
0
{
1332
0
    gs_font_type42 *const font42 = (gs_font_type42 *)font;
1333
0
    gs_font_type42 *const copied42 = (gs_font_type42 *)copied;
1334
0
    gs_copied_font_data_t *const cfdata = cf_data(copied);
1335
    /*
1336
     * We "write" the font, aside from the glyphs, into an in-memory
1337
     * structure, and access it from there.
1338
     * We allocate room at the end of the copied data for fake hmtx/vmtx.
1339
     */
1340
0
    uint extra = font42->data.trueNumGlyphs * 8;
1341
0
    stream fs;
1342
0
    int code;
1343
1344
0
    cfdata->notdef = find_notdef((gs_font_base *)font);
1345
0
    code = copied_Encoding_alloc(copied);
1346
0
    if (code < 0)
1347
0
        return code;
1348
0
    s_init(&fs, font->memory);
1349
0
    swrite_position_only(&fs);
1350
0
    code = (font->FontType == ft_TrueType ? psf_write_truetype_stripped(&fs, font42)
1351
0
                                          : psf_write_cid2_stripped(&fs, (gs_font_cid2 *)font42));
1352
0
    code = copied_data_alloc(copied, &fs, extra, code);
1353
0
    if (code < 0)
1354
0
        goto fail;
1355
0
    if (font->FontType == ft_TrueType)
1356
0
        psf_write_truetype_stripped(&fs, font42);
1357
0
    else
1358
0
        psf_write_cid2_stripped(&fs, (gs_font_cid2 *)font42);
1359
0
    copied42->data.string_proc = copied_type42_string_proc;
1360
0
    copied42->data.proc_data = cfdata;
1361
0
    code = gs_type42_font_init(copied42, 0);
1362
0
    if (code < 0)
1363
0
        goto fail2;
1364
    /* gs_type42_font_init overwrites font_info. */
1365
0
    copied->procs.font_info = copied_font_info;
1366
    /* gs_type42_font_init overwrites enumerate_glyph. */
1367
0
    copied42->procs.enumerate_glyph = copied_enumerate_glyph;
1368
0
    copied42->data.get_glyph_index = copied_type42_get_glyph_index;
1369
0
    copied42->data.get_outline = copied_type42_get_outline;
1370
0
    copied42->data.get_metrics = copied_type42_get_metrics;
1371
0
    copied42->data.metrics[0].numMetrics =
1372
0
        copied42->data.metrics[1].numMetrics =
1373
0
        extra / 8;
1374
0
    copied42->data.metrics[0].offset = cfdata->data_size - extra;
1375
0
    copied42->data.metrics[1].offset = cfdata->data_size - extra / 2;
1376
0
    copied42->data.metrics[0].length =
1377
0
        copied42->data.metrics[1].length =
1378
0
        extra / 2;
1379
0
    memset(cfdata->data + cfdata->data_size - extra, 0, extra);
1380
0
    copied42->data.numGlyphs = font42->data.numGlyphs;
1381
0
    copied42->data.trueNumGlyphs = font42->data.trueNumGlyphs;
1382
0
    return 0;
1383
0
 fail2:
1384
0
    gs_free_object(copied->memory, cfdata->data,
1385
0
                   "copy_font_type42(data)");
1386
0
 fail:
1387
0
    gs_free_object(copied->memory, cfdata->Encoding,
1388
0
                   "copy_font_type42(Encoding)");
1389
0
    return code;
1390
0
}
1391
1392
static int uncopy_glyph_type42(gs_font *font, gs_glyph glyph, gs_font *copied, int options)
1393
0
{
1394
0
    gs_copied_glyph_t *pcg = NULL;
1395
0
    gs_font_type42 *font42 = (gs_font_type42 *)font;
1396
0
    gs_font_cid2 *fontCID2 = (gs_font_cid2 *)font;
1397
0
    gs_copied_font_data_t *cfdata = cf_data(copied);
1398
0
    uint gid = (options & COPY_GLYPH_BY_INDEX ? glyph - GS_MIN_GLYPH_INDEX :
1399
0
                font->FontType == ft_CID_TrueType
1400
0
                    ? fontCID2->cidata.CIDMap_proc(fontCID2, glyph)
1401
0
                    : font42->data.get_glyph_index(font42, glyph));
1402
1403
0
    (void)copied_glyph_slot(cfdata, gid + GS_MIN_GLYPH_INDEX, &pcg);
1404
0
    if (pcg != NULL) {
1405
0
        if (pcg->gdata.data != NULL) {
1406
0
            gs_free_string(copied->memory, (byte *)pcg->gdata.data, pcg->gdata.size, "Free copied glyph name");
1407
0
            pcg->gdata.size = 0;
1408
0
            pcg->gdata.data = NULL;
1409
0
        }
1410
0
        pcg->used = 0;
1411
0
        cfdata->num_glyphs--;
1412
0
    }
1413
1414
0
    return 0;
1415
0
}
1416
1417
static int
1418
copy_glyph_type42(gs_font *font, gs_glyph glyph, gs_font *copied, int options)
1419
0
{
1420
0
    gs_glyph_data_t gdata;
1421
0
    gs_font_type42 *font42 = (gs_font_type42 *)font;
1422
0
    gs_font_cid2 *fontCID2 = (gs_font_cid2 *)font;
1423
0
    gs_font_type42 *const copied42 = (gs_font_type42 *)copied;
1424
0
    uint gid = (options & COPY_GLYPH_BY_INDEX ? glyph - GS_MIN_GLYPH_INDEX :
1425
0
                font->FontType == ft_CID_TrueType
1426
0
                    ? fontCID2->cidata.CIDMap_proc(fontCID2, glyph)
1427
0
                    : font42->data.get_glyph_index(font42, glyph));
1428
0
    int code;
1429
0
    int rcode;
1430
0
    gs_copied_font_data_t *const cfdata = cf_data(copied);
1431
0
    gs_copied_glyph_t *pcg;
1432
0
    float sbw[4];
1433
0
    double factor = font42->data.unitsPerEm;
1434
0
    int i;
1435
1436
    /* If we've been told to, use the TrueType GSUB table to find a possible replacement
1437
     * glyph for the one which was supplied by the CMAP subtable. This is slightly useful
1438
     * when using a TrueType as a replacement for a missing CIDFont, the CMap defines
1439
     * vertical writing and there is a suitable vertical glyph available to use as a
1440
     * replacement for a horizontal glyph (punctuation, basically). Not a common
1441
     * situation, of rather limited value, but....
1442
     */
1443
0
    if (!(options & COPY_GLYPH_BY_INDEX) && (options & COPY_GLYPH_USE_GSUB) && font->FontType == ft_CID_TrueType)
1444
0
        gid = fontCID2->data.substitute_glyph_index_vertical((gs_font_type42 *)font, gid, font->WMode, glyph);
1445
1446
0
    gdata.memory = font42->memory;
1447
0
    code = font42->data.get_outline(font42, gid, &gdata);
1448
    /* If the glyph is a /.notdef, and the GID is not 0, and we failed to find
1449
     * the /.notdef, try again with GID 0. We have seen fonts from GraphPad
1450
     * Prism which end up putting the /.notdef in the CharStrings dictionary
1451
     * with the wrong GID value (Bug #691573)
1452
     */
1453
0
    if (code < 0 && gid != 0) {
1454
0
        gs_const_string gnstr;
1455
0
        if (font->procs.glyph_name(font, glyph, &gnstr) >= 0 && gnstr.size == 7
1456
0
            && !memcmp(gnstr.data, ".notdef", 7)) {
1457
0
            gid = 0;
1458
0
            code = font42->data.get_outline(font42, gid, &gdata);
1459
0
        }
1460
0
    }
1461
0
    if (code < 0)
1462
0
        return code;
1463
1464
0
    code = copy_glyph_data(font, gid + GS_MIN_GLYPH_INDEX, copied, options,
1465
0
                           &gdata, NULL, 0);
1466
0
    if (code < 0)
1467
0
        return code;
1468
0
    rcode = code;
1469
0
    if (glyph < GS_MIN_CID_GLYPH)
1470
0
        code = copy_glyph_name(font, glyph, copied,
1471
0
                               gid + GS_MIN_GLYPH_INDEX);
1472
0
    DISCARD(copied_glyph_slot(cfdata, gid + GS_MIN_GLYPH_INDEX, &pcg)); /* can't fail */
1473
0
    for (i = 0; i < 2; ++i) {
1474
0
        if (font42->data.get_metrics(font42, gid, i, sbw) >= 0) {
1475
0
            int sb = (int)(sbw[i] * factor + 0.5);
1476
0
            uint width = (uint)(sbw[2 + i] * factor + 0.5);
1477
0
            byte *pmetrics =
1478
0
                cfdata->data + copied42->data.metrics[i].offset + gid * 4;
1479
1480
0
            pmetrics[0] = (byte)(width >> 8);
1481
0
            pmetrics[1] = (byte)width;
1482
0
            pmetrics[2] = (byte)(sb >> 8);
1483
0
            pmetrics[3] = (byte)sb;
1484
0
            pcg->used |= HAS_SBW0 << i;
1485
0
        }
1486
0
        factor = -factor; /* values are negated for WMode = 1 */
1487
0
    }
1488
0
    return (code < 0 ? code : rcode);
1489
0
}
1490
1491
static gs_glyph
1492
copied_type42_encode_char(gs_font *copied, gs_char chr,
1493
                          gs_glyph_space_t glyph_space)
1494
0
{
1495
0
    gs_copied_font_data_t *const cfdata = cf_data(copied);
1496
0
    const gs_glyph *Encoding = cfdata->Encoding;
1497
0
    gs_glyph glyph;
1498
1499
0
    if (chr >= 256 || Encoding == 0)
1500
0
        return GS_NO_GLYPH;
1501
0
    glyph = Encoding[chr];
1502
0
    if (glyph_space == GLYPH_SPACE_INDEX) {
1503
        /* Search linearly for the glyph by name. */
1504
0
        gs_copied_glyph_t *pcg;
1505
0
        int code = named_glyph_slot_linear(cfdata, glyph, &pcg);
1506
1507
0
        if (code < 0 || !pcg->used)
1508
0
            return GS_NO_GLYPH;
1509
0
        return GS_MIN_GLYPH_INDEX + (pcg - cfdata->glyphs);
1510
0
    }
1511
0
    return glyph;
1512
0
}
1513
1514
static const gs_copied_font_procs_t copied_procs_type42 = {
1515
    copy_font_type42, copy_glyph_type42, copied_char_add_encoding,
1516
    named_glyph_slot_linear,
1517
    copied_type42_encode_char, gs_type42_glyph_info, gs_type42_glyph_outline,
1518
    uncopy_glyph_type42
1519
};
1520
1521
static inline int
1522
access_type42_data(gs_font_type42 *pfont, ulong base, ulong length,
1523
                   const byte **vptr)
1524
0
{
1525
0
    return pfont->data.string_proc(pfont, base, length, vptr);
1526
0
}
1527
1528
static inline uint
1529
U16(const byte *p)
1530
0
{
1531
0
    return ((uint)p[0] << 8) + p[1];
1532
0
}
1533
1534
static int
1535
same_maxp_values(gs_font_type42 *font0, gs_font_type42 *font1)
1536
0
{
1537
0
    gs_type42_data *d0 = &font0->data, *d1 = &font1->data;
1538
1539
0
    if (d0->maxPoints < d1->maxPoints)
1540
0
        return 0;
1541
0
    if (d0->maxContours < d1->maxContours)
1542
0
        return 0;
1543
0
    if (d0->maxCPoints < d1->maxCPoints)
1544
0
        return 0;
1545
0
    if (d0->maxCContours < d1->maxCContours)
1546
0
        return 0;
1547
0
    return 1;
1548
0
}
1549
1550
static int
1551
same_type42_hinting(gs_font_type42 *font0, gs_font_type42 *font1)
1552
0
{
1553
0
    gs_type42_data *d0 = &font0->data, *d1 = &font1->data;
1554
0
    gs_font_type42 *font[2];
1555
0
    uint pos[2][3];
1556
0
    uint len[2][3] = {{0,0,0}, {0,0,0}};
1557
0
    int i, j, code;
1558
1559
0
    if (d0->unitsPerEm != d1->unitsPerEm)
1560
0
        return 0;
1561
0
    font[0] = font0;
1562
0
    font[1] = font1;
1563
0
    memset(pos, 0, sizeof(pos));
1564
0
    for (j = 0; j < 2; j++) {
1565
0
        const byte *OffsetTable;
1566
0
        uint numTables;
1567
1568
0
        code = access_type42_data(font[j], font[j]->data.subfontOffset, 12, &OffsetTable);
1569
0
        if (code < 0)
1570
0
            return code;
1571
0
        numTables = U16(OffsetTable + 4);
1572
0
        for (i = 0; i < numTables; ++i) {
1573
0
            const byte *tab;
1574
0
            ulong start;
1575
0
            uint length;
1576
1577
0
            code = access_type42_data(font[j], font[j]->data.subfontOffset + 12 + i * 16, 16, &tab);
1578
0
            if (code < 0)
1579
0
                return code;
1580
0
            start = get_u32_msb(tab + 8);
1581
0
            length = get_u32_msb(tab + 12);
1582
0
            if (!memcmp("prep", tab, 4))
1583
0
                pos[j][0] = start, len[j][0] = length;
1584
0
            else if (!memcmp("cvt ", tab, 4))
1585
0
                pos[j][1] = start, len[j][1] = length;
1586
0
            else if (!memcmp("fpgm", tab, 4))
1587
0
                pos[j][2] = start, len[j][2] = length;
1588
0
        }
1589
0
    }
1590
0
    for (i = 0; i < 3; i++) {
1591
0
        if (len[0][i] != len[1][i])
1592
0
            return 0;
1593
0
    }
1594
0
    for (i = 0; i < 3; i++) {
1595
0
        if (len[0][i] != 0) {
1596
0
            const byte *data0, *data1;
1597
0
            ulong length = len[0][i], size0, size1, size;
1598
0
            ulong pos0 = pos[0][i], pos1 = pos[1][i];
1599
1600
0
            while (length > 0) {
1601
0
                code = access_type42_data(font0, pos0, length, &data0);
1602
0
                if (code < 0)
1603
0
                    return code;
1604
0
                size0 = (code == 0 ? length : code);
1605
0
                code = access_type42_data(font1, pos1, length, &data1);
1606
0
                if (code < 0)
1607
0
                    return code;
1608
0
                size1 = (code == 0 ? length : code);
1609
0
                size = min(size0, size1);
1610
0
                if (memcmp(data0, data1, size))
1611
0
                    return 0;
1612
0
                pos0 += size;
1613
0
                pos1 += size;
1614
0
                length -= size;
1615
0
            }
1616
0
        }
1617
0
    }
1618
0
    return 1;
1619
0
}
1620
1621
/* ------ CIDFont shared ------ */
1622
1623
static int
1624
copy_font_cid_common(gs_font *font, gs_font *copied, gs_font_cid_data *pcdata)
1625
0
{
1626
0
    return (copy_string(copied->memory, &pcdata->CIDSystemInfo.Registry,
1627
0
                        "Registry") |
1628
0
            copy_string(copied->memory, &pcdata->CIDSystemInfo.Ordering,
1629
0
                        "Ordering"));
1630
0
}
1631
1632
/* ------ CIDFontType 0 ------ */
1633
1634
static int
1635
copied_cid0_glyph_data(gs_font_base *font, gs_glyph glyph,
1636
                       gs_glyph_data_t *pgd, int *pfidx)
1637
0
{
1638
0
    gs_font_cid0 *fcid0 = (gs_font_cid0 *)font;
1639
0
    gs_copied_font_data_t *const cfdata = cf_data((gs_font *)font);
1640
0
    gs_copied_glyph_t *pcg;
1641
0
    int code = copied_glyph_slot(cfdata, glyph, &pcg);
1642
0
    int fdbytes = fcid0->cidata.FDBytes;
1643
0
    int i;
1644
1645
0
    if (pfidx)
1646
0
        *pfidx = 0;
1647
0
    if (code < 0) {
1648
0
        if (pgd)
1649
0
            gs_glyph_data_from_null(pgd);
1650
0
        return_error(gs_error_undefined);
1651
0
    }
1652
0
    if (pfidx)
1653
0
        for (i = 0; i < fdbytes; ++i)
1654
0
            *pfidx = (*pfidx << 8) + pcg->gdata.data[i];
1655
0
    if (pgd)
1656
0
        gs_glyph_data_from_string(pgd, pcg->gdata.data + fdbytes,
1657
0
                                  pcg->gdata.size - fdbytes, NULL);
1658
0
    return 0;
1659
0
}
1660
static int
1661
copied_sub_type1_glyph_data(gs_font_type1 * pfont, gs_glyph glyph,
1662
                            gs_glyph_data_t *pgd)
1663
0
{
1664
0
    return
1665
0
      copied_cid0_glyph_data((gs_font_base *)cf_data((gs_font *)pfont)->parent,
1666
0
                             glyph, pgd, NULL);
1667
0
}
1668
1669
static int
1670
cid0_subfont(gs_font *copied, gs_glyph glyph, gs_font_type1 **pfont1)
1671
0
{
1672
0
    int fidx;
1673
0
    int code = copied_cid0_glyph_data((gs_font_base *)copied, glyph, NULL,
1674
0
                                      &fidx);
1675
1676
0
    if (code >= 0) {
1677
0
        gs_font_cid0 *font0 = (gs_font_cid0 *)copied;
1678
1679
0
        if (fidx >= font0->cidata.FDArray_size)
1680
0
            return_error(gs_error_unregistered); /* Must not happen. */
1681
0
        *pfont1 = font0->cidata.FDArray[fidx];
1682
0
    }
1683
0
    return code;
1684
0
}
1685
1686
static int
1687
copied_cid0_glyph_info(gs_font *font, gs_glyph glyph, const gs_matrix *pmat,
1688
                       int members, gs_glyph_info_t *info)
1689
0
{
1690
0
    gs_font_type1 *subfont1;
1691
0
    int code = cid0_subfont(font, glyph, &subfont1);
1692
1693
0
    if (code < 0)
1694
0
        return code;
1695
0
    if (members & GLYPH_INFO_WIDTH1) {
1696
        /* Hack : There is no way to pass WMode from font to glyph_info,
1697
         * and usually CID font has no metrics for WMode 1.
1698
         * Therefore we use FontBBox as default size.
1699
         * Warning : this incompletely implements the request :
1700
         * other requested members are not retrieved.
1701
         */
1702
0
        gs_font_info_t finfo;
1703
0
        int code = subfont1->procs.font_info(font, NULL, FONT_INFO_BBOX, &finfo);
1704
1705
0
        if (code < 0)
1706
0
            return code;
1707
0
        info->width[0].x = 0;
1708
0
        info->width[0].y = 0;
1709
0
        info->width[1].x = 0;
1710
0
        info->width[1].y = -finfo.BBox.q.x; /* Sic! */
1711
0
        info->v.x = finfo.BBox.q.x / 2;
1712
0
        info->v.y = finfo.BBox.q.y;
1713
0
        info->members = GLYPH_INFO_WIDTH1;
1714
0
        return 0;
1715
0
    }
1716
0
    return subfont1->procs.glyph_info((gs_font *)subfont1, glyph, pmat,
1717
0
                                      members, info);
1718
0
}
1719
1720
static int
1721
copied_cid0_glyph_outline(gs_font *font, int WMode, gs_glyph glyph,
1722
                          const gs_matrix *pmat, gx_path *ppath, double sbw[4])
1723
0
{
1724
0
    gs_font_type1 *subfont1;
1725
0
    int code = cid0_subfont(font, glyph, &subfont1);
1726
1727
0
    if (code < 0)
1728
0
        return code;
1729
0
    return subfont1->procs.glyph_outline((gs_font *)subfont1, WMode, glyph, pmat,
1730
0
                                         ppath, sbw);
1731
0
}
1732
1733
static int
1734
copy_font_cid0(gs_font *font, gs_font *copied)
1735
0
{
1736
0
    gs_font_cid0 *copied0 = (gs_font_cid0 *)copied;
1737
0
    gs_copied_font_data_t *const cfdata = cf_data(copied);
1738
0
    gs_font_type1 **FDArray =
1739
0
        gs_alloc_struct_array(copied->memory, copied0->cidata.FDArray_size,
1740
0
                              gs_font_type1 *,
1741
0
                              &st_gs_font_type1_ptr_element, "FDArray");
1742
0
    int i = 0, code;
1743
1744
0
    if (FDArray == 0)
1745
0
        return_error(gs_error_VMerror);
1746
0
    code = copy_font_cid_common(font, copied, &copied0->cidata.common);
1747
0
    if (code < 0)
1748
0
        goto fail;
1749
0
    for (; i < copied0->cidata.FDArray_size; ++i) {
1750
0
        gs_font *subfont = (gs_font *)copied0->cidata.FDArray[i];
1751
0
        gs_font_type1 *subfont1 = (gs_font_type1 *)subfont;
1752
0
        gs_font *subcopy;
1753
0
        gs_font_type1 *subcopy1;
1754
0
        gs_copied_font_data_t *subdata;
1755
1756
0
        if (i == 0) {
1757
            /* copy_subrs requires a Type 1 font, even for GSubrs. */
1758
0
            code = copy_subrs(subfont1, true, &cfdata->global_subrs,
1759
0
                              copied->memory);
1760
0
            if (code < 0)
1761
0
                goto fail;
1762
0
        }
1763
0
        code = gs_copy_font(subfont, &subfont->FontMatrix, copied->memory, &subcopy, -1);
1764
0
        if (code < 0)
1765
0
            goto fail;
1766
0
        subcopy1 = (gs_font_type1 *)subcopy;
1767
0
        subcopy1->data.parent = NULL;
1768
0
        subdata = cf_data(subcopy);
1769
0
        subdata->parent = copied0;
1770
0
        gs_free_object(copied->memory, subdata->Encoding,
1771
0
                       "copy_font_cid0(Encoding)");
1772
0
        subdata->Encoding = 0;
1773
        /*
1774
         * Share the glyph data and global_subrs with the parent.  This
1775
         * allows copied_type1_glyph_data in the subfont to do the right
1776
         * thing.
1777
         */
1778
0
        gs_free_object(copied->memory, subdata->names,
1779
0
                       "copy_font_cid0(subfont names)");
1780
0
        gs_free_object(copied->memory, subdata->glyphs,
1781
0
                       "copy_font_cid0(subfont glyphs)");
1782
0
        subcopy1->data.procs.glyph_data = copied_sub_type1_glyph_data;
1783
0
        subdata->glyphs = cfdata->glyphs;
1784
0
        subdata->glyphs_size = cfdata->glyphs_size;
1785
0
        subdata->names = 0;
1786
0
        if (subdata->global_subrs.data != NULL)
1787
0
            gs_free_object(copied->memory, subdata->global_subrs.data, "copy parent global subrs to child, free child global subrs");
1788
0
        if (subdata->global_subrs.starts != NULL)
1789
0
            gs_free_object(copied->memory, subdata->global_subrs.starts, "copy parent global subrs to child, free child global subrs");
1790
0
        subdata->global_subrs = cfdata->global_subrs;
1791
0
        FDArray[i] = subcopy1;
1792
0
    }
1793
0
    cfdata->notdef = GS_MIN_CID_GLYPH;
1794
0
    copied0->cidata.FDArray = FDArray;
1795
0
    copied0->cidata.FDBytes =
1796
0
        (copied0->cidata.FDArray_size <= 1 ? 0 :
1797
0
         copied0->cidata.FDArray_size <= 256 ? 1 : 2);
1798
0
    copied0->cidata.glyph_data = copied_cid0_glyph_data;
1799
0
    return 0;
1800
0
 fail:
1801
0
    while (--i >= 0)
1802
0
        gs_free_object(copied->memory, FDArray[i], "copy_font_cid0(subfont)");
1803
0
    gs_free_object(copied->memory, FDArray, "FDArray");
1804
0
    return code;
1805
0
}
1806
1807
static int
1808
uncopy_glyph_cid0(gs_font *font, gs_glyph glyph, gs_font *copied, int options)
1809
0
{
1810
0
    gs_copied_glyph_t *pcg = NULL;
1811
0
    gs_copied_font_data_t *cfdata = cf_data(copied);
1812
1813
0
    (void)copied_glyph_slot(cfdata, glyph, &pcg);
1814
0
    if (pcg != NULL) {
1815
0
        if (pcg->gdata.data != NULL) {
1816
0
            gs_free_string(copied->memory, (byte *)pcg->gdata.data, pcg->gdata.size, "Free copied glyph name");
1817
0
            pcg->gdata.size = 0;
1818
0
            pcg->gdata.data = NULL;
1819
0
        }
1820
0
        pcg->used = 0;
1821
0
        cfdata->num_glyphs--;
1822
0
    }
1823
0
    return 0;
1824
0
}
1825
1826
static int
1827
copy_glyph_cid0(gs_font *font, gs_glyph glyph, gs_font *copied, int options)
1828
0
{
1829
0
    gs_glyph_data_t gdata;
1830
0
    gs_font_cid0 *fcid0 = (gs_font_cid0 *)font;
1831
0
    gs_font_cid0 *copied0 = (gs_font_cid0 *)copied;
1832
0
    int fdbytes = copied0->cidata.FDBytes;
1833
0
    int fidx;
1834
0
    int code;
1835
0
    byte prefix[MAX_FDBytes];
1836
0
    int i;
1837
1838
0
    gdata.memory = font->memory;
1839
0
    code = fcid0->cidata.glyph_data((gs_font_base *)font, glyph,
1840
0
                &gdata, &fidx);
1841
0
    if (code < 0)
1842
0
        return code;
1843
0
    for (i = fdbytes - 1; i >= 0; --i, fidx >>= 8)
1844
0
        prefix[i] = (byte)fidx;
1845
0
    if (fidx != 0)
1846
0
        return_error(gs_error_rangecheck);
1847
0
    return copy_glyph_data(font, glyph, copied, options, &gdata, prefix, fdbytes);
1848
0
}
1849
1850
static const gs_copied_font_procs_t copied_procs_cid0 = {
1851
    copy_font_cid0, copy_glyph_cid0, copied_no_add_encoding,
1852
    named_glyph_slot_none,
1853
    gs_no_encode_char, copied_cid0_glyph_info, copied_cid0_glyph_outline,
1854
    uncopy_glyph_cid0
1855
};
1856
1857
static int
1858
same_cid0_hinting(const gs_font_cid0 *cfont, const gs_font_cid0 *ofont)
1859
0
{
1860
0
    int i;
1861
1862
0
    if (cfont->cidata.FDArray_size != ofont->cidata.FDArray_size)
1863
0
        return 0;
1864
1865
0
    for (i = 0; i < cfont->cidata.FDArray_size; i++) {
1866
0
        gs_font_type1 *subfont0 = cfont->cidata.FDArray[i];
1867
0
        gs_font_type1 *subfont1 = ofont->cidata.FDArray[i];
1868
0
        if (!same_type1_hinting(subfont0, subfont1))
1869
0
            return 0;
1870
0
    }
1871
0
    return 1;
1872
0
}
1873
1874
/* ------ CIDFontType 2 ------ */
1875
1876
static int
1877
copied_cid2_CIDMap_proc(gs_font_cid2 *fcid2, gs_glyph glyph)
1878
0
{
1879
0
    uint cid = glyph - GS_MIN_CID_GLYPH;
1880
0
    gs_copied_font_data_t *const cfdata = cf_data((gs_font *)fcid2);
1881
0
    const ushort *CIDMap = cfdata->CIDMap;
1882
1883
0
    if (glyph < GS_MIN_CID_GLYPH || cid >= fcid2->cidata.common.CIDCount)
1884
0
        return_error(gs_error_rangecheck);
1885
0
    if (CIDMap[cid] == 0xffff)
1886
0
        return -1;
1887
0
    return CIDMap[cid];
1888
0
}
1889
1890
static uint
1891
copied_cid2_get_glyph_index(gs_font_type42 *font, gs_glyph glyph)
1892
0
{
1893
0
    int glyph_index = copied_cid2_CIDMap_proc((gs_font_cid2 *)font, glyph);
1894
1895
0
    if (glyph_index < 0)
1896
0
        return GS_NO_GLYPH;
1897
0
    return glyph_index;
1898
0
}
1899
1900
extern_st(st_subst_CID_on_WMode);
1901
1902
static int
1903
copy_font_cid2(gs_font *font, gs_font *copied)
1904
0
{
1905
0
    gs_font_cid2 *copied2 = (gs_font_cid2 *)copied;
1906
0
    gs_copied_font_data_t *const cfdata = cf_data(copied);
1907
0
    int code;
1908
0
    int CIDCount = copied2->cidata.common.CIDCount;
1909
0
    ushort *CIDMap = (ushort *)
1910
0
        gs_alloc_byte_array(copied->memory, CIDCount, sizeof(ushort),
1911
0
                            "copy_font_cid2(CIDMap");
1912
1913
0
    if (CIDMap == 0)
1914
0
        return_error(gs_error_VMerror);
1915
0
    code = copy_font_cid_common(font, copied, &copied2->cidata.common);
1916
0
    if (code < 0 ||
1917
0
        (code = copy_font_type42(font, copied)) < 0
1918
0
        ) {
1919
0
        gs_free_object(copied->memory, CIDMap, "copy_font_cid2(CIDMap");
1920
0
        return code;
1921
0
    }
1922
0
    cfdata->notdef = GS_MIN_CID_GLYPH;
1923
0
    memset(CIDMap, 0xff, CIDCount * sizeof(*CIDMap));
1924
0
    cfdata->CIDMap = CIDMap;
1925
0
    copied2->cidata.MetricsCount = 0;
1926
0
    copied2->cidata.CIDMap_proc = copied_cid2_CIDMap_proc;
1927
0
    {
1928
0
        gs_font_type42 *const copied42 = (gs_font_type42 *)copied;
1929
1930
0
        copied42->data.get_glyph_index = copied_cid2_get_glyph_index;
1931
0
    }
1932
0
    if (copied2->subst_CID_on_WMode) {
1933
0
        gs_subst_CID_on_WMode_t *subst = NULL;
1934
1935
0
        rc_alloc_struct_1(subst, gs_subst_CID_on_WMode_t, &st_subst_CID_on_WMode,
1936
0
                            copied2->memory, return_error(gs_error_VMerror), "copy_font_cid2");
1937
0
        subst->data[0] = subst->data[1] = 0;
1938
0
        copied2->subst_CID_on_WMode = subst;
1939
0
    }
1940
1941
0
    return 0;
1942
0
}
1943
1944
static int expand_CIDMap(gs_font_cid2 *copied2, uint CIDCount)
1945
0
{
1946
0
    ushort *CIDMap;
1947
0
    gs_copied_font_data_t *const cfdata = cf_data((gs_font *)copied2);
1948
1949
0
    if (CIDCount <= copied2->cidata.common.CIDCount)
1950
0
        return 0;
1951
0
    CIDMap = (ushort *)
1952
0
        gs_alloc_byte_array(copied2->memory, CIDCount, sizeof(ushort),
1953
0
                            "expand_CIDMap(new CIDMap)");
1954
0
    if (CIDMap == 0)
1955
0
        return_error(gs_error_VMerror);
1956
0
    memcpy(CIDMap, cfdata->CIDMap, copied2->cidata.common.CIDCount * sizeof(*CIDMap));
1957
0
    memset(CIDMap + copied2->cidata.common.CIDCount, 0xFF,
1958
0
            (CIDCount - copied2->cidata.common.CIDCount) * sizeof(*CIDMap));
1959
0
    gs_free_object(copied2->memory, cfdata->CIDMap, "expand_CIDMap(old CIDMap)");
1960
0
    cfdata->CIDMap = CIDMap;
1961
0
    copied2->cidata.common.CIDCount = CIDCount;
1962
0
    return 0;
1963
0
}
1964
1965
static int
1966
uncopy_glyph_cid2(gs_font *font, gs_glyph glyph, gs_font *copied, int options)
1967
0
{
1968
0
    gs_copied_glyph_t *pcg = NULL;
1969
0
    gs_copied_font_data_t *cfdata = cf_data(copied);
1970
1971
0
    (void)copied_glyph_slot(cf_data(copied), glyph, &pcg);
1972
0
    if (pcg != NULL) {
1973
0
        if (pcg->gdata.data != NULL) {
1974
0
            gs_free_string(copied->memory, (byte *)pcg->gdata.data, pcg->gdata.size, "Free copied glyph name");
1975
0
            pcg->gdata.size = 0;
1976
0
            pcg->gdata.data = NULL;
1977
0
        }
1978
0
        pcg->used = 0;
1979
0
        cfdata->num_glyphs--;
1980
0
    }
1981
0
    return 0;
1982
0
}
1983
1984
static int
1985
copy_glyph_cid2(gs_font *font, gs_glyph glyph, gs_font *copied, int options)
1986
0
{
1987
0
    gs_font_cid2 *fcid2 = (gs_font_cid2 *)font;
1988
0
    gs_copied_font_data_t *const cfdata = cf_data(copied);
1989
0
    gs_font_cid2 *copied2 = (gs_font_cid2 *)copied;
1990
0
    int gid;
1991
0
    int code;
1992
1993
0
    if (!(options & COPY_GLYPH_BY_INDEX)) {
1994
0
        uint cid = glyph - GS_MIN_CID_GLYPH;
1995
0
        int CIDCount;
1996
1997
0
        code = expand_CIDMap(copied2, cid + 1);
1998
0
        if (code < 0)
1999
0
            return code;
2000
0
        CIDCount = copied2->cidata.common.CIDCount;
2001
0
        gid = fcid2->cidata.CIDMap_proc(fcid2, glyph);
2002
        /* If we've been told to, use the TrueType GSUB table to find a possible replacement
2003
         * glyph for the one which was supplied by the CMAP subtable. This is slightly useful
2004
         * when using a TrueType as a replacement for a missing CIDFont, the CMap defines
2005
         * vertical writing and there is a suitable vertical glyph available to use as a
2006
         * replacement for a horizontal glyph (punctuation, basically). Not a common
2007
         * situation, of rather limited value, but....
2008
         */
2009
0
        if (options & COPY_GLYPH_USE_GSUB)
2010
0
            gid = ((gs_font_cid2 *)font)->data.substitute_glyph_index_vertical((gs_font_type42 *)font, gid, font->WMode, glyph);
2011
0
        if (gid < 0 || gid >= cfdata->glyphs_size)
2012
0
            return_error(gs_error_rangecheck);
2013
0
        if (cid > CIDCount)
2014
0
            return_error(gs_error_invalidaccess);
2015
0
        if (cfdata->CIDMap[cid] != 0xffff && cfdata->CIDMap[cid] != gid)
2016
0
            return_error(gs_error_invalidaccess);
2017
0
        code = copy_glyph_type42(font, glyph, copied, options);
2018
0
        if (code < 0)
2019
0
            return code;
2020
0
        cfdata->CIDMap[cid] = gid;
2021
0
    } else {
2022
0
        gid = glyph - GS_MIN_GLYPH_INDEX;
2023
0
        if (gid < 0 || gid >= cfdata->glyphs_size)
2024
0
            return_error(gs_error_rangecheck);
2025
0
        code = copy_glyph_type42(font, glyph, copied, options);
2026
0
        if (code < 0)
2027
0
            return code;
2028
0
    }
2029
0
    return code;
2030
0
}
2031
2032
static const gs_copied_font_procs_t copied_procs_cid2 = {
2033
    copy_font_cid2, copy_glyph_cid2, copied_no_add_encoding,
2034
    named_glyph_slot_none,
2035
    gs_no_encode_char, gs_type42_glyph_info, gs_type42_glyph_outline,
2036
    uncopy_glyph_cid2
2037
};
2038
2039
static int
2040
same_cid2_hinting(const gs_font_cid2 *cfont, const gs_font_cid2 *ofont)
2041
0
{
2042
0
    return same_type42_hinting((gs_font_type42 *)cfont, (gs_font_type42 *)ofont);
2043
0
}
2044
2045
/* ---------------- Public ---------------- */
2046
2047
/*
2048
 * Procedure vector for copied fonts.
2049
 */
2050
static font_proc_font_info(copied_font_info);
2051
static font_proc_enumerate_glyph(copied_enumerate_glyph);
2052
static const gs_font_procs copied_font_procs = {
2053
    0,        /* define_font, not supported */
2054
    0,        /* make_font, not supported */
2055
    copied_font_info,
2056
    gs_default_same_font,
2057
    0,        /* encode_char, varies by FontType */
2058
    0,        /* decode_char, not supported */
2059
    copied_enumerate_glyph,
2060
    0,        /* glyph_info, varies by FontType */
2061
    0,        /* glyph_outline, varies by FontType */
2062
    copied_glyph_name,
2063
    gs_default_init_fstack,
2064
    gs_default_next_char_glyph,
2065
    copied_build_char
2066
};
2067
2068
#if GLYPHS_SIZE_IS_PRIME
2069
static const int some_primes[] = {
2070
    /* Arbitrary choosen prime numbers, being reasonable for a Type 1|2 font size.
2071
       We start with 257 to fit 256 glyphs and .notdef .
2072
       Smaller numbers aren't useful, because we don't know whether a font
2073
       will add more glyphs incrementally when we allocate its stable copy.
2074
    */
2075
    257, 359, 521, 769, 1031, 2053,
2076
    3079, 4099, 5101, 6101, 7109, 8209, 10007, 12007, 14009,
2077
    16411, 20107, 26501, 32771, 48857, 65537, 85229, 127837};
2078
#endif
2079
2080
/*
2081
 * Copy a font, aside from its glyphs.
2082
 */
2083
int
2084
gs_copy_font(gs_font *font, const gs_matrix *orig_matrix, gs_memory_t *mem, gs_font **pfont_new, int max_reserved_glyphs)
2085
0
{
2086
0
    gs_memory_type_ptr_t fstype = gs_object_type(font->memory, font);
2087
0
    uint fssize = gs_struct_type_size(fstype);
2088
0
    gs_font *copied = 0;
2089
0
    gs_copied_font_data_t *cfdata = 0;
2090
0
    gs_font_info_t info;
2091
0
    gs_copied_glyph_t *glyphs = 0;
2092
0
    uint glyphs_size;
2093
0
    gs_copied_glyph_name_t *names = 0;
2094
0
    bool have_names = false;
2095
0
    const gs_copied_font_procs_t *procs;
2096
0
    int code;
2097
2098
    /*
2099
     * Check for a supported FontType, and compute the size of its
2100
     * copied glyph table.
2101
     */
2102
0
    switch (font->FontType) {
2103
0
    case ft_TrueType:
2104
0
        procs = &copied_procs_type42;
2105
0
        glyphs_size = ((gs_font_type42 *)font)->data.trueNumGlyphs;
2106
0
        have_names = true;
2107
0
        break;
2108
0
    case ft_encrypted:
2109
0
    case ft_encrypted2:
2110
0
        procs = &copied_procs_type1;
2111
        /* Count the glyphs. */
2112
0
        glyphs_size = 0;
2113
0
        {
2114
0
            int index = 0;
2115
0
            gs_glyph glyph;
2116
2117
0
            while (font->procs.enumerate_glyph(font, &index, GLYPH_SPACE_NAME,
2118
0
                                               &glyph), index != 0)
2119
0
                ++glyphs_size;
2120
0
        }
2121
0
        if(glyphs_size > max_reserved_glyphs && max_reserved_glyphs != -1)
2122
0
            glyphs_size = max_reserved_glyphs;
2123
2124
0
#if GLYPHS_SIZE_IS_PRIME
2125
0
        if (glyphs_size < 257)
2126
0
            glyphs_size = 257;
2127
        /*
2128
         * Make glyphs_size a prime number to ensure termination of the loop in
2129
         * named_glyphs_slot_hashed, q.v.
2130
         * Also reserve additional slots for the case of font merging and
2131
         * for possible font increments.
2132
         */
2133
0
        glyphs_size = glyphs_size * 3 / 2;
2134
2135
0
        { int i;
2136
0
            for (i = 0; i < count_of(some_primes); i++)
2137
0
                if (glyphs_size <= some_primes[i])
2138
0
                    break;
2139
0
            if (i >= count_of(some_primes))
2140
0
                return_error(gs_error_rangecheck);
2141
0
            glyphs_size = some_primes[i];
2142
0
        }
2143
#else
2144
        /*
2145
         * Make names_size a power of 2 to ensure termination of the loop in
2146
         * named_glyphs_slot_hashed, q.v.
2147
         */
2148
        glyphs_size = glyphs_size * 3 / 2;
2149
        while (glyphs_size & (glyphs_size - 1))
2150
            glyphs_size = (glyphs_size | (glyphs_size - 1)) + 1;
2151
        if (glyphs_size < 256)  /* probably incremental font */
2152
            glyphs_size = 256;
2153
#endif
2154
0
        have_names = true;
2155
0
        break;
2156
0
    case ft_CID_encrypted:
2157
0
        procs = &copied_procs_cid0;
2158
        /* We used to use the CIDCount here, but for CIDFonts with a GlyphDirectory
2159
         * (dictionary form) the number of CIDs is not the same as the highest CID.
2160
         * Because we use the CID as the slot, we need to assign the highest possible
2161
         * CID, not the number of CIDs. Don't forget to add one because CIDs
2162
         * count from 0.
2163
         */
2164
0
        glyphs_size = ((gs_font_cid0 *)font)->cidata.common.MaxCID + 1;
2165
0
        break;
2166
0
    case ft_CID_TrueType:
2167
0
        procs = &copied_procs_cid2;
2168
        /* Glyphs are indexed by GID, not by CID. */
2169
0
        glyphs_size = ((gs_font_cid2 *)font)->data.trueNumGlyphs;
2170
0
        break;
2171
0
    default:
2172
0
        return_error(gs_error_rangecheck);
2173
0
    }
2174
2175
    /* Get the font_info for copying. */
2176
2177
0
    memset(&info, 0, sizeof(info));
2178
0
    info.Flags_requested = ~0;
2179
0
    code = font->procs.font_info(font, NULL, ~0, &info);
2180
2181
    /* We can ignore a lack of FontInfo for TrueType fonts which
2182
     * are descendants of CID fonts
2183
     */
2184
0
    if (code < 0 && !(font->FontType == ft_CID_TrueType))
2185
0
        return code;
2186
2187
    /* Allocate the generic copied information. */
2188
2189
0
    glyphs = gs_alloc_struct_array(mem, glyphs_size, gs_copied_glyph_t,
2190
0
                                   &st_gs_copied_glyph_element,
2191
0
                                   "gs_copy_font(glyphs)");
2192
0
    if (have_names != 0)
2193
0
        names = gs_alloc_struct_array(mem, glyphs_size, gs_copied_glyph_name_t,
2194
0
                                      &st_gs_copied_glyph_name_element,
2195
0
                                      "gs_copy_font(names)");
2196
0
    copied = gs_alloc_struct(mem, gs_font, fstype,
2197
0
                             "gs_copy_font(copied font)");
2198
0
    if (copied) {
2199
0
        gs_font_base *bfont = (gs_font_base *)copied;
2200
2201
        /* Initialize the copied font - minumum we need
2202
         * so we can safely free it in the "fail:" case
2203
         * below
2204
         */
2205
0
        memcpy(copied, font, fssize);
2206
0
        copied->next = copied->prev = 0;
2207
0
        copied->memory = mem;
2208
0
        copied->is_resource = false;
2209
0
        gs_notify_init(&copied->notify_list, mem);
2210
0
        copied->base = copied;
2211
2212
0
        bfont->FAPI = 0;
2213
0
        bfont->FAPI_font_data = 0;
2214
0
        bfont->encoding_index = ENCODING_INDEX_UNKNOWN;
2215
0
        code = uid_copy(&bfont->UID, mem, "gs_copy_font(UID)");
2216
0
        if (code < 0) {
2217
0
            uid_set_invalid(&bfont->UID);
2218
0
            goto fail;
2219
0
        }
2220
0
    }
2221
0
    cfdata = gs_alloc_struct(mem, gs_copied_font_data_t,
2222
0
                            &st_gs_copied_font_data,
2223
0
                            "gs_copy_font(wrapper data)");
2224
0
    if (cfdata)
2225
0
        memset(cfdata, 0, sizeof(*cfdata));
2226
0
    if (glyphs == 0 || (names == 0 && have_names) || copied == 0 ||
2227
0
        cfdata == 0
2228
0
        ) {
2229
0
        code = gs_note_error(gs_error_VMerror);
2230
0
        goto fail;
2231
0
    }
2232
0
    cfdata->info = info;
2233
2234
    /* This is somewhat unpleasant. We use the 'glyph' as the unique ID for a number
2235
     * of purposes, but in particular for determining which CharStrings need to be written
2236
     * out by pdfwrite. The 'glyph' appears to be (sometimes) given by the index of the glyph name
2237
     * in the *interpreter* name table. For names in one of the standard encodings
2238
     * we find the name there and use its ID. However, if the glyph name is non-standard
2239
     * then it is added to the interpreter name table and the name index is used to
2240
     * identify the glyph. The problem arises if the font is restored away, and a
2241
     * vmreclaim causes the (now unreferenced) glyph names to be flushed. If we
2242
     * should then use the same font and glyph, its possible that the name table
2243
     * might be different, resulting in a different name index. We would then write
2244
     * duplicate CharStrings to the output, see Bug 687172.
2245
     * The GC enumeration (see top of file) marks the names in the name table to prevent
2246
     * them being flushed. As long as everything is in the same memory allocator this
2247
     * works (ugly though it is). However, if we are using the pdfi PDF interpreter
2248
     * inside the PostScript interpreter, then a problem arises. The pdfwrite device
2249
     * holds on to the font copies until the device is destroyed, by which time the
2250
     * PDF interpreter has already gone. The vmreclaim prior to the device destruction
2251
     * enumerates the name pointers. Because the font was allocated by pdfi these
2252
     * are no longer valid. They are also not needed, since the pdfi name table is
2253
     * not garbage collected..
2254
     * To cater for both conditions we test the memory allocator the font was using.
2255
     * If its a GC'ed allocater then we keep a pointer to the font 'dir' and we enumerate
2256
     * the names and mark them in the interpreter table. Otherwise we don't attempt to
2257
     * mark them. We use dir being NULL to control whether we mark the names.
2258
     */
2259
0
    if (font->memory != font->memory->non_gc_memory)
2260
0
        cfdata->dir = font->dir;
2261
0
    else
2262
0
        cfdata->dir = NULL;
2263
2264
0
    if ((code = (copy_string(mem, &cfdata->info.Copyright,
2265
0
                             "gs_copy_font(Copyright)") |
2266
0
                 copy_string(mem, &cfdata->info.Notice,
2267
0
                             "gs_copy_font(Notice)") |
2268
0
                 copy_string(mem, &cfdata->info.FamilyName,
2269
0
                             "gs_copy_font(FamilyName)") |
2270
0
                 copy_string(mem, &cfdata->info.FullName,
2271
0
                             "gs_copy_font(FullName)"))) < 0
2272
0
        )
2273
0
        goto fail;
2274
    /* set the remainder of the copied font contents */
2275
0
    copied->FontMatrix = *orig_matrix;
2276
0
    copied->client_data = cfdata;
2277
0
    copied->procs = copied_font_procs;
2278
0
    copied->procs.encode_char = procs->encode_char;
2279
0
    copied->procs.glyph_info = procs->glyph_info;
2280
0
    copied->procs.glyph_outline = procs->glyph_outline;
2281
2282
0
    cfdata->procs = procs;
2283
0
    memset(glyphs, 0, glyphs_size * sizeof(*glyphs));
2284
0
    cfdata->glyphs = glyphs;
2285
0
    cfdata->glyphs_size = glyphs_size;
2286
0
    cfdata->num_glyphs = 0;
2287
0
    cfdata->ordered = false;
2288
0
    if (names)
2289
0
        memset(names, 0, glyphs_size * sizeof(*names));
2290
0
    cfdata->names = names;
2291
0
    if (names != 0) {
2292
0
        uint i;
2293
2294
0
        for (i = 0; i < glyphs_size; ++i)
2295
0
            names[i].glyph = GS_NO_GLYPH;
2296
0
    }
2297
2298
    /* Do FontType-specific initialization. */
2299
2300
0
    code = procs->finish_copy_font(font, copied);
2301
0
    if (code < 0)
2302
0
        goto fail;
2303
2304
0
    if (cfdata->notdef != GS_NO_GLYPH)
2305
0
        code = gs_copy_glyph(font, cfdata->notdef, copied);
2306
0
    if (code < 0)
2307
0
        gs_free_copied_font(copied);
2308
0
    else
2309
0
        *pfont_new = copied;
2310
2311
0
    return code;
2312
2313
0
 fail:
2314
    /* Free storage and exit. */
2315
0
    if (cfdata) {
2316
0
        uncopy_string(mem, &cfdata->info.FullName,
2317
0
                      "gs_copy_font(FullName)");
2318
0
        uncopy_string(mem, &cfdata->info.FamilyName,
2319
0
                      "gs_copy_font(FamilyName)");
2320
0
        uncopy_string(mem, &cfdata->info.Notice,
2321
0
                      "gs_copy_font(Notice)");
2322
0
        uncopy_string(mem, &cfdata->info.Copyright,
2323
0
                      "gs_copy_font(Copyright)");
2324
0
        gs_free_object(mem, cfdata, "gs_copy_font(wrapper data)");
2325
0
    }
2326
0
    gs_free_object(mem, copied, "gs_copy_font(copied font)");
2327
0
    gs_free_object(mem, names, "gs_copy_font(names)");
2328
0
    gs_free_object(mem, glyphs, "gs_copy_font(glyphs)");
2329
0
    return code;
2330
0
}
2331
2332
/* We only need this because the descendant(s) share the parent
2333
 * CIDFont glyph space, so we can't free that if we are a descendant.
2334
 */
2335
static int gs_free_copied_descendant_font(gs_font *font)
2336
0
{
2337
0
    gs_copied_font_data_t *cfdata = font->client_data;
2338
0
    gs_memory_t *mem = font->memory;
2339
2340
0
    if (cfdata) {
2341
0
        uncopy_string(mem, &cfdata->info.FullName,
2342
0
                      "gs_free_copied_font(FullName)");
2343
0
        uncopy_string(mem, &cfdata->info.FamilyName,
2344
0
                      "gs_free_copied_font(FamilyName)");
2345
0
        uncopy_string(mem, &cfdata->info.Notice,
2346
0
                      "gs_free_copied_font(Notice)");
2347
0
        uncopy_string(mem, &cfdata->info.Copyright,
2348
0
                      "gs_free_copied_font(Copyright)");
2349
0
        if (cfdata->Encoding)
2350
0
            gs_free_object(mem, cfdata->Encoding, "gs_free_copied_font(Encoding)");
2351
0
        gs_free_object(mem, cfdata->names, "gs_free_copied_font(names)");
2352
0
        gs_free_object(mem, cfdata->data, "gs_free_copied_font(data)");
2353
0
        if (cfdata->subrs.data != NULL)
2354
0
            gs_free_object(mem, cfdata->subrs.data, "gs_free_copied_font(subrs->data)");
2355
0
        if (cfdata->subrs.starts != NULL)
2356
0
            gs_free_object(mem, cfdata->subrs.starts, "gs_free_copied_font(subrs->starts)");
2357
        /* global subrs are 'shared with the parent', see copy_font_cid0()
2358
         * so we don't want to free them here, they are freed by the parent font.
2359
         */
2360
0
        gs_free_object(mem, cfdata, "gs_free_copied_font(wrapper data)");
2361
0
    }
2362
0
    gs_free_object(mem, font, "gs_free_copied_font(copied font)");
2363
0
    return 0;
2364
0
}
2365
2366
int gs_free_copied_font(gs_font *font)
2367
0
{
2368
0
    gs_copied_font_data_t *cfdata = font->client_data;
2369
0
    gs_memory_t *mem = font->memory;
2370
0
    int i, code;
2371
0
    gs_copied_glyph_t *pcg = 0;
2372
0
    gs_copied_glyph_name_t *pcgn = 0;
2373
2374
    /* For CID fonts, we must also free the descendants, which we copied
2375
     * at the time we copied the actual CIDFont itself
2376
     */
2377
0
    if (font->FontType == ft_CID_encrypted) {
2378
0
        gs_font_cid0 *copied0 = (gs_font_cid0 *)font;
2379
2380
0
        for (i = 0; i < copied0->cidata.FDArray_size; ++i) {
2381
0
            code = gs_free_copied_descendant_font((gs_font *)copied0->cidata.FDArray[i]);
2382
0
            if (code < 0)
2383
0
                return code;
2384
0
        }
2385
0
        gs_free_object(mem, copied0->cidata.FDArray, "free copied CIDFont FDArray");
2386
0
        copied0->cidata.FDArray = 0;
2387
0
        gs_free_string(mem, (byte *)copied0->cidata.common.CIDSystemInfo.Registry.data, copied0->cidata.common.CIDSystemInfo.Registry.size, "Free copied Registry");
2388
0
        gs_free_string(mem, (byte *)copied0->cidata.common.CIDSystemInfo.Ordering.data, copied0->cidata.common.CIDSystemInfo.Ordering.size, "Free copied Registry");
2389
0
        copied0->cidata.common.CIDSystemInfo.Registry.data = copied0->cidata.common.CIDSystemInfo.Ordering.data = NULL;
2390
0
        copied0->cidata.common.CIDSystemInfo.Registry.size = copied0->cidata.common.CIDSystemInfo.Ordering.size = 0;
2391
0
    }
2392
2393
0
    if (font->FontType == ft_CID_TrueType) {
2394
0
        gs_font_cid2 *copied2 = (gs_font_cid2 *)font;
2395
2396
0
        if (copied2->subst_CID_on_WMode)
2397
0
            rc_decrement(copied2->subst_CID_on_WMode, "gs_free_copied_font(subst_CID_on_WMode");
2398
0
        gs_free_string(mem, (byte *)copied2->cidata.common.CIDSystemInfo.Registry.data, copied2->cidata.common.CIDSystemInfo.Registry.size, "Free copied Registry");
2399
0
        gs_free_string(mem, (byte *)copied2->cidata.common.CIDSystemInfo.Ordering.data, copied2->cidata.common.CIDSystemInfo.Ordering.size, "Free copied Registry");
2400
0
        copied2->cidata.common.CIDSystemInfo.Registry.data = copied2->cidata.common.CIDSystemInfo.Ordering.data = NULL;
2401
0
        copied2->cidata.common.CIDSystemInfo.Registry.size = copied2->cidata.common.CIDSystemInfo.Ordering.size = 0;
2402
0
    }
2403
2404
0
    if (cfdata) {
2405
        /* free copied glyph data */
2406
0
        for (i=0;i < cfdata->glyphs_size;i++) {
2407
0
            pcg = &cfdata->glyphs[i];
2408
0
            if(pcg->gdata.data != NULL) {
2409
0
                gs_free_string(font->memory, (byte *)pcg->gdata.data, pcg->gdata.size, "Free copied glyph");
2410
0
            }
2411
0
            if (cfdata->names) {
2412
0
                pcgn = &cfdata->names[i];
2413
0
                if (pcgn->str.data != NULL) {
2414
0
                    if (!gs_is_c_glyph_name(pcgn->str.data, pcgn->str.size))
2415
0
                        gs_free_string(font->memory, (byte *)pcgn->str.data, pcgn->str.size, "Free copied glyph name");
2416
0
                }
2417
0
            }
2418
0
        }
2419
0
        if (cfdata->extra_names) {
2420
0
            gs_copied_glyph_extra_name_t *extra_name = cfdata->extra_names, *next;
2421
2422
0
            while (extra_name != NULL) {
2423
0
                next = extra_name->next;
2424
0
                if (!gs_is_c_glyph_name(extra_name->name.str.data, extra_name->name.str.size))
2425
0
                    gs_free_string(font->memory, (byte *)extra_name->name.str.data, extra_name->name.str.size, "Free extra name string");
2426
0
                gs_free_object(font->memory, extra_name, "free copied font(extra_names)");
2427
0
                extra_name = next;
2428
0
            }
2429
0
            cfdata->extra_names = NULL;
2430
0
        }
2431
2432
0
        uncopy_string(mem, &cfdata->info.FullName,
2433
0
                      "gs_free_copied_font(FullName)");
2434
0
        uncopy_string(mem, &cfdata->info.FamilyName,
2435
0
                      "gs_free_copied_font(FamilyName)");
2436
0
        uncopy_string(mem, &cfdata->info.Notice,
2437
0
                      "gs_free_copied_font(Notice)");
2438
0
        uncopy_string(mem, &cfdata->info.Copyright,
2439
0
                      "gs_free_copied_font(Copyright)");
2440
0
        if (cfdata->subrs.data != NULL)
2441
0
            gs_free_object(mem, cfdata->subrs.data, "gs_free_copied_font(subrs.data)");
2442
0
        if (cfdata->subrs.starts != NULL)
2443
0
            gs_free_object(mem, cfdata->subrs.starts, "gs_free_copied_font(subrs.dtarts)");
2444
0
        if (cfdata->global_subrs.data !=  NULL)
2445
0
            gs_free_object(mem, cfdata->global_subrs.data, "gs_free_copied_font(gsubrs.data)");
2446
0
        if (cfdata->global_subrs.starts !=  NULL)
2447
0
            gs_free_object(mem, cfdata->global_subrs.starts, "gs_free_copied_font(gsubrs.starts)");
2448
0
        if (cfdata->Encoding)
2449
0
            gs_free_object(mem, cfdata->Encoding, "gs_free_copied_font(Encoding)");
2450
0
        if (cfdata->CIDMap)
2451
0
            gs_free_object(mem, cfdata->CIDMap, "gs_free_copied_font(CIDMap)");
2452
0
        gs_free_object(mem, cfdata->glyphs, "gs_free_copied_font(glyphs)");
2453
0
        gs_free_object(mem, cfdata->names, "gs_free_copied_font(names)");
2454
0
        gs_free_object(mem, cfdata->data, "gs_free_copied_font(data)");
2455
0
        gs_free_object(mem, cfdata, "gs_free_copied_font(wrapper data)");
2456
0
    }
2457
0
    gs_free_object(mem, font, "gs_free_copied_font(copied font)");
2458
0
    return 0;
2459
0
}
2460
2461
/*
2462
 * Copy a glyph, including any sub-glyphs.
2463
 */
2464
int
2465
gs_copy_glyph(gs_font *font, gs_glyph glyph, gs_font *copied)
2466
0
{
2467
0
    return gs_copy_glyph_options(font, glyph, copied, 0);
2468
0
}
2469
int
2470
gs_copy_glyph_options(gs_font *font, gs_glyph glyph, gs_font *copied,
2471
                      int options)
2472
0
{
2473
0
    int code;
2474
0
#define MAX_GLYPH_PIECES 64  /* arbitrary, but 32 is too small - bug 687698. */
2475
0
    gs_glyph glyphs[MAX_GLYPH_PIECES];
2476
0
    uint count = 1, i;
2477
0
    gs_copied_font_data_t *cfdata = NULL;
2478
2479
0
    if (copied->procs.font_info != copied_font_info)
2480
0
        return_error(gs_error_rangecheck);
2481
0
    cfdata = cf_data(copied);
2482
0
    code = cfdata->procs->copy_glyph(font, glyph, copied, options);
2483
0
    if (code != 0)
2484
0
        return code;
2485
    /* Copy any sub-glyphs. */
2486
0
    glyphs[0] = glyph;
2487
0
    code = psf_add_subset_pieces(glyphs, &count, MAX_GLYPH_PIECES, MAX_GLYPH_PIECES,
2488
0
                          font);
2489
0
    if (code < 0)
2490
0
        return code;
2491
0
    if (count > MAX_GLYPH_PIECES)
2492
0
        return_error(gs_error_limitcheck);
2493
0
    for (i = 1; i < count; ++i) {
2494
0
        code = gs_copy_glyph_options(font, glyphs[i], copied,
2495
0
                                     (options & ~COPY_GLYPH_NO_OLD) | COPY_GLYPH_BY_INDEX);
2496
0
        if (code < 0) {
2497
0
            int j = 0;
2498
2499
0
            for (j = 0; j < i; j++) {
2500
0
                if (cfdata->procs->uncopy_glyph != NULL)
2501
0
                    (void)cfdata->procs->uncopy_glyph(font, glyph, copied, options);
2502
0
            }
2503
0
            return code;
2504
0
        }
2505
        /* if code > 0 then we already have the glyph, so no need to process further.
2506
         * If the original glyph was not a CID then we are copying by name, not by index.
2507
         * But the copy above copies by index which means we don't have an entry for
2508
         * the glyp-h component in the name table. If we are using names then we
2509
         * absolutely *must* have an entry in the name table, so go ahead and add
2510
         * one here. Note that the array returned by psf_add_subset_pieces has the
2511
         * GIDs with an offset of GS_MIN_GLYPH_INDEX added. Previously we removed this
2512
         * offset, but if the resulting GID referenced a name already in use (or later used)
2513
         * then the generated CMAP was incorrect. By leaving the offset in place we get
2514
         * a name generated (numeric name based on GID) which gurantees no name collisions.
2515
         * (Bug #693444).
2516
         */
2517
0
        if (code == 0 && glyph < GS_MIN_CID_GLYPH && glyphs[i] > GS_MIN_GLYPH_INDEX) {
2518
0
            code = copy_glyph_name(font, glyphs[i], copied,
2519
0
                               glyphs[i]);
2520
0
            if (code < 0)
2521
0
                return code;
2522
0
        }
2523
0
    }
2524
    /*
2525
     * Because 'seac' accesses the Encoding of the font as well as the
2526
     * glyphs, we have to copy the Encoding entries as well.
2527
     */
2528
0
    if (count == 1)
2529
0
        return 0;
2530
0
    switch (font->FontType) {
2531
0
    case ft_encrypted:
2532
0
    case ft_encrypted2:
2533
0
        break;
2534
0
    default:
2535
0
        return 0;
2536
0
    }
2537
#if 0 /* No need to add subglyphs to the Encoding because they always are
2538
         taken from StandardEncoding (See the Type 1 spec about 'seac').
2539
         Attempt to add them to the encoding can cause a conflict,
2540
         if the encoding specifies different glyphs for these char codes
2541
         (See the bug #687172). */
2542
    {
2543
        gs_copied_glyph_t *pcg;
2544
        gs_glyph_data_t gdata;
2545
        gs_char chars[2];
2546
2547
        gdata.memory = font->memory;
2548
        /* Since we just copied the glyph, copied_glyph_slot can't fail. */
2549
        DISCARD(copied_glyph_slot(cf_data(copied), glyph, &pcg));
2550
        gs_glyph_data_from_string(&gdata, pcg->gdata.data, pcg->gdata.size,
2551
                                  NULL);
2552
        code = gs_type1_piece_codes((gs_font_type1 *)font, &gdata, chars);
2553
        if (code <= 0 ||  /* 0 is not possible here */
2554
            (code = gs_copied_font_add_encoding(copied, chars[0], glyphs[1])) < 0 ||
2555
            (code = gs_copied_font_add_encoding(copied, chars[1], glyphs[2])) < 0
2556
            )
2557
            return code;
2558
    }
2559
#endif
2560
0
    return 0;
2561
0
#undef MAX_GLYPH_PIECES
2562
0
}
2563
2564
/*
2565
 * Add an Encoding entry to a copied font.  The glyph need not already have
2566
 * been copied.
2567
 */
2568
int
2569
gs_copied_font_add_encoding(gs_font *copied, gs_char chr, gs_glyph glyph)
2570
0
{
2571
0
    gs_copied_font_data_t *const cfdata = cf_data(copied);
2572
2573
0
    if (copied->procs.font_info != copied_font_info)
2574
0
        return_error(gs_error_rangecheck);
2575
0
    return cfdata->procs->add_encoding(copied, chr, glyph);
2576
0
}
2577
2578
/*
2579
 * Copy all the glyphs and, if relevant, Encoding entries from a font.  This
2580
 * is equivalent to copying the glyphs and Encoding entries individually,
2581
 * and returns errors under the same conditions.
2582
 */
2583
int
2584
gs_copy_font_complete(gs_font *font, gs_font *copied)
2585
0
{
2586
0
    int index, code = 0;
2587
0
    gs_glyph_space_t space = GLYPH_SPACE_NAME;
2588
0
    gs_glyph glyph;
2589
2590
    /*
2591
     * For Type 1 fonts and CIDFonts, enumerating the glyphs using
2592
     * GLYPH_SPACE_NAME will cover all the glyphs.  (The "names" of glyphs
2593
     * in CIDFonts are CIDs, but that is not a problem.)  For Type 42 fonts,
2594
     * however, we have to copy by name once, so that we also copy the
2595
     * name-to-GID mapping (the CharStrings dictionary in PostScript), and
2596
     * then copy again by GID, to cover glyphs that don't have names.
2597
     */
2598
0
    for (;;) {
2599
0
        for (index = 0;
2600
0
             code >= 0 &&
2601
0
                 (font->procs.enumerate_glyph(font, &index, space, &glyph),
2602
0
                  index != 0);
2603
0
            ) {
2604
0
            if (font->FontType == ft_TrueType &&
2605
0
                    ((glyph >= GS_MIN_CID_GLYPH && glyph < GS_MIN_GLYPH_INDEX) || glyph == GS_NO_GLYPH ||
2606
0
                    (space == GLYPH_SPACE_INDEX && glyph < GS_MIN_GLYPH_INDEX)))
2607
0
                return_error(gs_error_invalidfont); /* bug 688370. */
2608
0
            code = gs_copy_glyph(font, glyph, copied);
2609
0
        }
2610
        /* For Type 42 fonts, if we copied by name, now copy again by index. */
2611
0
        if (space == GLYPH_SPACE_NAME && font->FontType == ft_TrueType)
2612
0
            space = GLYPH_SPACE_INDEX;
2613
0
        else
2614
0
            break;
2615
0
    }
2616
0
    if (cf_data(copied)->Encoding != 0)
2617
0
        for (index = 0; code >= 0 && index < 256; ++index) {
2618
0
            glyph = font->procs.encode_char(font, (gs_char)index,
2619
0
                                            GLYPH_SPACE_NAME);
2620
0
            if (glyph != GS_NO_GLYPH) {
2621
0
                code = gs_copied_font_add_encoding(copied, (gs_char)index,
2622
0
                                                   glyph);
2623
0
                if (code == gs_error_undefined) {
2624
                    /* Skip Encoding entries, which point to undefiuned glyphs -
2625
                       happens with 033-52-5873.pdf. */
2626
0
                    code = 0;
2627
0
                }
2628
0
                if (code == gs_error_rangecheck) {
2629
                    /* Skip Encoding entries, which point to undefiuned glyphs -
2630
                       happens with 159.pdf. */
2631
0
                    code = 0;
2632
0
                }
2633
0
            }
2634
0
        }
2635
0
    if (copied->FontType != ft_composite) {
2636
0
        gs_font_base *bfont = (gs_font_base *)font;
2637
0
        gs_font_base *bcopied = (gs_font_base *)copied;
2638
2639
0
        bcopied->encoding_index = bfont->encoding_index;
2640
0
        bcopied->nearest_encoding_index = bfont->nearest_encoding_index;
2641
0
    }
2642
0
    return code;
2643
0
}
2644
2645
/*
2646
 * Check whether specified glyphs can be copied from another font.
2647
 * It means that (1) fonts have same hinting parameters and
2648
 * (2) font subsets for the specified glyph set don't include different
2649
 * outlines or metrics. Possible returned values :
2650
 * 0 (incompatible), 1 (compatible), < 0 (error)
2651
 */
2652
int
2653
gs_copied_can_copy_glyphs(const gs_font *cfont, const gs_font *ofont,
2654
                          gs_glyph *glyphs, int num_glyphs, int glyphs_step,
2655
                          bool check_hinting)
2656
0
{
2657
0
    int code = 0;
2658
2659
0
    if (cfont == ofont)
2660
0
        return 1;
2661
0
    if (cfont->FontType != ofont->FontType)
2662
0
        return 0;
2663
0
    if (cfont->WMode != ofont->WMode)
2664
0
        return 0;
2665
0
    if (cfont->font_name.size == 0 || ofont->font_name.size == 0) {
2666
0
        if (cfont->key_name.size != ofont->key_name.size ||
2667
0
            memcmp(cfont->key_name.chars, ofont->key_name.chars,
2668
0
                        cfont->font_name.size))
2669
0
            return 0; /* Don't allow to merge random fonts. */
2670
0
    } else {
2671
0
        if (cfont->font_name.size != ofont->font_name.size ||
2672
0
            memcmp(cfont->font_name.chars, ofont->font_name.chars,
2673
0
                            cfont->font_name.size))
2674
0
            return 0; /* Don't allow to merge random fonts. */
2675
0
    }
2676
0
    if (check_hinting) {
2677
0
        switch(cfont->FontType) {
2678
0
            case ft_encrypted:
2679
0
            case ft_encrypted2:
2680
0
                if (!same_type1_hinting((const gs_font_type1 *)cfont,
2681
0
                                        (const gs_font_type1 *)ofont))
2682
0
                    return 0;
2683
0
                code = 1;
2684
0
                break;
2685
0
            case ft_TrueType:
2686
0
                code = same_type42_hinting((gs_font_type42 *)cfont,
2687
0
                                        (gs_font_type42 *)ofont);
2688
0
                if (code > 0)
2689
0
                    code = same_maxp_values((gs_font_type42 *)cfont,
2690
0
                                        (gs_font_type42 *)ofont);
2691
0
                break;
2692
0
            case ft_CID_encrypted:
2693
0
                if (!gs_is_CIDSystemInfo_compatible(
2694
0
                                gs_font_cid_system_info(cfont),
2695
0
                                gs_font_cid_system_info(ofont)))
2696
0
                    return 0;
2697
0
                code = same_cid0_hinting((const gs_font_cid0 *)cfont,
2698
0
                                         (const gs_font_cid0 *)ofont);
2699
0
                break;
2700
0
            case ft_CID_TrueType:
2701
0
                if (!gs_is_CIDSystemInfo_compatible(
2702
0
                                gs_font_cid_system_info(cfont),
2703
0
                                gs_font_cid_system_info(ofont)))
2704
0
                    return 0;
2705
0
                code = same_cid2_hinting((const gs_font_cid2 *)cfont,
2706
0
                                         (const gs_font_cid2 *)ofont);
2707
0
                if (code > 0)
2708
0
                    code = same_maxp_values((gs_font_type42 *)cfont,
2709
0
                                        (gs_font_type42 *)ofont);
2710
0
                break;
2711
0
            default:
2712
0
                return_error(gs_error_unregistered); /* Must not happen. */
2713
0
        }
2714
0
        if (code <= 0) /* an error or false */
2715
0
            return code;
2716
0
    }
2717
0
    return compare_glyphs(cfont, ofont, glyphs, num_glyphs, glyphs_step, 0);
2718
0
}
2719
2720
/* Extension glyphs may be added to a font to resolve
2721
   glyph name conflicts while conwerting a PDF Widths into Metrics.
2722
   This function drops them before writing out an embedded font. */
2723
int
2724
copied_drop_extension_glyphs(gs_font *copied)
2725
0
{
2726
    /* When we encounter a glyph used at multiple encoding positions, and
2727
     * the encoding positions have different Widths, we end up defining
2728
     * a new glyph name, because we can't have a PostScript glyph which has
2729
     * two sets of metrics. Here we are supposed to find such duplicates
2730
     * and 'drop' them. It appears that the original intention was to mark
2731
     * the 'slot'->used member as false, with the expectation that this
2732
     * would drop the glyph from the font.
2733
     */
2734
    /*  Note : This function drops 'used' flags for some glyphs
2735
        and truncates glyph names. Can't use the font
2736
        for outlining|rasterization|width after applying it.
2737
     */
2738
0
    gs_copied_font_data_t *const cfdata = cf_data(copied);
2739
0
    uint gsize = cfdata->glyphs_size, ext_name;
2740
0
    const int sl = strlen(gx_extendeg_glyph_name_separator);
2741
2742
0
    for (ext_name = 0; ext_name < gsize; ext_name++) {
2743
0
        gs_copied_glyph_t *pslot = &cfdata->glyphs[ext_name];
2744
0
        gs_copied_glyph_name_t *name;
2745
0
        int l, j, k, non_ext_name;
2746
2747
0
        if (!pslot->used)
2748
0
            continue;
2749
0
        name = &cfdata->names[ext_name];
2750
0
        l = name->str.size - sl;
2751
2752
0
        for (j = 0; j < l; j ++)
2753
0
            if (!memcmp(gx_extendeg_glyph_name_separator, name->str.data + j, sl))
2754
0
                break;
2755
0
        if (j >= l)
2756
0
            continue;
2757
        /* Found an extension name.
2758
           Find the corresponding non-extended one. */
2759
0
        non_ext_name = ext_name;
2760
0
        for (k = 0; k < gsize; k++)
2761
0
            if (cfdata->glyphs[k].used &&
2762
0
                    cfdata->names[k].str.size == j &&
2763
0
                    !memcmp(cfdata->names[k].str.data, name->str.data, j) &&
2764
0
                    !bytes_compare(pslot->gdata.data, pslot->gdata.size,
2765
0
                            cfdata->glyphs[k].gdata.data, cfdata->glyphs[k].gdata.size)) {
2766
0
                non_ext_name = k;
2767
0
                break;
2768
0
            }
2769
        /* Drop others with same prefix. */
2770
0
        for (k = 0; k < gsize; k++)
2771
0
            if (k != non_ext_name && cfdata->glyphs[k].used &&
2772
0
                    cfdata->names[k].str.size >= j + sl &&
2773
0
                    !memcmp(cfdata->names[k].str.data, name->str.data, j) &&
2774
0
                    !memcmp(gx_extendeg_glyph_name_separator, name->str.data + j, sl) &&
2775
0
                    !bytes_compare(pslot->gdata.data, pslot->gdata.size,
2776
0
                    cfdata->glyphs[k].gdata.data, cfdata->glyphs[k].gdata.size)) {
2777
0
                cfdata->glyphs[k].used = false;
2778
0
                cfdata->names[k].str.size = j;
2779
0
            }
2780
        /* Truncate the extended glyph name. */
2781
0
        cfdata->names[ext_name].str.size = j;
2782
0
    }
2783
0
    return 0;
2784
0
}
2785
2786
static int
2787
compare_glyph_names(const void *pg1, const void *pg2)
2788
0
{
2789
0
    const gs_copied_glyph_name_t * gn1 = *(const gs_copied_glyph_name_t **)pg1;
2790
0
    const gs_copied_glyph_name_t * gn2 = *(const gs_copied_glyph_name_t **)pg2;
2791
2792
0
    return bytes_compare(gn1->str.data, gn1->str.size, gn2->str.data, gn2->str.size);
2793
0
}
2794
2795
/* Order font data to avoid a serialization indeterminism. */
2796
static int
2797
order_font_data(gs_copied_font_data_t *cfdata, gs_memory_t *memory)
2798
0
{
2799
0
    int i, j = 0;
2800
2801
0
    gs_copied_glyph_name_t **a = (gs_copied_glyph_name_t **)gs_alloc_byte_array(memory, cfdata->num_glyphs,
2802
0
        sizeof(gs_copied_glyph_name_t *), "order_font_data");
2803
0
    if (a == NULL)
2804
0
        return_error(gs_error_VMerror);
2805
0
    j = 0;
2806
0
    for (i = 0; i < cfdata->glyphs_size; i++) {
2807
0
        if (cfdata->glyphs[i].used) {
2808
0
            if (j >= cfdata->num_glyphs) {
2809
0
                gs_free_object(memory, a, "order_font_data");
2810
0
                return_error(gs_error_unregistered); /* Must not happen */
2811
0
            }
2812
0
            a[j++] = &cfdata->names[i];
2813
0
        }
2814
0
    }
2815
0
    qsort(a, j, sizeof(*a), compare_glyph_names);
2816
0
    for (j--; j >= 0; j--)
2817
0
        cfdata->glyphs[j].order_index = a[j] - cfdata->names;
2818
0
    gs_free_object(memory, a, "order_font_data");
2819
0
    return 0;
2820
0
}
2821
2822
/* Order font to avoid a serialization indeterminism. */
2823
int
2824
copied_order_font(gs_font *font)
2825
0
{
2826
2827
0
    if (font->procs.enumerate_glyph != copied_enumerate_glyph)
2828
0
        return_error(gs_error_unregistered); /* Must not happen */
2829
0
    if (font->FontType != ft_encrypted && font->FontType != ft_encrypted2) {
2830
         /* Don't need to order, because it is ordered by CIDs or glyph indices. */
2831
0
        return 0;
2832
0
    }
2833
0
    { gs_copied_font_data_t * cfdata = cf_data(font);
2834
0
        cfdata->ordered = true;
2835
0
        return order_font_data(cfdata, font->memory);
2836
0
    }
2837
0
}
2838
2839
/* Get .nmotdef glyph. */
2840
gs_glyph
2841
copied_get_notdef(const gs_font *font)
2842
0
{
2843
0
    gs_copied_font_data_t * cfdata = cf_data(font);
2844
2845
0
    return cfdata->notdef;
2846
0
}