1
/* Copyright (C) 2001-2006 Artifex Software, Inc.
4
This software is provided AS-IS with no warranty, either express or
7
This software is distributed under license and may not be copied, modified
8
or distributed except as expressly authorized under the terms of that
9
license. Refer to licensing information at http://www.artifex.com/
10
or contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134,
11
San Rafael, CA 94903, U.S.A., +1(415)492-9861, for further information.
14
/* $Id: gxfcopy.c 9263 2008-12-08 08:17:55Z ken $ */
15
/* Font copying for high-level output */
18
#include <stdlib.h> /* for qsort */
21
#include "gsline.h" /* for BuildChar */
22
#include "gspaint.h" /* for BuildChar */
23
#include "gspath.h" /* for gs_moveto in BuildChar */
34
#include "gxfcache.h" /* for gs_font_dir_s */
35
#include "gxistate.h" /* for Type 1 glyph_outline */
36
#include "gxtext.h" /* for BuildChar */
37
#include "gxtype1.h" /* for Type 1 glyph_outline */
38
#include "gzstate.h" /* for path for BuildChar */
41
#define GLYPHS_SIZE_IS_PRIME 1 /* Old code = 0, new code = 1. */
43
/* ================ Types and structures ================ */
45
typedef struct gs_copied_glyph_s gs_copied_glyph_t;
46
typedef struct gs_copied_font_data_s gs_copied_font_data_t;
48
typedef struct gs_copied_font_procs_s {
49
int (*finish_copy_font)(gs_font *font, gs_font *copied);
50
int (*copy_glyph)(gs_font *font, gs_glyph glyph, gs_font *copied,
52
int (*add_encoding)(gs_font *copied, gs_char chr, gs_glyph glyph);
53
int (*named_glyph_slot)(gs_copied_font_data_t *cfdata, gs_glyph glyph,
54
gs_copied_glyph_t **pslot);
56
font_proc_encode_char((*encode_char));
57
font_proc_glyph_info((*glyph_info));
58
font_proc_glyph_outline((*glyph_outline));
59
} gs_copied_font_procs_t;
62
* We need to store the Subrs data for Type 1/2 and CIDFontType 0 fonts,
63
* and the GlobalSubrs data for all but Type 1.
65
typedef struct gs_subr_info_s {
66
byte *data; /* Subr data */
68
uint *starts; /* [count+1] Subr[i] = data[starts[i]..starts[i+1]] */
72
* The glyphs for copied fonts are stored explicitly in a table indexed by
74
* For Type 1 fonts, the glyph numbers are parallel to the hashed name table.
75
* For TrueType fonts, the glyph number is the TrueType GID.
76
* For CIDFontType 0 fonts, the glyph number is the CID.
77
* For CIDFontType 2 fonts, the glyph number is the TrueType GID;
78
* a separate CIDMap array maps CIDs to GIDs.
80
struct gs_copied_glyph_s {
81
gs_const_string gdata; /* vector data */
82
#define HAS_DATA 1 /* entry is in use */
83
/* HAS_SBW* are only used for TT-based fonts */
84
#define HAS_SBW0 2 /* has hmtx */
85
#define HAS_SBW1 4 /* has vmtx */
86
byte used; /* non-zero iff this entry is in use */
87
/* (if not, gdata.{data,size} = 0) */
88
int order_index; /* Index for the ordered glyph set. */
91
* We use a special GC descriptor to avoid large GC overhead.
93
gs_private_st_composite(st_gs_copied_glyph_element, gs_copied_glyph_t,
94
"gs_copied_glyph_t[]", copied_glyph_element_enum_ptrs,
95
copied_glyph_element_reloc_ptrs);
96
static ENUM_PTRS_WITH(copied_glyph_element_enum_ptrs, gs_copied_glyph_t *pcg)
97
if (index < size / (uint)sizeof(gs_copied_glyph_t))
98
return ENUM_CONST_STRING(&pcg[index].gdata);
101
static RELOC_PTRS_WITH(copied_glyph_element_reloc_ptrs, gs_copied_glyph_t *pcg)
103
uint count = size / (uint)sizeof(gs_copied_glyph_t);
104
gs_copied_glyph_t *p = pcg;
106
for (; count > 0; --count, ++p)
107
if (p->gdata.size > 0)
108
RELOC_CONST_STRING_VAR(p->gdata);
113
* Type 1 and TrueType fonts also have a 'names' table, parallel to the
115
* For Type 1 fonts, this is a hash table; glyph numbers are assigned
116
* arbitrarily, according to the hashed placement of the names.
117
* For TrueType fonts, this is indexed by GID.
118
* The strings in this table are either those returned by the font's
119
* glyph_name procedure, which we assume are garbage-collected, or those
120
* associated with the known encodings, which we assume are immutable.
122
typedef struct gs_copied_glyph_name_s {
123
gs_glyph glyph; /* key (for comparison and glyph_name only) */
124
gs_const_string str; /* glyph name */
125
} gs_copied_glyph_name_t;
127
* We use the same special GC descriptor as above for 'names'.
129
gs_private_st_composite(st_gs_copied_glyph_name_element,
130
gs_copied_glyph_name_t,
131
"gs_copied_glyph_name_t[]",
132
copied_glyph_name_enum_ptrs,
133
copied_glyph_name_reloc_ptrs);
134
static ENUM_PTRS_WITH(copied_glyph_name_enum_ptrs, gs_copied_glyph_name_t *pcgn)
135
if (index < size / (uint)sizeof(gs_copied_glyph_name_t)) {
136
const gs_copied_glyph_name_t *const p = &pcgn[index];
138
return (p->str.size == 0 ||
139
gs_is_c_glyph_name(p->str.data, p->str.size) ?
140
ENUM_CONST_STRING2(0, 0) :
141
ENUM_CONST_STRING(&p->str));
144
/* We should mark glyph name here, but we have no access to
145
the gs_font_dir instance. Will mark in gs_copied_font_data_enum_ptrs.
148
static RELOC_PTRS_WITH(copied_glyph_name_reloc_ptrs, gs_copied_glyph_name_t *pcgn)
150
uint count = size / (uint)sizeof(gs_copied_glyph_name_t);
151
gs_copied_glyph_name_t *p = pcgn;
153
for (; count > 0; --count, ++p)
154
if (p->str.size > 0 && !gs_is_c_glyph_name(p->str.data, p->str.size))
155
RELOC_CONST_STRING_VAR(p->str);
160
* To accommodate glyphs with multiple names, there is an additional
161
* 'extra_names' table. Since this is rare, this table uses linear search.
163
typedef struct gs_copied_glyph_extra_name_s gs_copied_glyph_extra_name_t;
164
struct gs_copied_glyph_extra_name_s {
165
gs_copied_glyph_name_t name;
166
uint gid; /* index in glyphs table */
167
gs_copied_glyph_extra_name_t *next;
169
BASIC_PTRS(gs_copied_glyph_extra_name_ptrs) {
170
GC_STRING_ELT(gs_copied_glyph_extra_name_t, name.str),
171
GC_OBJ_ELT(gs_copied_glyph_extra_name_t, next)
173
gs_private_st_basic(st_gs_copied_glyph_extra_name,
174
gs_copied_glyph_extra_name_t,
175
"gs_copied_glyph_extra_name_t",
176
gs_copied_glyph_extra_name_ptrs,
177
gs_copied_glyph_extra_name_data);
180
* The client_data of copied fonts points to an instance of
181
* gs_copied_font_data_t.
183
struct gs_copied_font_data_s {
184
gs_font_info_t info; /* from the original font, must be first */
185
const gs_copied_font_procs_t *procs;
186
gs_copied_glyph_t *glyphs; /* [glyphs_size] */
187
uint glyphs_size; /* (a power of 2 or a prime number for Type 1/2) */
188
uint num_glyphs; /* The number of glyphs copied. */
189
gs_glyph notdef; /* CID 0 or .notdef glyph */
191
* We don't use a union for the rest of the data, because some of the
192
* cases overlap and it's just not worth the trouble.
194
gs_copied_glyph_name_t *names; /* (Type 1/2, TrueType) [glyphs_size] */
195
gs_copied_glyph_extra_name_t *extra_names; /* (TrueType) */
196
byte *data; /* (TrueType and CID fonts) copied data */
197
uint data_size; /* (TrueType and CID fonts) */
198
gs_glyph *Encoding; /* (Type 1/2 and Type 42) [256] */
199
ushort *CIDMap; /* (CIDFontType 2) [CIDCount] */
200
gs_subr_info_t subrs; /* (Type 1/2 and CIDFontType 0) */
201
gs_subr_info_t global_subrs; /* (Type 2 and CIDFontType 0) */
202
gs_font_cid0 *parent; /* (Type 1 subfont) => parent CIDFontType 0 */
206
extern_st(st_gs_font_info);
208
ENUM_PTRS_WITH(gs_copied_font_data_enum_ptrs, gs_copied_font_data_t *cfdata)
210
gs_copied_glyph_name_t *names = cfdata->names;
211
gs_copied_glyph_extra_name_t *en = cfdata->extra_names;
215
for (i = 0; i < cfdata->glyphs_size; ++i)
216
if (names[i].glyph < gs_c_min_std_encoding_glyph)
217
cfdata->dir->ccache.mark_glyph(mem, names[i].glyph, NULL);
218
for (; en != NULL; en = en->next)
219
if (en->name.glyph < gs_c_min_std_encoding_glyph)
220
cfdata->dir->ccache.mark_glyph(mem, en->name.glyph, NULL);
222
return ENUM_USING(st_gs_font_info, &cfdata->info, sizeof(gs_font_info_t), index - 12);
223
ENUM_PTR3(0, gs_copied_font_data_t, glyphs, names, extra_names);
224
ENUM_PTR3(3, gs_copied_font_data_t, data, Encoding, CIDMap);
225
ENUM_PTR3(6, gs_copied_font_data_t, subrs.data, subrs.starts, global_subrs.data);
226
ENUM_PTR3(9, gs_copied_font_data_t, global_subrs.starts, parent, dir);
229
static RELOC_PTRS_WITH(gs_copied_font_data_reloc_ptrs, gs_copied_font_data_t *cfdata)
231
RELOC_PTR3(gs_copied_font_data_t, glyphs, names, extra_names);
232
RELOC_PTR3(gs_copied_font_data_t, data, Encoding, CIDMap);
233
RELOC_PTR3(gs_copied_font_data_t, subrs.data, subrs.starts, global_subrs.data);
234
RELOC_PTR3(gs_copied_font_data_t, global_subrs.starts, parent, dir);
235
RELOC_USING(st_gs_font_info, &cfdata->info, sizeof(gs_font_info_t));
239
gs_private_st_composite(st_gs_copied_font_data, gs_copied_font_data_t, "gs_copied_font_data_t",\
240
gs_copied_font_data_enum_ptrs, gs_copied_font_data_reloc_ptrs);
242
static inline gs_copied_font_data_t *
243
cf_data(const gs_font *font)
245
return (gs_copied_font_data_t *)font->client_data;
248
/* ================ Procedures ================ */
250
/* ---------------- Private utilities ---------------- */
252
/* Copy a string. Return 0 or gs_error_VMerror. */
254
copy_string(gs_memory_t *mem, gs_const_string *pstr, client_name_t cname)
256
const byte *data = pstr->data;
257
uint size = pstr->size;
261
return 0; /* empty string */
262
str = gs_alloc_string(mem, size, cname);
265
return_error(gs_error_VMerror);
266
memcpy(str, data, size);
270
/* Free a copied string. */
272
uncopy_string(gs_memory_t *mem, gs_const_string *pstr, client_name_t cname)
275
gs_free_const_string(mem, pstr->data, pstr->size, cname);
279
* Allocate an Encoding for a Type 1 or Type 42 font.
282
copied_Encoding_alloc(gs_font *copied)
284
gs_copied_font_data_t *const cfdata = cf_data(copied);
285
gs_glyph *Encoding = (gs_glyph *)
286
gs_alloc_byte_array(copied->memory, 256, sizeof(*cfdata->Encoding),
287
"copy_font_type1(Encoding)");
291
return_error(gs_error_VMerror);
292
for (i = 0; i < 256; ++i)
293
Encoding[i] = GS_NO_GLYPH;
294
cfdata->Encoding = Encoding;
299
* Allocate and set up data copied from a TrueType or CID font.
300
* stell(*s) + extra is the length of the data.
303
copied_data_alloc(gs_font *copied, stream *s, uint extra, int code)
305
gs_copied_font_data_t *const cfdata = cf_data(copied);
311
fdata = gs_alloc_bytes(copied->memory, len + extra, "copied_data_alloc");
313
return_error(gs_error_VMerror);
314
s_init(s, copied->memory);
315
swrite_string(s, fdata, len);
316
cfdata->data = fdata;
317
cfdata->data_size = len + extra;
322
* Copy Subrs or GSubrs from a font.
325
copy_subrs(gs_font_type1 *pfont, bool global, gs_subr_info_t *psi,
330
gs_glyph_data_t gdata;
334
gdata.memory = pfont->memory;
335
/* Scan the font to determine the size of the subrs. */
336
for (i = 0, size = 0;
337
(code = pfont->data.procs.subr_data(pfont, i, global, &gdata)) !=
341
size += gdata.bits.size;
342
gs_glyph_data_free(&gdata, "copy_subrs");
346
data = 0, starts = 0, i = 0;
348
/* Allocate the copy. */
349
data = gs_alloc_bytes(mem, size, "copy_subrs(data)");
350
starts = (uint *)gs_alloc_byte_array(mem, i + 1, sizeof(*starts),
351
"copy_subrs(starts)");
352
if (data == 0 || starts == 0) {
353
gs_free_object(mem, starts, "copy_subrs(starts)");
354
gs_free_object(mem, data, "copy_subrs(data)");
355
return_error(gs_error_VMerror);
359
for (i = 0, size = 0;
360
(code = pfont->data.procs.subr_data(pfont, i, global, &gdata)) !=
365
memcpy(data + size, gdata.bits.data, gdata.bits.size);
366
size += gdata.bits.size;
367
gs_glyph_data_free(&gdata, "copy_subrs");
374
psi->starts = starts;
380
* Return a pointer to the definition of a copied glyph, accessed either by
381
* name or by glyph number. If the glyph is out of range, return
382
* gs_error_rangecheck; if the glyph is in range but undefined, store a
383
* pointer to the slot where it would be added, which will have gdata.data
384
* == 0, and return gs_error_undefined; if the glyph is defined, store the
385
* pointer and return 0.
388
copied_glyph_slot(gs_copied_font_data_t *cfdata, gs_glyph glyph,
389
gs_copied_glyph_t **pslot)
391
uint gsize = cfdata->glyphs_size;
394
if (glyph >= GS_MIN_GLYPH_INDEX) {
395
/* CIDFontType 2 uses glyph indices for slots. */
396
if (glyph - GS_MIN_GLYPH_INDEX >= gsize)
397
return_error(gs_error_rangecheck);
398
*pslot = &cfdata->glyphs[glyph - GS_MIN_GLYPH_INDEX];
399
} else if (glyph >= GS_MIN_CID_GLYPH) {
400
/* CIDFontType 0 uses CIDS for slots. */
401
if (glyph - GS_MIN_CID_GLYPH >= gsize)
402
return_error(gs_error_rangecheck);
403
*pslot = &cfdata->glyphs[glyph - GS_MIN_CID_GLYPH];
404
} else if (cfdata->names == 0)
405
return_error(gs_error_rangecheck);
407
int code = cfdata->procs->named_glyph_slot(cfdata, glyph, pslot);
413
return_error(gs_error_undefined);
417
named_glyph_slot_none(gs_copied_font_data_t *cfdata, gs_glyph glyph,
418
gs_copied_glyph_t **pslot)
420
return_error(gs_error_rangecheck);
423
named_glyph_slot_hashed(gs_copied_font_data_t *cfdata, gs_glyph glyph,
424
gs_copied_glyph_t **pslot)
426
uint gsize = cfdata->glyphs_size;
427
gs_copied_glyph_name_t *names = cfdata->names;
428
uint hash = (uint)glyph % gsize;
430
* gsize is either a prime number or a power of 2.
431
* If it is prime, any positive reprobe below gsize guarantees that we
432
* will touch every slot.
433
* If it is a power of 2, any odd reprobe guarantees that we
434
* will touch every slot.
436
uint hash2 = ((uint)glyph / gsize * 2 + 1) % gsize;
439
while (names[hash].str.data != 0 && names[hash].glyph != glyph) {
440
hash = (hash + hash2) % gsize;
442
return gs_error_undefined;
445
*pslot = &cfdata->glyphs[hash];
449
named_glyph_slot_linear(gs_copied_font_data_t *cfdata, gs_glyph glyph,
450
gs_copied_glyph_t **pslot)
453
gs_copied_glyph_name_t *names = cfdata->names;
456
for (i = 0; i < cfdata->glyphs_size; ++i)
457
if (names[i].glyph == glyph) {
458
*pslot = &cfdata->glyphs[i];
462
/* This might be a glyph with multiple names. Search extra_names. */
464
gs_copied_glyph_extra_name_t *extra_name = cfdata->extra_names;
466
for (; extra_name != 0; extra_name = extra_name->next)
467
if (extra_name->name.glyph == glyph) {
468
*pslot = &cfdata->glyphs[extra_name->gid];
472
return_error(gs_error_rangecheck);
476
* Add glyph data to the glyph table. This handles copying the vector
477
* data, detecting attempted redefinitions, and freeing temporary glyph
478
* data. The glyph must be an integer, an index in the glyph table.
479
* Return 1 if the glyph was already defined, 0 if newly added (or an
480
* error per options).
483
copy_glyph_data(gs_font *font, gs_glyph glyph, gs_font *copied, int options,
484
gs_glyph_data_t *pgdata, const byte *prefix, int prefix_bytes)
486
gs_copied_font_data_t *const cfdata = cf_data(copied);
487
uint size = pgdata->bits.size;
488
gs_copied_glyph_t *pcg = 0;
489
int code = copied_glyph_slot(cfdata, glyph, &pcg);
492
return_error(gs_error_unregistered); /* Must not happen. */
494
case 0: /* already defined */
495
if ((options & COPY_GLYPH_NO_OLD) ||
496
pcg->gdata.size != prefix_bytes + size ||
497
memcmp(pcg->gdata.data, prefix, prefix_bytes) ||
498
memcmp(pcg->gdata.data + prefix_bytes,
499
pgdata->bits.data, size)
501
code = gs_note_error(gs_error_invalidaccess);
505
case gs_error_undefined:
506
if (options & COPY_GLYPH_NO_NEW)
507
code = gs_note_error(gs_error_undefined);
508
else if (pcg == NULL)
509
code = gs_note_error(gs_error_undefined);
511
uint str_size = prefix_bytes + size;
512
byte *str = gs_alloc_string(copied->memory, str_size,
513
"copy_glyph_data(data)");
516
code = gs_note_error(gs_error_VMerror);
519
memcpy(str, prefix, prefix_bytes);
520
memcpy(str + prefix_bytes, pgdata->bits.data, size);
521
pcg->gdata.data = str;
522
pcg->gdata.size = str_size;
523
pcg->used = HAS_DATA;
524
pcg->order_index = -1;
526
cfdata->num_glyphs++;
532
gs_glyph_data_free(pgdata, "copy_glyph_data");
537
* Copy a glyph name into the names table.
540
copy_glyph_name(gs_font *font, gs_glyph glyph, gs_font *copied,
541
gs_glyph copied_glyph)
543
gs_glyph known_glyph;
544
gs_copied_font_data_t *const cfdata = cf_data(copied);
545
gs_copied_glyph_t *pcg;
546
int code = copied_glyph_slot(cfdata, copied_glyph, &pcg);
547
gs_copied_glyph_name_t *pcgn;
551
return_error(gs_error_unregistered); /* Must not happen. */
553
(code = font->procs.glyph_name(font, glyph, &str)) < 0
556
/* Try to share a permanently allocated known glyph name. */
557
if ((known_glyph = gs_c_name_glyph(str.data, str.size)) != GS_NO_GLYPH)
558
gs_c_glyph_name(known_glyph, &str);
559
else if ((code = copy_string(copied->memory, &str, "copy_glyph_name")) < 0)
561
pcgn = cfdata->names + (pcg - cfdata->glyphs);
562
if (pcgn->glyph != GS_NO_GLYPH &&
563
(pcgn->str.size != str.size ||
564
memcmp(pcgn->str.data, str.data, str.size))
566
/* This is a glyph with multiple names. Add an extra_name entry. */
567
gs_copied_glyph_extra_name_t *extra_name =
568
gs_alloc_struct(copied->memory, gs_copied_glyph_extra_name_t,
569
&st_gs_copied_glyph_extra_name,
570
"copy_glyph_name(extra_name)");
573
return_error(gs_error_VMerror);
574
extra_name->next = cfdata->extra_names;
575
extra_name->gid = pcg - cfdata->glyphs;
576
cfdata->extra_names = extra_name;
577
pcgn = &extra_name->name;
585
* Find the .notdef glyph in a font.
588
find_notdef(gs_font_base *font)
593
while (font->procs.enumerate_glyph((gs_font *)font, &index,
594
GLYPH_SPACE_NAME, &glyph),
596
if (gs_font_glyph_is_notdef(font, glyph))
598
return GS_NO_GLYPH; /* best we can do */
602
* Add an Encoding entry to a character-indexed font (Type 1/2/42).
605
copied_char_add_encoding(gs_font *copied, gs_char chr, gs_glyph glyph)
607
gs_copied_font_data_t *const cfdata = cf_data(copied);
608
gs_glyph *Encoding = cfdata->Encoding;
609
gs_copied_glyph_t *pslot;
613
return_error(gs_error_unregistered); /* Must not happen. */
615
return_error(gs_error_invalidaccess);
616
if (chr >= 256 || glyph >= GS_MIN_CID_GLYPH)
617
return_error(gs_error_rangecheck);
618
code = copied_glyph_slot(cfdata, glyph, &pslot);
621
if (Encoding[chr] != glyph && Encoding[chr] != GS_NO_GLYPH)
622
return_error(gs_error_invalidaccess);
623
Encoding[chr] = glyph;
627
/* Don't allow adding an Encoding entry. */
629
copied_no_add_encoding(gs_font *copied, gs_char chr, gs_glyph glyph)
631
return_error(gs_error_invalidaccess);
634
/* ---------------- Font procedures ---------------- */
637
copied_font_info(gs_font *font, const gs_point *pscale, int members,
638
gs_font_info_t *info)
641
return_error(gs_error_rangecheck);
642
*info = cf_data(font)->info;
647
copied_encode_char(gs_font *copied, gs_char chr, gs_glyph_space_t glyph_space)
649
gs_copied_font_data_t *const cfdata = cf_data(copied);
650
const gs_glyph *Encoding = cfdata->Encoding;
652
if (chr >= 256 || Encoding == 0)
654
return Encoding[chr];
658
copied_enumerate_glyph(gs_font *font, int *pindex,
659
gs_glyph_space_t glyph_space, gs_glyph *pglyph)
661
gs_copied_font_data_t *const cfdata = cf_data(font);
663
if (cfdata->ordered) {
664
if (*pindex >= cfdata->num_glyphs)
667
int i = cfdata->glyphs[*pindex].order_index;
669
*pglyph = cfdata->names[i].glyph;
674
for (; *pindex < cfdata->glyphs_size; ++*pindex)
675
if (cfdata->glyphs[*pindex].used) {
677
(glyph_space == GLYPH_SPACE_NAME && cfdata->names != 0 ?
678
cfdata->names[*pindex].glyph :
679
/* CIDFontType 0 uses CIDS as slot indices; CIDFontType 2 uses GIDs. */
680
*pindex + (glyph_space == GLYPH_SPACE_NAME
681
? GS_MIN_CID_GLYPH : GS_MIN_GLYPH_INDEX));
690
copied_glyph_name(gs_font *font, gs_glyph glyph, gs_const_string *pstr)
692
gs_copied_font_data_t *const cfdata = cf_data(font);
693
gs_copied_glyph_t *pcg;
695
if (glyph >= GS_MIN_CID_GLYPH)
696
return_error(gs_error_rangecheck);
697
if (copied_glyph_slot(cfdata, glyph, &pcg) < 0)
698
return_error(gs_error_undefined);
699
*pstr = cfdata->names[pcg - cfdata->glyphs].str;
704
copied_build_char(gs_show_enum *pte, gs_state *pgs, gs_font *font,
705
gs_char chr, gs_glyph glyph)
707
int wmode = font->WMode;
709
gs_glyph_info_t info;
711
double sbw_stub[4]; /* Currently glyph_outline retrieves sbw only with type 1,2,9 fonts. */
713
if (glyph == GS_NO_GLYPH) {
714
glyph = font->procs.encode_char(font, chr, GLYPH_SPACE_INDEX);
715
if (glyph == GS_NO_GLYPH)
716
glyph = cf_data(font)->notdef;
719
* Type 1/2 outlines don't require a current point, but TrueType
720
* outlines do. We might want to fix this someday....
722
if ((code = gs_moveto(pgs, 0.0, 0.0)) < 0 ||
723
(code = font->procs.glyph_info(font, glyph, NULL,
724
(GLYPH_INFO_WIDTH << wmode) |
726
GLYPH_INFO_OUTLINE_WIDTHS,
730
wxy[0] = info.width[wmode].x;
731
wxy[1] = info.width[wmode].y;
732
wxy[2] = info.bbox.p.x;
733
wxy[3] = info.bbox.p.y;
734
wxy[4] = info.bbox.q.x;
735
wxy[5] = info.bbox.q.y;
736
if ((code = gs_setcachedevice_double(pte, pte->pgs, wxy)) < 0 ||
737
(code = font->procs.glyph_outline(font, wmode, glyph, &ctm_only(pgs),
738
pgs->path, sbw_stub)) < 0
741
if (font->PaintType != 0) {
742
gs_setlinewidth(pgs, font->StrokeWidth);
743
return gs_stroke(pgs);
750
compare_arrays(const float *v0, int l0, const float *v1, int l1)
754
if (memcmp(v0, v1, l0 * sizeof(v0[0])))
759
#define compare_tables(a, b) compare_arrays(a.values, a.count, b.values, b.count)
762
compare_glyphs(const gs_font *cfont, const gs_font *ofont, gs_glyph *glyphs,
763
int num_glyphs, int glyphs_step, int level)
766
* Checking widths because we can synthesize fonts from random fonts
767
* having same FontName and FontType.
768
* We must request width explicitely because Type 42 stores widths
769
* separately from outline data. We could skip it for Type 1, which doesn't.
770
* We don't care of Metrics, Metrics2 because copied font never has them.
772
int i, WMode = ofont->WMode;
773
int members = (GLYPH_INFO_WIDTH0 << WMode) | GLYPH_INFO_OUTLINE_WIDTHS | GLYPH_INFO_NUM_PIECES;
775
gs_copied_font_data_t *const cfdata = cf_data(cfont);
776
int num_new_glyphs = 0;
778
gs_make_identity(&mat);
779
for (i = 0; i < num_glyphs; i++) {
780
gs_glyph glyph = *(gs_glyph *)((byte *)glyphs + i * glyphs_step);
781
gs_glyph pieces0[40], *pieces = pieces0;
782
gs_glyph_info_t info0, info1;
783
int code0 = ofont->procs.glyph_info((gs_font *)ofont, glyph, &mat, members, &info0);
784
int code1 = cfont->procs.glyph_info((gs_font *)cfont, glyph, &mat, members, &info1);
787
if (code0 == gs_error_undefined)
789
if (code1 == gs_error_undefined) {
791
if (num_new_glyphs > cfdata->glyphs_size - cfdata->num_glyphs)
799
if (info0.num_pieces != info1.num_pieces)
801
if (info0.width[WMode].x != info1.width[WMode].x ||
802
info0.width[WMode].y != info1.width[WMode].y)
804
if (WMode && (info0.v.x != info1.v.x || info0.v.y != info1.v.y))
806
if (info0.num_pieces > 0) {
808
return_error(gs_error_rangecheck); /* abnormal glyph recursion */
809
if (info0.num_pieces > countof(pieces0) / 2) {
810
pieces = (gs_glyph *)gs_alloc_bytes(cfont->memory,
811
sizeof(glyphs) * info0.num_pieces * 2, "compare_glyphs");
813
return_error(gs_error_VMerror);
815
info0.pieces = pieces;
816
info1.pieces = pieces + info0.num_pieces;
817
code0 = ofont->procs.glyph_info((gs_font *)ofont, glyph, &mat,
818
GLYPH_INFO_PIECES, &info0);
819
code1 = cfont->procs.glyph_info((gs_font *)cfont, glyph, &mat,
820
GLYPH_INFO_PIECES, &info1);
821
if (code0 >= 0 && code1 >= 0) {
822
code2 = memcmp(info0.pieces, info1.pieces, info0.num_pieces * sizeof(*pieces));
824
code = compare_glyphs(cfont, ofont, pieces, info0.num_pieces, glyphs_step, level + 1);
826
code = 0; /* Quiet compiler. */
829
if (pieces != pieces0)
830
gs_free_object(cfont->memory, pieces, "compare_glyphs");
831
if (code0 == gs_error_undefined)
833
if (code1 == gs_error_undefined) {
835
if (num_new_glyphs > cfdata->glyphs_size - cfdata->num_glyphs)
843
if (code2 || code == 0) {
847
gs_glyph_data_t gdata0, gdata1;
849
switch(cfont->FontType) {
851
case ft_encrypted2: {
852
gs_font_type1 *font0 = (gs_font_type1 *)cfont;
853
gs_font_type1 *font1 = (gs_font_type1 *)ofont;
855
gdata0.memory = font0->memory;
856
gdata1.memory = font1->memory;
857
code0 = font0->data.procs.glyph_data(font0, glyph, &gdata0);
858
code1 = font1->data.procs.glyph_data(font1, glyph, &gdata1);
862
case ft_CID_TrueType: {
863
gs_font_type42 *font0 = (gs_font_type42 *)cfont;
864
gs_font_type42 *font1 = (gs_font_type42 *)ofont;
865
uint glyph_index0 = font0->data.get_glyph_index(font0, glyph);
866
uint glyph_index1 = font1->data.get_glyph_index(font1, glyph);
868
gdata0.memory = font0->memory;
869
gdata1.memory = font1->memory;
870
code0 = font0->data.get_outline(font0, glyph_index0, &gdata0);
871
code1 = font1->data.get_outline(font1, glyph_index1, &gdata1);
874
case ft_CID_encrypted: {
875
gs_font_cid0 *font0 = (gs_font_cid0 *)cfont;
876
gs_font_cid0 *font1 = (gs_font_cid0 *)ofont;
879
gdata0.memory = font0->memory;
880
gdata1.memory = font1->memory;
881
code0 = font0->cidata.glyph_data((gs_font_base *)font0, glyph, &gdata0, &fidx0);
882
code1 = font1->cidata.glyph_data((gs_font_base *)font1, glyph, &gdata1, &fidx1);
886
return_error(gs_error_unregistered); /* unimplemented */
890
gs_glyph_data_free(&gdata1, "compare_glyphs");
895
gs_glyph_data_free(&gdata0, "compare_glyphs");
898
if (gdata0.bits.size != gdata1.bits.size)
900
if (memcmp(gdata0.bits.data, gdata0.bits.data, gdata0.bits.size))
902
gs_glyph_data_free(&gdata0, "compare_glyphs");
903
gs_glyph_data_free(&gdata1, "compare_glyphs");
909
/* ---------------- Individual FontTypes ---------------- */
911
/* ------ Type 1 ------ */
914
copied_type1_glyph_data(gs_font_type1 * pfont, gs_glyph glyph,
915
gs_glyph_data_t *pgd)
917
gs_copied_font_data_t *const cfdata = cf_data((gs_font *)pfont);
918
gs_copied_glyph_t *pslot;
919
int code = copied_glyph_slot(cfdata, glyph, &pslot);
923
gs_glyph_data_from_string(pgd, pslot->gdata.data, pslot->gdata.size,
929
copied_type1_subr_data(gs_font_type1 * pfont, int subr_num, bool global,
930
gs_glyph_data_t *pgd)
932
gs_copied_font_data_t *const cfdata = cf_data((gs_font *)pfont);
933
const gs_subr_info_t *psi =
934
(global ? &cfdata->global_subrs : &cfdata->subrs);
936
if (subr_num < 0 || subr_num >= psi->count)
937
return_error(gs_error_rangecheck);
938
gs_glyph_data_from_string(pgd, psi->data + psi->starts[subr_num],
939
psi->starts[subr_num + 1] -
940
psi->starts[subr_num],
946
copied_type1_seac_data(gs_font_type1 * pfont, int ccode,
947
gs_glyph * pglyph, gs_const_string *gstr, gs_glyph_data_t *pgd)
950
* This can only be invoked if the components have already been
951
* copied to their proper positions, so it is simple.
953
gs_glyph glyph = gs_c_known_encode((gs_char)ccode, ENCODING_INDEX_STANDARD);
957
if (glyph == GS_NO_GLYPH)
958
return_error(gs_error_rangecheck);
959
code = gs_c_glyph_name(glyph, gstr);
962
code = pfont->dir->global_glyph_code(pfont->memory, gstr, &glyph1);
968
return copied_type1_glyph_data(pfont, glyph1, pgd);
974
copied_type1_push_values(void *callback_data, const fixed *values, int count)
976
return_error(gs_error_unregistered);
980
copied_type1_pop_value(void *callback_data, fixed *value)
982
return_error(gs_error_unregistered);
986
copy_font_type1(gs_font *font, gs_font *copied)
988
gs_font_type1 *font1 = (gs_font_type1 *)font;
989
gs_font_type1 *copied1 = (gs_font_type1 *)copied;
990
gs_copied_font_data_t *const cfdata = cf_data(copied);
993
cfdata->notdef = find_notdef((gs_font_base *)font);
994
code = copied_Encoding_alloc(copied);
997
if ((code = copy_subrs(font1, false, &cfdata->subrs, copied->memory)) < 0 ||
998
(code = copy_subrs(font1, true, &cfdata->global_subrs, copied->memory)) < 0
1000
gs_free_object(copied->memory, cfdata->Encoding,
1001
"copy_font_type1(Encoding)");
1005
* We don't need real push/pop procedures, because we can't do anything
1006
* useful with fonts that have non-standard OtherSubrs anyway.
1008
copied1->data.procs.glyph_data = copied_type1_glyph_data;
1009
copied1->data.procs.subr_data = copied_type1_subr_data;
1010
copied1->data.procs.seac_data = copied_type1_seac_data;
1011
copied1->data.procs.push_values = copied_type1_push_values;
1012
copied1->data.procs.pop_value = copied_type1_pop_value;
1013
copied1->data.proc_data = 0;
1018
copy_glyph_type1(gs_font *font, gs_glyph glyph, gs_font *copied, int options)
1020
gs_glyph_data_t gdata;
1021
gs_font_type1 *font1 = (gs_font_type1 *)font;
1025
gdata.memory = font->memory;
1026
code = font1->data.procs.glyph_data(font1, glyph, &gdata);
1029
code = copy_glyph_data(font, glyph, copied, options, &gdata, NULL, 0);
1034
code = copy_glyph_name(font, glyph, copied, glyph);
1035
return (code < 0 ? code : rcode);
1039
copied_type1_glyph_outline(gs_font *font, int WMode, gs_glyph glyph,
1040
const gs_matrix *pmat, gx_path *ppath, double sbw[4])
1042
* 'WMode' may be inherited from an upper font.
1043
* We ignore in because Type 1,2 charstrings do not depend on it.
1047
* This code duplicates much of zcharstring_outline in zchar1.c.
1048
* This is unfortunate, but we don't see a simple way to refactor the
1051
gs_glyph_data_t gdata;
1052
gs_font_type1 *const pfont1 = (gs_font_type1 *)font;
1054
const gs_glyph_data_t *pgd = &gdata;
1056
gs_imager_state gis;
1058
gdata.memory = pfont1->memory;
1059
code = pfont1->data.procs.glyph_data(pfont1, glyph, &gdata);
1062
if (pgd->bits.size <= max(pfont1->data.lenIV, 0))
1063
return_error(gs_error_invalidfont);
1064
/* Initialize just enough of the imager state. */
1066
gs_matrix_fixed_from_matrix(&gis.ctm, pmat);
1070
gs_make_identity(&imat);
1071
gs_matrix_fixed_from_matrix(&gis.ctm, &imat);
1074
code = gs_type1_interp_init(&cis, &gis, ppath, NULL, NULL, true, 0,
1078
cis.no_grid_fitting = true;
1079
/* Continue interpreting. */
1083
code = pfont1->data.interpret(&cis, pgd, &value);
1085
case 0: /* all done */
1087
default: /* code < 0, error */
1089
case type1_result_callothersubr: /* unknown OtherSubr */
1090
return_error(gs_error_rangecheck); /* can't handle it */
1091
case type1_result_sbw: /* [h]sbw, just continue */
1093
type1_cis_get_metrics(&cis, sbw);
1098
static const gs_copied_font_procs_t copied_procs_type1 = {
1099
copy_font_type1, copy_glyph_type1, copied_char_add_encoding,
1100
named_glyph_slot_hashed,
1101
copied_encode_char, gs_type1_glyph_info, copied_type1_glyph_outline
1105
same_type1_subrs(const gs_font_type1 *cfont, const gs_font_type1 *ofont,
1108
gs_glyph_data_t gdata0, gdata1;
1112
gdata0.memory = cfont->memory;
1113
gdata1.memory = ofont->memory;
1114
/* Scan the font to determine the size of the subrs. */
1115
for (i = 0; !exit; i++) {
1116
int code0 = cfont->data.procs.subr_data((gs_font_type1 *)cfont,
1117
i, global, &gdata0);
1118
int code1 = ofont->data.procs.subr_data((gs_font_type1 *)ofont,
1119
i, global, &gdata1);
1120
bool missing0, missing1;
1122
if (code0 == gs_error_rangecheck && code1 == gs_error_rangecheck)
1123
return 1; /* Both arrays exceeded. */
1124
/* Some fonts use null for skiping elements in subrs array.
1125
This gives typecheck.
1127
missing0 = (code0 == gs_error_rangecheck || code0 == gs_error_typecheck);
1128
missing1 = (code1 == gs_error_rangecheck || code1 == gs_error_typecheck);
1129
if (missing0 && missing1)
1131
if (missing0 && !missing1)
1132
return 0; /* The copy has insufficient subrs. */
1136
code = code0, exit = true;
1138
code = code1, exit = true;
1139
else if (gdata0.bits.size != gdata1.bits.size)
1141
else if (memcmp(gdata0.bits.data, gdata1.bits.data, gdata0.bits.size))
1144
gs_glyph_data_free(&gdata0, "same_type1_subrs");
1146
gs_glyph_data_free(&gdata1, "same_type1_subrs");
1152
same_type1_hinting(const gs_font_type1 *cfont, const gs_font_type1 *ofont)
1154
const gs_type1_data *d0 = &cfont->data, *d1 = &ofont->data;
1156
if (d0->lenIV != d1->lenIV)
1159
if (d0->defaultWidthX != d1->defaultWidthX)
1161
if (d0->nominalWidthX != d1->nominalWidthX)
1164
if (d0->BlueFuzz != d1->BlueFuzz)
1166
if (d0->BlueScale != d1->BlueScale)
1168
if (d0->BlueShift != d1->BlueShift)
1170
if (d0->ExpansionFactor != d1->ExpansionFactor)
1172
if (d0->ForceBold != d1->ForceBold)
1174
if (!compare_tables(d0->FamilyBlues, d1->FamilyBlues))
1176
if (!compare_tables(d0->FamilyOtherBlues, d1->FamilyOtherBlues))
1178
if (d0->LanguageGroup != d1->LanguageGroup)
1180
if (!compare_tables(d0->OtherBlues, d1->OtherBlues))
1182
if (d0->RndStemUp != d1->RndStemUp)
1184
if (!compare_tables(d0->StdHW, d1->StdHW))
1186
if (!compare_tables(d0->StemSnapH, d1->StemSnapH))
1188
if (!compare_tables(d0->StemSnapV, d1->StemSnapV))
1190
if (!compare_tables(d0->WeightVector, d1->WeightVector))
1192
if (!same_type1_subrs(cfont, ofont, false))
1194
if (!same_type1_subrs(cfont, ofont, true))
1197
* We ignore differences in OtherSubrs because pdfwrite
1198
* must build without PS interpreter and therefore copied font
1199
* have no storage for them.
1204
/* ------ Type 42 ------ */
1207
copied_type42_string_proc(gs_font_type42 *font, ulong offset, uint len,
1210
gs_copied_font_data_t *const cfdata = font->data.proc_data;
1212
if (offset + len > cfdata->data_size)
1213
return_error(gs_error_rangecheck);
1214
*pstr = cfdata->data + offset;
1219
copied_type42_get_outline(gs_font_type42 *font, uint glyph_index,
1220
gs_glyph_data_t *pgd)
1222
gs_copied_font_data_t *const cfdata = font->data.proc_data;
1223
gs_copied_glyph_t *pcg;
1225
if (glyph_index >= cfdata->glyphs_size)
1226
return_error(gs_error_rangecheck);
1227
pcg = &cfdata->glyphs[glyph_index];
1229
gs_glyph_data_from_null(pgd);
1231
gs_glyph_data_from_string(pgd, pcg->gdata.data, pcg->gdata.size, NULL);
1236
copied_type42_get_metrics(gs_font_type42 * pfont, uint glyph_index,
1237
gs_type42_metrics_options_t options, float sbw[4])
1239
/* Check whether we have metrics for this (glyph,wmode) pair. */
1240
gs_copied_font_data_t *const cfdata = pfont->data.proc_data;
1241
gs_copied_glyph_t *pcg;
1242
int wmode = gs_type42_metrics_options_wmode(options);
1244
if (glyph_index >= cfdata->glyphs_size)
1245
return_error(gs_error_rangecheck);
1246
pcg = &cfdata->glyphs[glyph_index];
1247
if (!(pcg->used & (HAS_SBW0 << wmode)))
1248
return_error(gs_error_undefined);
1249
return gs_type42_default_get_metrics(pfont, glyph_index, options, sbw);
1253
copied_type42_get_glyph_index(gs_font_type42 *font, gs_glyph glyph)
1255
gs_copied_font_data_t *const cfdata = cf_data((gs_font *)font);
1256
gs_copied_glyph_t *pcg;
1257
int code = copied_glyph_slot(cfdata, glyph, &pcg);
1261
return pcg - cfdata->glyphs;
1265
copy_font_type42(gs_font *font, gs_font *copied)
1267
gs_font_type42 *const font42 = (gs_font_type42 *)font;
1268
gs_font_type42 *const copied42 = (gs_font_type42 *)copied;
1269
gs_copied_font_data_t *const cfdata = cf_data(copied);
1271
* We "write" the font, aside from the glyphs, into an in-memory
1272
* structure, and access it from there.
1273
* We allocate room at the end of the copied data for fake hmtx/vmtx.
1275
uint extra = font42->data.trueNumGlyphs * 8;
1279
cfdata->notdef = find_notdef((gs_font_base *)font);
1280
code = copied_Encoding_alloc(copied);
1283
s_init(&fs, font->memory);
1284
swrite_position_only(&fs);
1285
code = (font->FontType == ft_TrueType ? psf_write_truetype_stripped(&fs, font42)
1286
: psf_write_cid2_stripped(&fs, (gs_font_cid2 *)font42));
1287
code = copied_data_alloc(copied, &fs, extra, code);
1290
if (font->FontType == ft_TrueType)
1291
psf_write_truetype_stripped(&fs, font42);
1293
psf_write_cid2_stripped(&fs, (gs_font_cid2 *)font42);
1294
copied42->data.string_proc = copied_type42_string_proc;
1295
copied42->data.proc_data = cfdata;
1296
code = gs_type42_font_init(copied42, 0);
1299
/* gs_type42_font_init overwrites font_info. */
1300
copied->procs.font_info = copied_font_info;
1301
/* gs_type42_font_init overwrites enumerate_glyph. */
1302
copied42->procs.enumerate_glyph = copied_enumerate_glyph;
1303
copied42->data.get_glyph_index = copied_type42_get_glyph_index;
1304
copied42->data.get_outline = copied_type42_get_outline;
1305
copied42->data.get_metrics = copied_type42_get_metrics;
1306
copied42->data.metrics[0].numMetrics =
1307
copied42->data.metrics[1].numMetrics =
1309
copied42->data.metrics[0].offset = cfdata->data_size - extra;
1310
copied42->data.metrics[1].offset = cfdata->data_size - extra / 2;
1311
copied42->data.metrics[0].length =
1312
copied42->data.metrics[1].length =
1314
memset(cfdata->data + cfdata->data_size - extra, 0, extra);
1315
copied42->data.numGlyphs = font42->data.numGlyphs;
1316
copied42->data.trueNumGlyphs = font42->data.trueNumGlyphs;
1319
gs_free_object(copied->memory, cfdata->data,
1320
"copy_font_type42(data)");
1322
gs_free_object(copied->memory, cfdata->Encoding,
1323
"copy_font_type42(Encoding)");
1328
copy_glyph_type42(gs_font *font, gs_glyph glyph, gs_font *copied, int options)
1330
gs_glyph_data_t gdata;
1331
gs_font_type42 *font42 = (gs_font_type42 *)font;
1332
gs_font_cid2 *fontCID2 = (gs_font_cid2 *)font;
1333
gs_font_type42 *const copied42 = (gs_font_type42 *)copied;
1334
uint gid = (options & COPY_GLYPH_BY_INDEX ? glyph - GS_MIN_GLYPH_INDEX :
1335
font->FontType == ft_CID_TrueType
1336
? fontCID2->cidata.CIDMap_proc(fontCID2, glyph)
1337
: font42->data.get_glyph_index(font42, glyph));
1340
gs_copied_font_data_t *const cfdata = cf_data(copied);
1341
gs_copied_glyph_t *pcg;
1343
double factor = font42->data.unitsPerEm;
1346
gdata.memory = font42->memory;
1347
code = font42->data.get_outline(font42, gid, &gdata);
1350
code = copy_glyph_data(font, gid + GS_MIN_GLYPH_INDEX, copied, options,
1355
if (glyph < GS_MIN_CID_GLYPH)
1356
code = copy_glyph_name(font, glyph, copied,
1357
gid + GS_MIN_GLYPH_INDEX);
1358
DISCARD(copied_glyph_slot(cfdata, gid + GS_MIN_GLYPH_INDEX, &pcg)); /* can't fail */
1359
for (i = 0; i < 2; ++i) {
1360
if (font42->data.get_metrics(font42, gid, i, sbw) >= 0) {
1361
int sb = (int)(sbw[i] * factor + 0.5);
1362
uint width = (uint)(sbw[2 + i] * factor + 0.5);
1364
cfdata->data + copied42->data.metrics[i].offset + gid * 4;
1366
pmetrics[0] = (byte)(width >> 8);
1367
pmetrics[1] = (byte)width;
1368
pmetrics[2] = (byte)(sb >> 8);
1369
pmetrics[3] = (byte)sb;
1370
pcg->used |= HAS_SBW0 << i;
1372
factor = -factor; /* values are negated for WMode = 1 */
1374
return (code < 0 ? code : rcode);
1378
copied_type42_encode_char(gs_font *copied, gs_char chr,
1379
gs_glyph_space_t glyph_space)
1381
gs_copied_font_data_t *const cfdata = cf_data(copied);
1382
const gs_glyph *Encoding = cfdata->Encoding;
1385
if (chr >= 256 || Encoding == 0)
1387
glyph = Encoding[chr];
1388
if (glyph_space == GLYPH_SPACE_INDEX) {
1389
/* Search linearly for the glyph by name. */
1390
gs_copied_glyph_t *pcg;
1391
int code = named_glyph_slot_linear(cfdata, glyph, &pcg);
1393
if (code < 0 || !pcg->used)
1395
return GS_MIN_GLYPH_INDEX + (pcg - cfdata->glyphs);
1401
static const gs_copied_font_procs_t copied_procs_type42 = {
1402
copy_font_type42, copy_glyph_type42, copied_char_add_encoding,
1403
named_glyph_slot_linear,
1404
copied_type42_encode_char, gs_type42_glyph_info, gs_type42_glyph_outline
1408
access_type42_data(gs_font_type42 *pfont, ulong base, ulong length,
1411
return pfont->data.string_proc(pfont, base, length, vptr);
1417
return ((uint)p[0] << 8) + p[1];
1421
same_type42_hinting(gs_font_type42 *font0, gs_font_type42 *font1)
1423
gs_type42_data *d0 = &font0->data, *d1 = &font1->data;
1424
gs_font_type42 *font[2];
1426
uint len[2][3] = {{0,0,0}, {0,0,0}};
1429
if (d0->unitsPerEm != d1->unitsPerEm)
1433
memset(pos, 0, sizeof(pos));
1434
for (j = 0; j < 2; j++) {
1435
const byte *OffsetTable;
1438
code = access_type42_data(font[j], 0, 12, &OffsetTable);
1441
numTables = U16(OffsetTable + 4);
1442
for (i = 0; i < numTables; ++i) {
1447
code = access_type42_data(font[j], 12 + i * 16, 16, &tab);
1450
start = get_u32_msb(tab + 8);
1451
length = get_u32_msb(tab + 12);
1452
if (!memcmp("prep", tab, 4))
1453
pos[j][0] = start, len[j][0] = length;
1454
else if (!memcmp("cvt ", tab, 4))
1455
pos[j][1] = start, len[j][1] = length;
1456
else if (!memcmp("fpgm", tab, 4))
1457
pos[j][2] = start, len[j][2] = length;
1460
for (i = 0; i < 3; i++) {
1461
if (len[0][i] != len[1][i])
1464
for (i = 0; i < 3; i++) {
1465
if (len[0][i] != 0) {
1466
const byte *data0, *data1;
1467
ulong length = len[0][i], size0, size1, size;
1468
ulong pos0 = pos[0][i], pos1 = pos[1][i];
1470
while (length > 0) {
1471
code = access_type42_data(font0, pos0, length, &data0);
1474
size0 = (code == 0 ? length : code);
1475
code = access_type42_data(font1, pos1, length, &data1);
1478
size1 = (code == 0 ? length : code);
1479
size = min(size0, size1);
1480
if (memcmp(data0, data1, size))
1491
/* ------ CIDFont shared ------ */
1494
copy_font_cid_common(gs_font *font, gs_font *copied, gs_font_cid_data *pcdata)
1496
return (copy_string(copied->memory, &pcdata->CIDSystemInfo.Registry,
1498
copy_string(copied->memory, &pcdata->CIDSystemInfo.Ordering,
1502
/* ------ CIDFontType 0 ------ */
1505
copied_cid0_glyph_data(gs_font_base *font, gs_glyph glyph,
1506
gs_glyph_data_t *pgd, int *pfidx)
1508
gs_font_cid0 *fcid0 = (gs_font_cid0 *)font;
1509
gs_copied_font_data_t *const cfdata = cf_data((gs_font *)font);
1510
gs_copied_glyph_t *pcg;
1511
int code = copied_glyph_slot(cfdata, glyph, &pcg);
1512
int fdbytes = fcid0->cidata.FDBytes;
1519
gs_glyph_data_from_null(pgd);
1520
return_error(gs_error_undefined);
1523
for (i = 0; i < fdbytes; ++i)
1524
*pfidx = (*pfidx << 8) + pcg->gdata.data[i];
1526
gs_glyph_data_from_string(pgd, pcg->gdata.data + fdbytes,
1527
pcg->gdata.size - fdbytes, NULL);
1531
copied_sub_type1_glyph_data(gs_font_type1 * pfont, gs_glyph glyph,
1532
gs_glyph_data_t *pgd)
1535
copied_cid0_glyph_data((gs_font_base *)cf_data((gs_font *)pfont)->parent,
1540
cid0_subfont(gs_font *copied, gs_glyph glyph, gs_font_type1 **pfont1)
1543
int code = copied_cid0_glyph_data((gs_font_base *)copied, glyph, NULL,
1547
gs_font_cid0 *font0 = (gs_font_cid0 *)copied;
1549
if (fidx >= font0->cidata.FDArray_size)
1550
return_error(gs_error_unregistered); /* Must not happen. */
1551
*pfont1 = font0->cidata.FDArray[fidx];
1557
copied_cid0_glyph_info(gs_font *font, gs_glyph glyph, const gs_matrix *pmat,
1558
int members, gs_glyph_info_t *info)
1560
gs_font_type1 *subfont1;
1561
int code = cid0_subfont(font, glyph, &subfont1);
1565
if (members & GLYPH_INFO_WIDTH1) {
1566
/* Hack : There is no way to pass WMode from font to glyph_info,
1567
* and usually CID font has no metrics for WMode 1.
1568
* Therefore we use FontBBox as default size.
1569
* Warning : this incompletely implements the request :
1570
* other requested members are not retrieved.
1572
gs_font_info_t finfo;
1573
int code = subfont1->procs.font_info(font, NULL, FONT_INFO_BBOX, &finfo);
1577
info->width[0].x = 0;
1578
info->width[0].y = 0;
1579
info->width[1].x = 0;
1580
info->width[1].y = -finfo.BBox.q.x; /* Sic! */
1581
info->v.x = finfo.BBox.q.x / 2;
1582
info->v.y = finfo.BBox.q.y;
1583
info->members = GLYPH_INFO_WIDTH1;
1586
return subfont1->procs.glyph_info((gs_font *)subfont1, glyph, pmat,
1591
copied_cid0_glyph_outline(gs_font *font, int WMode, gs_glyph glyph,
1592
const gs_matrix *pmat, gx_path *ppath, double sbw[4])
1594
gs_font_type1 *subfont1;
1595
int code = cid0_subfont(font, glyph, &subfont1);
1599
return subfont1->procs.glyph_outline((gs_font *)subfont1, WMode, glyph, pmat,
1604
copy_font_cid0(gs_font *font, gs_font *copied)
1606
gs_font_cid0 *copied0 = (gs_font_cid0 *)copied;
1607
gs_copied_font_data_t *const cfdata = cf_data(copied);
1608
gs_font_type1 **FDArray =
1609
gs_alloc_struct_array(copied->memory, copied0->cidata.FDArray_size,
1611
&st_gs_font_type1_ptr_element, "FDArray");
1615
return_error(gs_error_VMerror);
1616
code = copy_font_cid_common(font, copied, &copied0->cidata.common);
1619
for (; i < copied0->cidata.FDArray_size; ++i) {
1620
gs_font *subfont = (gs_font *)copied0->cidata.FDArray[i];
1621
gs_font_type1 *subfont1 = (gs_font_type1 *)subfont;
1623
gs_font_type1 *subcopy1;
1624
gs_copied_font_data_t *subdata;
1627
/* copy_subrs requires a Type 1 font, even for GSubrs. */
1628
code = copy_subrs(subfont1, true, &cfdata->global_subrs,
1633
code = gs_copy_font(subfont, &subfont->FontMatrix, copied->memory, &subcopy, -1);
1636
subcopy1 = (gs_font_type1 *)subcopy;
1637
subcopy1->data.parent = NULL;
1638
subdata = cf_data(subcopy);
1639
subdata->parent = copied0;
1640
gs_free_object(copied->memory, subdata->Encoding,
1641
"copy_font_cid0(Encoding)");
1642
subdata->Encoding = 0;
1644
* Share the glyph data and global_subrs with the parent. This
1645
* allows copied_type1_glyph_data in the subfont to do the right
1648
gs_free_object(copied->memory, subdata->names,
1649
"copy_font_cid0(subfont names)");
1650
gs_free_object(copied->memory, subdata->glyphs,
1651
"copy_font_cid0(subfont glyphs)");
1652
subcopy1->data.procs.glyph_data = copied_sub_type1_glyph_data;
1653
subdata->glyphs = cfdata->glyphs;
1654
subdata->glyphs_size = cfdata->glyphs_size;
1656
subdata->global_subrs = cfdata->global_subrs;
1657
FDArray[i] = subcopy1;
1659
cfdata->notdef = GS_MIN_CID_GLYPH;
1660
copied0->cidata.FDArray = FDArray;
1661
copied0->cidata.FDBytes =
1662
(copied0->cidata.FDArray_size <= 1 ? 0 :
1663
copied0->cidata.FDArray_size <= 256 ? 1 : 2);
1664
copied0->cidata.glyph_data = copied_cid0_glyph_data;
1668
gs_free_object(copied->memory, FDArray[i], "copy_font_cid0(subfont)");
1669
gs_free_object(copied->memory, FDArray, "FDArray");
1674
copy_glyph_cid0(gs_font *font, gs_glyph glyph, gs_font *copied, int options)
1676
gs_glyph_data_t gdata;
1677
gs_font_cid0 *fcid0 = (gs_font_cid0 *)font;
1678
gs_font_cid0 *copied0 = (gs_font_cid0 *)copied;
1679
int fdbytes = copied0->cidata.FDBytes;
1682
byte prefix[MAX_FDBytes];
1685
gdata.memory = font->memory;
1686
code = fcid0->cidata.glyph_data((gs_font_base *)font, glyph,
1690
for (i = fdbytes - 1; i >= 0; --i, fidx >>= 8)
1691
prefix[i] = (byte)fidx;
1693
return_error(gs_error_rangecheck);
1694
return copy_glyph_data(font, glyph, copied, options, &gdata, prefix, fdbytes);
1697
static const gs_copied_font_procs_t copied_procs_cid0 = {
1698
copy_font_cid0, copy_glyph_cid0, copied_no_add_encoding,
1699
named_glyph_slot_none,
1700
gs_no_encode_char, copied_cid0_glyph_info, copied_cid0_glyph_outline
1704
same_cid0_hinting(const gs_font_cid0 *cfont, const gs_font_cid0 *ofont)
1708
if (cfont->cidata.FDArray_size != ofont->cidata.FDArray_size)
1711
for (i = 0; i < cfont->cidata.FDArray_size; i++) {
1712
gs_font_type1 *subfont0 = cfont->cidata.FDArray[i];
1713
gs_font_type1 *subfont1 = ofont->cidata.FDArray[i];
1714
if (!same_type1_hinting(subfont0, subfont1))
1720
/* ------ CIDFontType 2 ------ */
1723
copied_cid2_CIDMap_proc(gs_font_cid2 *fcid2, gs_glyph glyph)
1725
uint cid = glyph - GS_MIN_CID_GLYPH;
1726
gs_copied_font_data_t *const cfdata = cf_data((gs_font *)fcid2);
1727
const ushort *CIDMap = cfdata->CIDMap;
1729
if (glyph < GS_MIN_CID_GLYPH || cid >= fcid2->cidata.common.CIDCount)
1730
return_error(gs_error_rangecheck);
1731
if (CIDMap[cid] == 0xffff)
1737
copied_cid2_get_glyph_index(gs_font_type42 *font, gs_glyph glyph)
1739
int glyph_index = copied_cid2_CIDMap_proc((gs_font_cid2 *)font, glyph);
1741
if (glyph_index < 0)
1747
copy_font_cid2(gs_font *font, gs_font *copied)
1749
gs_font_cid2 *copied2 = (gs_font_cid2 *)copied;
1750
gs_copied_font_data_t *const cfdata = cf_data(copied);
1752
int CIDCount = copied2->cidata.common.CIDCount;
1753
ushort *CIDMap = (ushort *)
1754
gs_alloc_byte_array(copied->memory, CIDCount, sizeof(ushort),
1755
"copy_font_cid2(CIDMap");
1758
return_error(gs_error_VMerror);
1759
code = copy_font_cid_common(font, copied, &copied2->cidata.common);
1761
(code = copy_font_type42(font, copied)) < 0
1763
gs_free_object(copied->memory, CIDMap, "copy_font_cid2(CIDMap");
1766
cfdata->notdef = GS_MIN_CID_GLYPH;
1767
memset(CIDMap, 0xff, CIDCount * sizeof(*CIDMap));
1768
cfdata->CIDMap = CIDMap;
1769
copied2->cidata.MetricsCount = 0;
1770
copied2->cidata.CIDMap_proc = copied_cid2_CIDMap_proc;
1772
gs_font_type42 *const copied42 = (gs_font_type42 *)copied;
1774
copied42->data.get_glyph_index = copied_cid2_get_glyph_index;
1779
static int expand_CIDMap(gs_font_cid2 *copied2, uint CIDCount)
1782
gs_copied_font_data_t *const cfdata = cf_data((gs_font *)copied2);
1784
if (CIDCount <= copied2->cidata.common.CIDCount)
1787
gs_alloc_byte_array(copied2->memory, CIDCount, sizeof(ushort),
1788
"copy_font_cid2(CIDMap");
1790
return_error(gs_error_VMerror);
1791
memcpy(CIDMap, cfdata->CIDMap, copied2->cidata.common.CIDCount * sizeof(*CIDMap));
1792
memset(CIDMap + copied2->cidata.common.CIDCount, 0xFF,
1793
(CIDCount - copied2->cidata.common.CIDCount) * sizeof(*CIDMap));
1794
cfdata->CIDMap = CIDMap;
1795
copied2->cidata.common.CIDCount = CIDCount;
1800
copy_glyph_cid2(gs_font *font, gs_glyph glyph, gs_font *copied, int options)
1802
gs_font_cid2 *fcid2 = (gs_font_cid2 *)font;
1803
gs_copied_font_data_t *const cfdata = cf_data(copied);
1804
gs_font_cid2 *copied2 = (gs_font_cid2 *)copied;
1808
if (!(options & COPY_GLYPH_BY_INDEX)) {
1809
uint cid = glyph - GS_MIN_CID_GLYPH;
1812
code = expand_CIDMap(copied2, cid + 1);
1815
CIDCount = copied2->cidata.common.CIDCount;
1816
gid = fcid2->cidata.CIDMap_proc(fcid2, glyph);
1817
if (gid < 0 || gid >= cfdata->glyphs_size)
1818
return_error(gs_error_rangecheck);
1820
return_error(gs_error_invalidaccess);
1821
if (cfdata->CIDMap[cid] != 0xffff && cfdata->CIDMap[cid] != gid)
1822
return_error(gs_error_invalidaccess);
1823
code = copy_glyph_type42(font, glyph, copied, options);
1826
cfdata->CIDMap[cid] = gid;
1828
gid = glyph - GS_MIN_GLYPH_INDEX;
1829
if (gid < 0 || gid >= cfdata->glyphs_size)
1830
return_error(gs_error_rangecheck);
1831
code = copy_glyph_type42(font, glyph, copied, options);
1838
static const gs_copied_font_procs_t copied_procs_cid2 = {
1839
copy_font_cid2, copy_glyph_cid2, copied_no_add_encoding,
1840
named_glyph_slot_none,
1841
gs_no_encode_char, gs_type42_glyph_info, gs_type42_glyph_outline
1845
same_cid2_hinting(const gs_font_cid2 *cfont, const gs_font_cid2 *ofont)
1847
return same_type42_hinting((gs_font_type42 *)cfont, (gs_font_type42 *)ofont);
1850
/* ---------------- Public ---------------- */
1853
* Procedure vector for copied fonts.
1855
static font_proc_font_info(copied_font_info);
1856
static font_proc_enumerate_glyph(copied_enumerate_glyph);
1857
static const gs_font_procs copied_font_procs = {
1858
0, /* define_font, not supported */
1859
0, /* make_font, not supported */
1861
gs_default_same_font,
1862
0, /* encode_char, varies by FontType */
1863
0, /* decode_char, not supported */
1864
copied_enumerate_glyph,
1865
0, /* glyph_info, varies by FontType */
1866
0, /* glyph_outline, varies by FontType */
1868
gs_default_init_fstack,
1869
gs_default_next_char_glyph,
1873
#if GLYPHS_SIZE_IS_PRIME
1874
static const int some_primes[] = {
1875
/* Arbitrary choosen prime numbers, being reasonable for a Type 1|2 font size.
1876
We start with 257 to fit 256 glyphs and .notdef .
1877
Smaller numbers aren't useful, because we don't know whether a font
1878
will add more glyphs incrementally when we allocate its stable copy.
1880
257, 359, 521, 769, 1031, 2053,
1881
3079, 4099, 5101, 6101, 7109, 8209, 10007, 12007, 14009,
1882
16411, 20107, 26501, 32771, 48857, 65537, 85229, 127837};
1886
* Copy a font, aside from its glyphs.
1889
gs_copy_font(gs_font *font, const gs_matrix *orig_matrix, gs_memory_t *mem, gs_font **pfont_new, int max_reserved_glyphs)
1891
gs_memory_type_ptr_t fstype = gs_object_type(font->memory, font);
1892
uint fssize = gs_struct_type_size(fstype);
1893
gs_font *copied = 0;
1894
gs_copied_font_data_t *cfdata = 0;
1895
gs_font_info_t info;
1896
gs_copied_glyph_t *glyphs = 0;
1898
gs_copied_glyph_name_t *names = 0;
1899
bool have_names = false;
1900
const gs_copied_font_procs_t *procs;
1904
* Check for a supported FontType, and compute the size of its
1905
* copied glyph table.
1907
switch (font->FontType) {
1909
procs = &copied_procs_type42;
1910
glyphs_size = ((gs_font_type42 *)font)->data.trueNumGlyphs;
1915
procs = &copied_procs_type1;
1916
/* Count the glyphs. */
1922
while (font->procs.enumerate_glyph(font, &index, GLYPH_SPACE_NAME,
1923
&glyph), index != 0)
1926
if(glyphs_size > max_reserved_glyphs && max_reserved_glyphs != -1)
1927
glyphs_size = max_reserved_glyphs;
1929
#if GLYPHS_SIZE_IS_PRIME
1930
if (glyphs_size < 257)
1933
* Make glyphs_size a prime number to ensure termination of the loop in
1934
* named_glyphs_slot_hashed, q.v.
1935
* Also reserve additional slots for the case of font merging and
1936
* for possible font increments.
1938
glyphs_size = glyphs_size * 3 / 2;
1941
for (i = 0; i < count_of(some_primes); i++)
1942
if (glyphs_size <= some_primes[i])
1944
if (i >= count_of(some_primes))
1945
return_error(gs_error_rangecheck);
1946
glyphs_size = some_primes[i];
1950
* Make names_size a power of 2 to ensure termination of the loop in
1951
* named_glyphs_slot_hashed, q.v.
1953
glyphs_size = glyphs_size * 3 / 2;
1954
while (glyphs_size & (glyphs_size - 1))
1955
glyphs_size = (glyphs_size | (glyphs_size - 1)) + 1;
1956
if (glyphs_size < 256) /* probably incremental font */
1961
case ft_CID_encrypted:
1962
procs = &copied_procs_cid0;
1963
glyphs_size = ((gs_font_cid0 *)font)->cidata.common.CIDCount;
1965
case ft_CID_TrueType:
1966
procs = &copied_procs_cid2;
1967
/* Glyphs are indexed by GID, not by CID. */
1968
glyphs_size = ((gs_font_cid2 *)font)->data.trueNumGlyphs;
1971
return_error(gs_error_rangecheck);
1974
/* Get the font_info for copying. */
1976
memset(&info, 0, sizeof(info));
1977
info.Flags_requested = ~0;
1978
code = font->procs.font_info(font, NULL, ~0, &info);
1982
/* Allocate the generic copied information. */
1984
glyphs = gs_alloc_struct_array(mem, glyphs_size, gs_copied_glyph_t,
1985
&st_gs_copied_glyph_element,
1986
"gs_copy_font(glyphs)");
1987
if (have_names != 0)
1988
names = gs_alloc_struct_array(mem, glyphs_size, gs_copied_glyph_name_t,
1989
&st_gs_copied_glyph_name_element,
1990
"gs_copy_font(names)");
1991
copied = gs_alloc_struct(mem, gs_font, fstype,
1992
"gs_copy_font(copied font)");
1993
cfdata = gs_alloc_struct(mem, gs_copied_font_data_t,
1994
&st_gs_copied_font_data,
1995
"gs_copy_font(wrapper data)");
1997
memset(cfdata, 0, sizeof(*cfdata));
1998
if (glyphs == 0 || (names == 0 && have_names) || copied == 0 ||
2001
code = gs_note_error(gs_error_VMerror);
2004
cfdata->info = info;
2005
cfdata->dir = font->dir;
2006
if ((code = (copy_string(mem, &cfdata->info.Copyright,
2007
"gs_copy_font(Copyright)") |
2008
copy_string(mem, &cfdata->info.Notice,
2009
"gs_copy_font(Notice)") |
2010
copy_string(mem, &cfdata->info.FamilyName,
2011
"gs_copy_font(FamilyName)") |
2012
copy_string(mem, &cfdata->info.FullName,
2013
"gs_copy_font(FullName)"))) < 0
2017
/* Initialize the copied font. */
2019
memcpy(copied, font, fssize);
2020
copied->next = copied->prev = 0;
2021
copied->memory = mem;
2022
copied->is_resource = false;
2023
gs_notify_init(&copied->notify_list, mem);
2024
copied->base = copied;
2025
copied->FontMatrix = *orig_matrix;
2026
copied->client_data = cfdata;
2027
copied->procs = copied_font_procs;
2028
copied->procs.encode_char = procs->encode_char;
2029
copied->procs.glyph_info = procs->glyph_info;
2030
copied->procs.glyph_outline = procs->glyph_outline;
2032
gs_font_base *bfont = (gs_font_base *)copied;
2035
bfont->FAPI_font_data = 0;
2036
bfont->encoding_index = ENCODING_INDEX_UNKNOWN;
2037
code = uid_copy(&bfont->UID, mem, "gs_copy_font(UID)");
2042
cfdata->procs = procs;
2043
memset(glyphs, 0, glyphs_size * sizeof(*glyphs));
2044
cfdata->glyphs = glyphs;
2045
cfdata->glyphs_size = glyphs_size;
2046
cfdata->num_glyphs = 0;
2047
cfdata->ordered = false;
2049
memset(names, 0, glyphs_size * sizeof(*names));
2050
cfdata->names = names;
2054
for (i = 0; i < glyphs_size; ++i)
2055
names[i].glyph = GS_NO_GLYPH;
2058
/* Do FontType-specific initialization. */
2060
code = procs->finish_copy_font(font, copied);
2064
*pfont_new = copied;
2065
if (cfdata->notdef != GS_NO_GLYPH)
2066
code = gs_copy_glyph(font, cfdata->notdef, copied);
2070
/* Free storage and exit. */
2072
uncopy_string(mem, &cfdata->info.FullName,
2073
"gs_copy_font(FullName)");
2074
uncopy_string(mem, &cfdata->info.FamilyName,
2075
"gs_copy_font(FamilyName)");
2076
uncopy_string(mem, &cfdata->info.Notice,
2077
"gs_copy_font(Notice)");
2078
uncopy_string(mem, &cfdata->info.Copyright,
2079
"gs_copy_font(Copyright)");
2080
gs_free_object(mem, cfdata, "gs_copy_font(wrapper data)");
2082
gs_free_object(mem, copied, "gs_copy_font(copied font)");
2083
gs_free_object(mem, names, "gs_copy_font(names)");
2084
gs_free_object(mem, glyphs, "gs_copy_font(glyphs)");
2089
* Copy a glyph, including any sub-glyphs.
2092
gs_copy_glyph(gs_font *font, gs_glyph glyph, gs_font *copied)
2094
return gs_copy_glyph_options(font, glyph, copied, 0);
2097
gs_copy_glyph_options(gs_font *font, gs_glyph glyph, gs_font *copied,
2101
#define MAX_GLYPH_PIECES 64 /* arbitrary, but 32 is too small - bug 687698. */
2102
gs_glyph glyphs[MAX_GLYPH_PIECES];
2105
if (copied->procs.font_info != copied_font_info)
2106
return_error(gs_error_rangecheck);
2107
code = cf_data(copied)->procs->copy_glyph(font, glyph, copied, options);
2110
/* Copy any sub-glyphs. */
2112
code = psf_add_subset_pieces(glyphs, &count, MAX_GLYPH_PIECES, MAX_GLYPH_PIECES,
2116
if (count > MAX_GLYPH_PIECES)
2117
return_error(gs_error_limitcheck);
2118
for (i = 1; i < count; ++i) {
2119
code = gs_copy_glyph_options(font, glyphs[i], copied,
2120
(options & ~COPY_GLYPH_NO_OLD) | COPY_GLYPH_BY_INDEX);
2125
* Because 'seac' accesses the Encoding of the font as well as the
2126
* glyphs, we have to copy the Encoding entries as well.
2130
switch (font->FontType) {
2137
#if 0 /* No need to add subglyphs to the Encoding because they always are
2138
taken from StandardEncoding (See the Type 1 spec about 'seac').
2139
Attempt to add them to the encoding can cause a conflict,
2140
if the encoding specifies different glyphs for these char codes
2141
(See the bug #687172). */
2143
gs_copied_glyph_t *pcg;
2144
gs_glyph_data_t gdata;
2147
gdata.memory = font->memory;
2148
/* Since we just copied the glyph, copied_glyph_slot can't fail. */
2149
DISCARD(copied_glyph_slot(cf_data(copied), glyph, &pcg));
2150
gs_glyph_data_from_string(&gdata, pcg->gdata.data, pcg->gdata.size,
2152
code = gs_type1_piece_codes((gs_font_type1 *)font, &gdata, chars);
2153
if (code <= 0 || /* 0 is not possible here */
2154
(code = gs_copied_font_add_encoding(copied, chars[0], glyphs[1])) < 0 ||
2155
(code = gs_copied_font_add_encoding(copied, chars[1], glyphs[2])) < 0
2161
#undef MAX_GLYPH_PIECES
2165
* Add an Encoding entry to a copied font. The glyph need not already have
2169
gs_copied_font_add_encoding(gs_font *copied, gs_char chr, gs_glyph glyph)
2171
gs_copied_font_data_t *const cfdata = cf_data(copied);
2173
if (copied->procs.font_info != copied_font_info)
2174
return_error(gs_error_rangecheck);
2175
return cfdata->procs->add_encoding(copied, chr, glyph);
2179
* Copy all the glyphs and, if relevant, Encoding entries from a font. This
2180
* is equivalent to copying the glyphs and Encoding entries individually,
2181
* and returns errors under the same conditions.
2184
gs_copy_font_complete(gs_font *font, gs_font *copied)
2186
int index, code = 0;
2187
gs_glyph_space_t space = GLYPH_SPACE_NAME;
2191
* For Type 1 fonts and CIDFonts, enumerating the glyphs using
2192
* GLYPH_SPACE_NAME will cover all the glyphs. (The "names" of glyphs
2193
* in CIDFonts are CIDs, but that is not a problem.) For Type 42 fonts,
2194
* however, we have to copy by name once, so that we also copy the
2195
* name-to-GID mapping (the CharStrings dictionary in PostScript), and
2196
* then copy again by GID, to cover glyphs that don't have names.
2201
(font->procs.enumerate_glyph(font, &index, space, &glyph),
2204
if (font->FontType == ft_TrueType &&
2205
glyph >= GS_MIN_CID_GLYPH && glyph < GS_MIN_GLYPH_INDEX)
2206
return_error(gs_error_invalidfont); /* bug 688370. */
2207
code = gs_copy_glyph(font, glyph, copied);
2209
/* For Type 42 fonts, if we copied by name, now copy again by index. */
2210
if (space == GLYPH_SPACE_NAME && font->FontType == ft_TrueType)
2211
space = GLYPH_SPACE_INDEX;
2215
if (cf_data(copied)->Encoding != 0)
2216
for (index = 0; code >= 0 && index < 256; ++index) {
2217
glyph = font->procs.encode_char(font, (gs_char)index,
2219
if (glyph != GS_NO_GLYPH) {
2220
code = gs_copied_font_add_encoding(copied, (gs_char)index,
2222
if (code == gs_error_undefined) {
2223
/* Skip Encoding entries, which point to undefiuned glyphs -
2224
happens with 033-52-5873.pdf. */
2227
if (code == gs_error_rangecheck) {
2228
/* Skip Encoding entries, which point to undefiuned glyphs -
2229
happens with 159.pdf. */
2234
if (copied->FontType != ft_composite) {
2235
gs_font_base *bfont = (gs_font_base *)font;
2236
gs_font_base *bcopied = (gs_font_base *)copied;
2238
bcopied->encoding_index = bfont->encoding_index;
2239
bcopied->nearest_encoding_index = bfont->nearest_encoding_index;
2245
* Check whether specified glyphs can be copied from another font.
2246
* It means that (1) fonts have same hinting parameters and
2247
* (2) font subsets for the specified glyph set don't include different
2248
* outlines or metrics. Possible returned values :
2249
* 0 (incompatible), 1 (compatible), < 0 (error)
2252
gs_copied_can_copy_glyphs(const gs_font *cfont, const gs_font *ofont,
2253
gs_glyph *glyphs, int num_glyphs, int glyphs_step,
2260
if (cfont->FontType != ofont->FontType)
2262
if (cfont->WMode != ofont->WMode)
2264
if (cfont->font_name.size == 0 || ofont->font_name.size == 0) {
2265
if (cfont->key_name.size != ofont->key_name.size ||
2266
memcmp(cfont->key_name.chars, ofont->key_name.chars,
2267
cfont->font_name.size))
2268
return 0; /* Don't allow to merge random fonts. */
2270
if (cfont->font_name.size != ofont->font_name.size ||
2271
memcmp(cfont->font_name.chars, ofont->font_name.chars,
2272
cfont->font_name.size))
2273
return 0; /* Don't allow to merge random fonts. */
2275
if (check_hinting) {
2276
switch(cfont->FontType) {
2279
if (!same_type1_hinting((const gs_font_type1 *)cfont,
2280
(const gs_font_type1 *)ofont))
2285
code = same_type42_hinting((gs_font_type42 *)cfont,
2286
(gs_font_type42 *)ofont);
2288
case ft_CID_encrypted:
2289
if (!gs_is_CIDSystemInfo_compatible(
2290
gs_font_cid_system_info(cfont),
2291
gs_font_cid_system_info(ofont)))
2293
code = same_cid0_hinting((const gs_font_cid0 *)cfont,
2294
(const gs_font_cid0 *)ofont);
2296
case ft_CID_TrueType:
2297
if (!gs_is_CIDSystemInfo_compatible(
2298
gs_font_cid_system_info(cfont),
2299
gs_font_cid_system_info(ofont)))
2301
code = same_cid2_hinting((const gs_font_cid2 *)cfont,
2302
(const gs_font_cid2 *)ofont);
2305
return_error(gs_error_unregistered); /* Must not happen. */
2307
if (code <= 0) /* an error or false */
2310
return compare_glyphs(cfont, ofont, glyphs, num_glyphs, glyphs_step, 0);
2313
/* Extension glyphs may be added to a font to resolve
2314
glyph name conflicts while conwerting a PDF Widths into Metrics.
2315
This function drops them before writing out an embedded font. */
2317
copied_drop_extension_glyphs(gs_font *copied)
2319
/* Note : This function drops 'used' flags for some glyphs
2320
and truncates glyph names. Can't use the font
2321
for outlining|rasterization|width after applying it.
2323
gs_copied_font_data_t *const cfdata = cf_data(copied);
2324
uint gsize = cfdata->glyphs_size, i;
2325
const int sl = strlen(gx_extendeg_glyph_name_separator);
2327
for (i = 0; i < gsize; i++) {
2328
gs_copied_glyph_t *pslot = &cfdata->glyphs[i];
2329
gs_copied_glyph_name_t *name;
2334
name = &cfdata->names[i];
2335
l = name->str.size - sl;
2337
for (j = 0; j < l; j ++)
2338
if (!memcmp(gx_extendeg_glyph_name_separator, name->str.data + j, sl))
2342
/* Found an extension name.
2343
Find the corresponding non-extended one. */
2345
for (k = 0; k < gsize; k++)
2346
if (cfdata->glyphs[k].used &&
2347
cfdata->names[k].str.size == j &&
2348
!memcmp(cfdata->names[k].str.data, name->str.data, j) &&
2349
!bytes_compare(pslot->gdata.data, pslot->gdata.size,
2350
cfdata->glyphs[k].gdata.data, cfdata->glyphs[k].gdata.size)) {
2354
/* Truncate the extended glyph name. */
2355
cfdata->names[i0].str.size = j;
2356
/* Drop others with same prefix. */
2357
for (k = 0; k < gsize; k++)
2358
if (k != i0 && cfdata->glyphs[k].used &&
2359
cfdata->names[k].str.size >= j + sl &&
2360
!memcmp(cfdata->names[k].str.data, name->str.data, j) &&
2361
!memcmp(gx_extendeg_glyph_name_separator, name + j, sl) &&
2362
!bytes_compare(pslot->gdata.data, pslot->gdata.size,
2363
cfdata->glyphs[k].gdata.data, cfdata->glyphs[k].gdata.size))
2364
cfdata->glyphs[k].used = false;
2370
compare_glyph_names(const void *pg1, const void *pg2)
2372
const gs_copied_glyph_name_t * gn1 = *(const gs_copied_glyph_name_t **)pg1;
2373
const gs_copied_glyph_name_t * gn2 = *(const gs_copied_glyph_name_t **)pg2;
2375
return bytes_compare(gn1->str.data, gn1->str.size, gn2->str.data, gn2->str.size);
2379
/* Order font data to avoid a serialization indeterminism. */
2381
order_font_data(gs_copied_font_data_t *cfdata, gs_memory_t *memory)
2385
gs_copied_glyph_name_t **a = (gs_copied_glyph_name_t **)gs_alloc_byte_array(memory, cfdata->num_glyphs,
2386
sizeof(gs_copied_glyph_name_t *), "order_font_data");
2388
return_error(gs_error_VMerror);
2390
for (i = 0; i < cfdata->glyphs_size; i++) {
2391
if (cfdata->glyphs[i].used) {
2392
if (j >= cfdata->num_glyphs)
2393
return_error(gs_error_unregistered); /* Must not happen */
2394
a[j++] = &cfdata->names[i];
2397
qsort(a, cfdata->num_glyphs, sizeof(*a), compare_glyph_names);
2398
for (j--; j >= 0; j--)
2399
cfdata->glyphs[j].order_index = a[j] - cfdata->names;
2400
gs_free_object(memory, a, "order_font_data");
2404
/* Order font to avoid a serialization indeterminism. */
2406
copied_order_font(gs_font *font)
2409
if (font->procs.enumerate_glyph != copied_enumerate_glyph)
2410
return_error(gs_error_unregistered); /* Must not happen */
2411
if (font->FontType != ft_encrypted && font->FontType != ft_encrypted2) {
2412
/* Don't need to order, because it is ordered by CIDs or glyph indices. */
2415
{ gs_copied_font_data_t * cfdata = cf_data(font);
2416
cfdata->ordered = true;
2417
return order_font_data(cfdata, font->memory);
2421
/* Get .nmotdef glyph. */
2423
copied_get_notdef(const gs_font *font)
2425
gs_copied_font_data_t * cfdata = cf_data(font);
2427
return cfdata->notdef;