1 /* Copyright (C) 2002 Aladdin Enterprises. All rights reserved.
2
3 This software is provided AS-IS with no warranty, either express or
4 implied.
5
6 This software is distributed under license and may not be copied,
7 modified or distributed except as expressly authorized under the terms
8 of the license contained in the file LICENSE in this distribution.
9
10 For more information about licensing, please refer to
11 http://www.ghostscript.com/licensing/. For information on
12 commercial licensing, go to http://www.artifex.com/licensing/ or
13 contact Artifex Software, Inc., 101 Lucas Valley Road #110,
14 San Rafael, CA 94903, U.S.A., +1(415)492-9861.
15 */
16
17 /* $Id: gxfcopy.c,v 1.55 2004/12/15 23:21:32 igor Exp $ */
18 /* Font copying for high-level output */
19 #include "memory_.h"
20 #include "gx.h"
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 "stream.h"
29 #include "gxfont.h"
30 #include "gxfont1.h"
31 #include "gxfont42.h"
32 #include "gxfcid.h"
33 #include "gxfcopy.h"
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 */
39 #include "gdevpsf.h"
40
41 #define GLYPHS_SIZE_IS_PRIME 1 /* Old code = 0, new code = 1. */
42
43 /* ================ Types and structures ================ */
44
45 typedef struct gs_copied_glyph_s gs_copied_glyph_t;
46 typedef struct gs_copied_font_data_s gs_copied_font_data_t;
47
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,
51 int options);
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);
55 /* Font procedures */
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;
60
61 /*
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.
64 */
65 typedef struct gs_subr_info_s {
66 byte *data; /* Subr data */
67 int count;
68 uint *starts; /* [count+1] Subr[i] = data[starts[i]..starts[i+1]] */
69 } gs_subr_info_t;
70
71 /*
72 * The glyphs for copied fonts are stored explicitly in a table indexed by
73 * glyph number.
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.
79 */
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 };
89 /*
90 * We use a special GC descriptor to avoid large GC overhead.
91 */
92 gs_private_st_composite(st_gs_copied_glyph_element, gs_copied_glyph_t,
93 "gs_copied_glyph_t[]", copied_glyph_element_enum_ptrs,
94 copied_glyph_element_reloc_ptrs);
95 private ENUM_PTRS_WITH(copied_glyph_element_enum_ptrs, gs_copied_glyph_t *pcg)
96 if (index < size / (uint)sizeof(gs_copied_glyph_t))
97 return ENUM_CONST_STRING(&pcg[index].gdata);
98 return 0;
99 ENUM_PTRS_END
RELOC_PTRS_WITH(copied_glyph_element_reloc_ptrs,gs_copied_glyph_t * pcg)100 private RELOC_PTRS_WITH(copied_glyph_element_reloc_ptrs, gs_copied_glyph_t *pcg)
101 {
102 uint count = size / (uint)sizeof(gs_copied_glyph_t);
103 gs_copied_glyph_t *p = pcg;
104
105 for (; count > 0; --count, ++p)
106 if (p->gdata.size > 0)
107 RELOC_CONST_STRING_VAR(p->gdata);
108 }
109 RELOC_PTRS_END
110
111 /*
112 * Type 1 and TrueType fonts also have a 'names' table, parallel to the
113 * 'glyphs' table.
114 * For Type 1 fonts, this is a hash table; glyph numbers are assigned
115 * arbitrarily, according to the hashed placement of the names.
116 * For TrueType fonts, this is indexed by GID.
117 * The strings in this table are either those returned by the font's
118 * glyph_name procedure, which we assume are garbage-collected, or those
119 * associated with the known encodings, which we assume are immutable.
120 */
121 typedef struct gs_copied_glyph_name_s {
122 gs_glyph glyph; /* key (for comparison and glyph_name only) */
123 gs_const_string str; /* glyph name */
124 } gs_copied_glyph_name_t;
125 /*
126 * We use the same special GC descriptor as above for 'names'.
127 */
128 gs_private_st_composite(st_gs_copied_glyph_name_element,
129 gs_copied_glyph_name_t,
130 "gs_copied_glyph_name_t[]",
131 copied_glyph_name_enum_ptrs,
132 copied_glyph_name_reloc_ptrs);
133 private ENUM_PTRS_WITH(copied_glyph_name_enum_ptrs, gs_copied_glyph_name_t *pcgn)
134 if (index < size / (uint)sizeof(gs_copied_glyph_name_t)) {
135 const gs_copied_glyph_name_t *const p = &pcgn[index];
136
137 return (p->str.size == 0 ||
138 gs_is_c_glyph_name(p->str.data, p->str.size) ?
139 ENUM_CONST_STRING2(0, 0) :
140 ENUM_CONST_STRING(&p->str));
141 }
142 return 0;
143 /* We should mark glyph name here, but we have no access to
144 the gs_font_dir instance. Will mark in gs_copied_font_data_enum_ptrs.
145 */
146 ENUM_PTRS_END
RELOC_PTRS_WITH(copied_glyph_name_reloc_ptrs,gs_copied_glyph_name_t * pcgn)147 private RELOC_PTRS_WITH(copied_glyph_name_reloc_ptrs, gs_copied_glyph_name_t *pcgn)
148 {
149 uint count = size / (uint)sizeof(gs_copied_glyph_name_t);
150 gs_copied_glyph_name_t *p = pcgn;
151
152 for (; count > 0; --count, ++p)
153 if (p->str.size > 0 && !gs_is_c_glyph_name(p->str.data, p->str.size))
154 RELOC_CONST_STRING_VAR(p->str);
155 }
156 RELOC_PTRS_END
157
158 /*
159 * To accommodate glyphs with multiple names, there is an additional
160 * 'extra_names' table. Since this is rare, this table uses linear search.
161 */
162 typedef struct gs_copied_glyph_extra_name_s gs_copied_glyph_extra_name_t;
163 struct gs_copied_glyph_extra_name_s {
164 gs_copied_glyph_name_t name;
165 uint gid; /* index in glyphs table */
166 gs_copied_glyph_extra_name_t *next;
167 };
BASIC_PTRS(gs_copied_glyph_extra_name_ptrs)168 BASIC_PTRS(gs_copied_glyph_extra_name_ptrs) {
169 GC_STRING_ELT(gs_copied_glyph_extra_name_t, name.str),
170 GC_OBJ_ELT(gs_copied_glyph_extra_name_t, next)
171 };
172 gs_private_st_basic(st_gs_copied_glyph_extra_name,
173 gs_copied_glyph_extra_name_t,
174 "gs_copied_glyph_extra_name_t",
175 gs_copied_glyph_extra_name_ptrs,
176 gs_copied_glyph_extra_name_data);
177
178 /*
179 * The client_data of copied fonts points to an instance of
180 * gs_copied_font_data_t.
181 */
182 struct gs_copied_font_data_s {
183 gs_font_info_t info; /* from the original font, must be first */
184 const gs_copied_font_procs_t *procs;
185 gs_copied_glyph_t *glyphs; /* [glyphs_size] */
186 uint glyphs_size; /* (a power of 2 or a prime number for Type 1/2) */
187 uint num_glyphs; /* The number of glyphs copied. */
188 gs_glyph notdef; /* CID 0 or .notdef glyph */
189 /*
190 * We don't use a union for the rest of the data, because some of the
191 * cases overlap and it's just not worth the trouble.
192 */
193 gs_copied_glyph_name_t *names; /* (Type 1/2, TrueType) [glyphs_size] */
194 gs_copied_glyph_extra_name_t *extra_names; /* (TrueType) */
195 byte *data; /* (TrueType and CID fonts) copied data */
196 uint data_size; /* (TrueType and CID fonts) */
197 gs_glyph *Encoding; /* (Type 1/2 and Type 42) [256] */
198 ushort *CIDMap; /* (CIDFontType 2) [CIDCount] */
199 gs_subr_info_t subrs; /* (Type 1/2 and CIDFontType 0) */
200 gs_subr_info_t global_subrs; /* (Type 2 and CIDFontType 0) */
201 gs_font_cid0 *parent; /* (Type 1 subfont) => parent CIDFontType 0 */
202 gs_font_dir *dir;
203 };
204 extern_st(st_gs_font_info);
205 private
206 ENUM_PTRS_WITH(gs_copied_font_data_enum_ptrs, gs_copied_font_data_t *cfdata)
207 if (index == 12) {
208 gs_copied_glyph_name_t *names = cfdata->names;
209 gs_copied_glyph_extra_name_t *en = cfdata->extra_names;
210 int i;
211
212 if (names != NULL)
213 for (i = 0; i < cfdata->glyphs_size; ++i)
214 if (names[i].glyph < gs_c_min_std_encoding_glyph)
215 cfdata->dir->ccache.mark_glyph(mem, names[i].glyph, NULL);
216 for (; en != NULL; en = en->next)
217 if (en->name.glyph < gs_c_min_std_encoding_glyph)
218 cfdata->dir->ccache.mark_glyph(mem, en->name.glyph, NULL);
219 }
220 return ENUM_USING(st_gs_font_info, &cfdata->info, sizeof(gs_font_info_t), index - 12);
221 ENUM_PTR3(0, gs_copied_font_data_t, glyphs, names, extra_names);
222 ENUM_PTR3(3, gs_copied_font_data_t, data, Encoding, CIDMap);
223 ENUM_PTR3(6, gs_copied_font_data_t, subrs.data, subrs.starts, global_subrs.data);
224 ENUM_PTR3(9, gs_copied_font_data_t, global_subrs.starts, parent, dir);
225 ENUM_PTRS_END
226
RELOC_PTRS_WITH(gs_copied_font_data_reloc_ptrs,gs_copied_font_data_t * cfdata)227 private RELOC_PTRS_WITH(gs_copied_font_data_reloc_ptrs, gs_copied_font_data_t *cfdata)
228 {
229 RELOC_PTR3(gs_copied_font_data_t, glyphs, names, extra_names);
230 RELOC_PTR3(gs_copied_font_data_t, data, Encoding, CIDMap);
231 RELOC_PTR3(gs_copied_font_data_t, subrs.data, subrs.starts, global_subrs.data);
232 RELOC_PTR3(gs_copied_font_data_t, global_subrs.starts, parent, dir);
233 RELOC_USING(st_gs_font_info, &cfdata->info, sizeof(gs_font_info_t));
234 }
235 RELOC_PTRS_END
236
237 gs_private_st_composite(st_gs_copied_font_data, gs_copied_font_data_t, "gs_copied_font_data_t",\
238 gs_copied_font_data_enum_ptrs, gs_copied_font_data_reloc_ptrs);
239
240 inline private gs_copied_font_data_t *
cf_data(const gs_font * font)241 cf_data(const gs_font *font)
242 {
243 return (gs_copied_font_data_t *)font->client_data;
244 }
245
246 /* ================ Procedures ================ */
247
248 /* ---------------- Private utilities ---------------- */
249
250 /* Copy a string. Return 0 or gs_error_VMerror. */
251 private int
copy_string(gs_memory_t * mem,gs_const_string * pstr,client_name_t cname)252 copy_string(gs_memory_t *mem, gs_const_string *pstr, client_name_t cname)
253 {
254 const byte *data = pstr->data;
255 uint size = pstr->size;
256 byte *str;
257
258 if (data == 0)
259 return 0; /* empty string */
260 str = gs_alloc_string(mem, size, cname);
261 pstr->data = str;
262 if (str == 0)
263 return_error(gs_error_VMerror);
264 memcpy(str, data, size);
265 return 0;
266 }
267
268 /* Free a copied string. */
269 private void
uncopy_string(gs_memory_t * mem,gs_const_string * pstr,client_name_t cname)270 uncopy_string(gs_memory_t *mem, gs_const_string *pstr, client_name_t cname)
271 {
272 if (pstr->data)
273 gs_free_const_string(mem, pstr->data, pstr->size, cname);
274 }
275
276 /*
277 * Allocate an Encoding for a Type 1 or Type 42 font.
278 */
279 private int
copied_Encoding_alloc(gs_font * copied)280 copied_Encoding_alloc(gs_font *copied)
281 {
282 gs_copied_font_data_t *const cfdata = cf_data(copied);
283 gs_glyph *Encoding = (gs_glyph *)
284 gs_alloc_byte_array(copied->memory, 256, sizeof(*cfdata->Encoding),
285 "copy_font_type1(Encoding)");
286 int i;
287
288 if (Encoding == 0)
289 return_error(gs_error_VMerror);
290 for (i = 0; i < 256; ++i)
291 Encoding[i] = GS_NO_GLYPH;
292 cfdata->Encoding = Encoding;
293 return 0;
294 }
295
296 /*
297 * Allocate and set up data copied from a TrueType or CID font.
298 * stell(*s) + extra is the length of the data.
299 */
300 private int
copied_data_alloc(gs_font * copied,stream * s,uint extra,int code)301 copied_data_alloc(gs_font *copied, stream *s, uint extra, int code)
302 {
303 gs_copied_font_data_t *const cfdata = cf_data(copied);
304 uint len = stell(s);
305 byte *fdata;
306
307 if (code < 0)
308 return code;
309 fdata = gs_alloc_bytes(copied->memory, len + extra, "copied_data_alloc");
310 if (fdata == 0)
311 return_error(gs_error_VMerror);
312 swrite_string(s, fdata, len);
313 cfdata->data = fdata;
314 cfdata->data_size = len + extra;
315 return 0;
316 }
317
318 /*
319 * Copy Subrs or GSubrs from a font.
320 */
321 private int
copy_subrs(gs_font_type1 * pfont,bool global,gs_subr_info_t * psi,gs_memory_t * mem)322 copy_subrs(gs_font_type1 *pfont, bool global, gs_subr_info_t *psi,
323 gs_memory_t *mem)
324 {
325 int i, code;
326 uint size;
327 gs_glyph_data_t gdata;
328 byte *data;
329 uint *starts;
330
331 gdata.memory = pfont->memory;
332 /* Scan the font to determine the size of the subrs. */
333 for (i = 0, size = 0;
334 (code = pfont->data.procs.subr_data(pfont, i, global, &gdata)) !=
335 gs_error_rangecheck;
336 ++i) {
337 if (code >= 0) {
338 size += gdata.bits.size;
339 gs_glyph_data_free(&gdata, "copy_subrs");
340 }
341 }
342 if (size == 0)
343 data = 0, starts = 0, i = 0;
344 else {
345 /* Allocate the copy. */
346 data = gs_alloc_bytes(mem, size, "copy_subrs(data)");
347 starts = (uint *)gs_alloc_byte_array(mem, i + 1, sizeof(*starts),
348 "copy_subrs(starts)");
349 if (data == 0 || starts == 0) {
350 gs_free_object(mem, starts, "copy_subrs(starts)");
351 gs_free_object(mem, data, "copy_subrs(data)");
352 return_error(gs_error_VMerror);
353 }
354
355 /* Copy the data. */
356 for (i = 0, size = 0;
357 (code = pfont->data.procs.subr_data(pfont, i, global, &gdata)) !=
358 gs_error_rangecheck;
359 ++i) {
360 starts[i] = size;
361 if (code >= 0) {
362 memcpy(data + size, gdata.bits.data, gdata.bits.size);
363 size += gdata.bits.size;
364 gs_glyph_data_free(&gdata, "copy_subrs");
365 }
366 }
367 starts[i] = size;
368 }
369
370 psi->data = data;
371 psi->starts = starts;
372 psi->count = i;
373 return 0;
374 }
375
376 /*
377 * Return a pointer to the definition of a copied glyph, accessed either by
378 * name or by glyph number. If the glyph is out of range, return
379 * gs_error_rangecheck; if the glyph is in range but undefined, store a
380 * pointer to the slot where it would be added, which will have gdata.data
381 * == 0, and return gs_error_undefined; if the glyph is defined, store the
382 * pointer and return 0.
383 */
384 private int
copied_glyph_slot(gs_copied_font_data_t * cfdata,gs_glyph glyph,gs_copied_glyph_t ** pslot)385 copied_glyph_slot(gs_copied_font_data_t *cfdata, gs_glyph glyph,
386 gs_copied_glyph_t **pslot)
387 {
388 uint gsize = cfdata->glyphs_size;
389
390 *pslot = 0;
391 if (glyph >= GS_MIN_GLYPH_INDEX) {
392 /* CIDFontType 2 uses glyph indices for slots. */
393 if (glyph - GS_MIN_GLYPH_INDEX >= gsize)
394 return_error(gs_error_rangecheck);
395 *pslot = &cfdata->glyphs[glyph - GS_MIN_GLYPH_INDEX];
396 } else if (glyph >= GS_MIN_CID_GLYPH) {
397 /* CIDFontType 0 uses CIDS for slots. */
398 if (glyph - GS_MIN_CID_GLYPH >= gsize)
399 return_error(gs_error_rangecheck);
400 *pslot = &cfdata->glyphs[glyph - GS_MIN_CID_GLYPH];
401 } else if (cfdata->names == 0)
402 return_error(gs_error_rangecheck);
403 else {
404 int code = cfdata->procs->named_glyph_slot(cfdata, glyph, pslot);
405
406 if (code < 0)
407 return code;
408 }
409 if (!(*pslot)->used)
410 return_error(gs_error_undefined);
411 return 0;
412 }
413 private int
named_glyph_slot_none(gs_copied_font_data_t * cfdata,gs_glyph glyph,gs_copied_glyph_t ** pslot)414 named_glyph_slot_none(gs_copied_font_data_t *cfdata, gs_glyph glyph,
415 gs_copied_glyph_t **pslot)
416 {
417 return_error(gs_error_rangecheck);
418 }
419 private int
named_glyph_slot_hashed(gs_copied_font_data_t * cfdata,gs_glyph glyph,gs_copied_glyph_t ** pslot)420 named_glyph_slot_hashed(gs_copied_font_data_t *cfdata, gs_glyph glyph,
421 gs_copied_glyph_t **pslot)
422 {
423 uint gsize = cfdata->glyphs_size;
424 gs_copied_glyph_name_t *names = cfdata->names;
425 uint hash = (uint)glyph % gsize;
426 /*
427 * gsize is either a prime number or a power of 2.
428 * If it is prime, any positive reprobe below gsize guarantees that we
429 * will touch every slot.
430 * If it is a power of 2, any odd reprobe guarantees that we
431 * will touch every slot.
432 */
433 uint hash2 = ((uint)glyph / gsize * 2 + 1) % gsize;
434 uint tries = gsize;
435
436 while (names[hash].str.data != 0 && names[hash].glyph != glyph) {
437 hash = (hash + hash2) % gsize;
438 if (!tries)
439 return gs_error_undefined;
440 tries--;
441 }
442 *pslot = &cfdata->glyphs[hash];
443 return 0;
444 }
445 private int
named_glyph_slot_linear(gs_copied_font_data_t * cfdata,gs_glyph glyph,gs_copied_glyph_t ** pslot)446 named_glyph_slot_linear(gs_copied_font_data_t *cfdata, gs_glyph glyph,
447 gs_copied_glyph_t **pslot)
448 {
449 {
450 gs_copied_glyph_name_t *names = cfdata->names;
451 int i;
452
453 for (i = 0; i < cfdata->glyphs_size; ++i)
454 if (names[i].glyph == glyph) {
455 *pslot = &cfdata->glyphs[i];
456 return 0;
457 }
458 }
459 /* This might be a glyph with multiple names. Search extra_names. */
460 {
461 gs_copied_glyph_extra_name_t *extra_name = cfdata->extra_names;
462
463 for (; extra_name != 0; extra_name = extra_name->next)
464 if (extra_name->name.glyph == glyph) {
465 *pslot = &cfdata->glyphs[extra_name->gid];
466 return 0;
467 }
468 }
469 return_error(gs_error_rangecheck);
470 }
471
472 /*
473 * Add glyph data to the glyph table. This handles copying the vector
474 * data, detecting attempted redefinitions, and freeing temporary glyph
475 * data. The glyph must be an integer, an index in the glyph table.
476 * Return 1 if the glyph was already defined, 0 if newly added (or an
477 * error per options).
478 */
479 private int
copy_glyph_data(gs_font * font,gs_glyph glyph,gs_font * copied,int options,gs_glyph_data_t * pgdata,const byte * prefix,int prefix_bytes)480 copy_glyph_data(gs_font *font, gs_glyph glyph, gs_font *copied, int options,
481 gs_glyph_data_t *pgdata, const byte *prefix, int prefix_bytes)
482 {
483 gs_copied_font_data_t *const cfdata = cf_data(copied);
484 uint size = pgdata->bits.size;
485 gs_copied_glyph_t *pcg = 0;
486 int code = copied_glyph_slot(cfdata, glyph, &pcg);
487
488 switch (code) {
489 case 0: /* already defined */
490 if ((options & COPY_GLYPH_NO_OLD) ||
491 pcg->gdata.size != prefix_bytes + size ||
492 memcmp(pcg->gdata.data, prefix, prefix_bytes) ||
493 memcmp(pcg->gdata.data + prefix_bytes,
494 pgdata->bits.data, size)
495 )
496 code = gs_note_error(gs_error_invalidaccess);
497 else
498 code = 1;
499 break;
500 case gs_error_undefined:
501 if (options & COPY_GLYPH_NO_NEW)
502 code = gs_note_error(gs_error_undefined);
503 else if (pcg == NULL)
504 code = gs_note_error(gs_error_undefined);
505 else {
506 uint str_size = prefix_bytes + size;
507 byte *str = gs_alloc_string(copied->memory, str_size,
508 "copy_glyph_data(data)");
509
510 if (str == 0)
511 code = gs_note_error(gs_error_VMerror);
512 else {
513 if (prefix_bytes)
514 memcpy(str, prefix, prefix_bytes);
515 memcpy(str + prefix_bytes, pgdata->bits.data, size);
516 pcg->gdata.data = str;
517 pcg->gdata.size = str_size;
518 pcg->used = HAS_DATA;
519 code = 0;
520 cfdata->num_glyphs++;
521 }
522 }
523 default:
524 break;
525 }
526 gs_glyph_data_free(pgdata, "copy_glyph_data");
527 return code;
528 }
529
530 /*
531 * Copy a glyph name into the names table.
532 */
533 private int
copy_glyph_name(gs_font * font,gs_glyph glyph,gs_font * copied,gs_glyph copied_glyph)534 copy_glyph_name(gs_font *font, gs_glyph glyph, gs_font *copied,
535 gs_glyph copied_glyph)
536 {
537 gs_glyph known_glyph;
538 gs_copied_font_data_t *const cfdata = cf_data(copied);
539 gs_copied_glyph_t *pcg;
540 int code = copied_glyph_slot(cfdata, copied_glyph, &pcg);
541 gs_copied_glyph_name_t *pcgn;
542 gs_const_string str;
543
544 if (code < 0 ||
545 (code = font->procs.glyph_name(font, glyph, &str)) < 0
546 )
547 return code;
548 /* Try to share a permanently allocated known glyph name. */
549 if ((known_glyph = gs_c_name_glyph(str.data, str.size)) != GS_NO_GLYPH)
550 gs_c_glyph_name(known_glyph, &str);
551 else if ((code = copy_string(copied->memory, &str, "copy_glyph_name")) < 0)
552 return code;
553 pcgn = cfdata->names + (pcg - cfdata->glyphs);
554 if (pcgn->glyph != GS_NO_GLYPH &&
555 (pcgn->str.size != str.size ||
556 memcmp(pcgn->str.data, str.data, str.size))
557 ) {
558 /* This is a glyph with multiple names. Add an extra_name entry. */
559 gs_copied_glyph_extra_name_t *extra_name =
560 gs_alloc_struct(copied->memory, gs_copied_glyph_extra_name_t,
561 &st_gs_copied_glyph_extra_name,
562 "copy_glyph_name(extra_name)");
563
564 if (extra_name == 0)
565 return_error(gs_error_VMerror);
566 extra_name->next = cfdata->extra_names;
567 extra_name->gid = pcg - cfdata->glyphs;
568 cfdata->extra_names = extra_name;
569 pcgn = &extra_name->name;
570 }
571 pcgn->glyph = glyph;
572 pcgn->str = str;
573 return 0;
574 }
575
576 /*
577 * Find the .notdef glyph in a font.
578 */
579 private gs_glyph
find_notdef(gs_font_base * font)580 find_notdef(gs_font_base *font)
581 {
582 int index = 0;
583 gs_glyph glyph;
584
585 while (font->procs.enumerate_glyph((gs_font *)font, &index,
586 GLYPH_SPACE_NAME, &glyph),
587 index != 0)
588 if (gs_font_glyph_is_notdef(font, glyph))
589 return glyph;
590 return GS_NO_GLYPH; /* best we can do */
591 }
592
593 /*
594 * Add an Encoding entry to a character-indexed font (Type 1/2/42).
595 */
596 private int
copied_char_add_encoding(gs_font * copied,gs_char chr,gs_glyph glyph)597 copied_char_add_encoding(gs_font *copied, gs_char chr, gs_glyph glyph)
598 {
599 gs_copied_font_data_t *const cfdata = cf_data(copied);
600 gs_glyph *Encoding = cfdata->Encoding;
601 gs_copied_glyph_t *pslot;
602 int code;
603
604 if (Encoding == 0)
605 return_error(gs_error_invalidaccess);
606 if (chr >= 256 || glyph >= GS_MIN_CID_GLYPH)
607 return_error(gs_error_rangecheck);
608 code = copied_glyph_slot(cfdata, glyph, &pslot);
609 if (code < 0)
610 return code;
611 if (Encoding[chr] != glyph && Encoding[chr] != GS_NO_GLYPH)
612 return_error(gs_error_invalidaccess);
613 Encoding[chr] = glyph;
614 return 0;
615 }
616
617 /* Don't allow adding an Encoding entry. */
618 private int
copied_no_add_encoding(gs_font * copied,gs_char chr,gs_glyph glyph)619 copied_no_add_encoding(gs_font *copied, gs_char chr, gs_glyph glyph)
620 {
621 return_error(gs_error_invalidaccess);
622 }
623
624 /* ---------------- Font procedures ---------------- */
625
626 private int
copied_font_info(gs_font * font,const gs_point * pscale,int members,gs_font_info_t * info)627 copied_font_info(gs_font *font, const gs_point *pscale, int members,
628 gs_font_info_t *info)
629 {
630 if (pscale != 0)
631 return_error(gs_error_rangecheck);
632 *info = cf_data(font)->info;
633 return 0;
634 }
635
636 private gs_glyph
copied_encode_char(gs_font * copied,gs_char chr,gs_glyph_space_t glyph_space)637 copied_encode_char(gs_font *copied, gs_char chr, gs_glyph_space_t glyph_space)
638 {
639 gs_copied_font_data_t *const cfdata = cf_data(copied);
640 const gs_glyph *Encoding = cfdata->Encoding;
641
642 if (chr >= 256 || Encoding == 0)
643 return GS_NO_GLYPH;
644 return Encoding[chr];
645 }
646
647 private int
copied_enumerate_glyph(gs_font * font,int * pindex,gs_glyph_space_t glyph_space,gs_glyph * pglyph)648 copied_enumerate_glyph(gs_font *font, int *pindex,
649 gs_glyph_space_t glyph_space, gs_glyph *pglyph)
650 {
651 gs_copied_font_data_t *const cfdata = cf_data(font);
652
653 for (; *pindex < cfdata->glyphs_size; ++*pindex)
654 if (cfdata->glyphs[*pindex].used) {
655 *pglyph =
656 (glyph_space == GLYPH_SPACE_NAME && cfdata->names != 0 ?
657 cfdata->names[*pindex].glyph :
658 /* CIDFontType 0 uses CIDS as slot indices; CIDFontType 2 uses GIDs. */
659 *pindex + (glyph_space == GLYPH_SPACE_NAME
660 ? GS_MIN_CID_GLYPH : GS_MIN_GLYPH_INDEX));
661 ++(*pindex);
662 return 0;
663 }
664 *pindex = 0;
665 return 0;
666 }
667
668 private int
copied_glyph_name(gs_font * font,gs_glyph glyph,gs_const_string * pstr)669 copied_glyph_name(gs_font *font, gs_glyph glyph, gs_const_string *pstr)
670 {
671 gs_copied_font_data_t *const cfdata = cf_data(font);
672 gs_copied_glyph_t *pcg;
673
674 if (glyph >= GS_MIN_CID_GLYPH)
675 return_error(gs_error_rangecheck);
676 if (copied_glyph_slot(cfdata, glyph, &pcg) < 0)
677 return_error(gs_error_undefined);
678 *pstr = cfdata->names[pcg - cfdata->glyphs].str;
679 return 0;
680 }
681
682 private int
copied_build_char(gs_text_enum_t * pte,gs_state * pgs,gs_font * font,gs_char chr,gs_glyph glyph)683 copied_build_char(gs_text_enum_t *pte, gs_state *pgs, gs_font *font,
684 gs_char chr, gs_glyph glyph)
685 {
686 int wmode = font->WMode;
687 int code;
688 gs_glyph_info_t info;
689 double wxy[6];
690 double sbw_stub[4]; /* Currently glyph_outline retrieves sbw only with type 1,2,9 fonts. */
691
692 if (glyph == GS_NO_GLYPH) {
693 glyph = font->procs.encode_char(font, chr, GLYPH_SPACE_INDEX);
694 if (glyph == GS_NO_GLYPH) {
695 glyph = cf_data(font)->notdef;
696 }
697 }
698 /*
699 * Type 1/2 outlines don't require a current point, but TrueType
700 * outlines do. We might want to fix this someday....
701 */
702 if ((code = gs_moveto(pgs, 0.0, 0.0)) < 0 ||
703 (code = font->procs.glyph_info(font, glyph, NULL,
704 (GLYPH_INFO_WIDTH << wmode) |
705 GLYPH_INFO_BBOX |
706 GLYPH_INFO_OUTLINE_WIDTHS,
707 &info)) < 0
708 )
709 return code;
710 wxy[0] = info.width[wmode].x;
711 wxy[1] = info.width[wmode].y;
712 wxy[2] = info.bbox.p.x;
713 wxy[3] = info.bbox.p.y;
714 wxy[4] = info.bbox.q.x;
715 wxy[5] = info.bbox.q.y;
716 if ((code = gs_text_setcachedevice(pte, wxy)) < 0 ||
717 (code = font->procs.glyph_outline(font, wmode, glyph, &ctm_only(pgs),
718 pgs->path, sbw_stub)) < 0
719 )
720 return code;
721 if (font->PaintType != 0) {
722 gs_setlinewidth(pgs, font->StrokeWidth);
723 return gs_stroke(pgs);
724 } else {
725 return gs_fill(pgs);
726 }
727 }
728
729 private inline bool
compare_arrays(const float * v0,int l0,const float * v1,int l1)730 compare_arrays(const float *v0, int l0, const float *v1, int l1)
731 {
732 if (l0 != l1)
733 return false;
734 if (memcmp(v0, v1, l0 * sizeof(v0[0])))
735 return false;
736 return true;
737 }
738
739 #define compare_tables(a, b) compare_arrays(a.values, a.count, b.values, b.count)
740
741 private int
compare_glyphs(const gs_font * cfont,const gs_font * ofont,gs_glyph * glyphs,int num_glyphs,int glyphs_step,int level)742 compare_glyphs(const gs_font *cfont, const gs_font *ofont, gs_glyph *glyphs,
743 int num_glyphs, int glyphs_step, int level)
744 {
745 /*
746 * Checking widths because we can synthesize fonts from random fonts
747 * having same FontName and FontType.
748 * We must request width explicitely because Type 42 stores widths
749 * separately from outline data. We could skip it for Type 1, which doesn't.
750 * We don't care of Metrics, Metrics2 because copied font never has them.
751 */
752 int i, WMode = ofont->WMode;
753 int members = (GLYPH_INFO_WIDTH0 << WMode) | GLYPH_INFO_OUTLINE_WIDTHS | GLYPH_INFO_NUM_PIECES;
754 gs_matrix mat;
755 gs_copied_font_data_t *const cfdata = cf_data(cfont);
756 int num_new_glyphs = 0;
757
758 gs_make_identity(&mat);
759 for (i = 0; i < num_glyphs; i++) {
760 gs_glyph glyph = *(gs_glyph *)((byte *)glyphs + i * glyphs_step);
761 gs_glyph pieces0[40], *pieces = pieces0;
762 gs_glyph_info_t info0, info1;
763 int code0 = ofont->procs.glyph_info((gs_font *)ofont, glyph, &mat, members, &info0);
764 int code1 = cfont->procs.glyph_info((gs_font *)cfont, glyph, &mat, members, &info1);
765 int code2, code;
766
767 if (code0 == gs_error_undefined)
768 continue;
769 if (code1 == gs_error_undefined) {
770 num_new_glyphs++;
771 if (num_new_glyphs > cfdata->glyphs_size - cfdata->num_glyphs)
772 return 0;
773 continue;
774 }
775 if (code0 < 0)
776 return code0;
777 if (code1 < 0)
778 return code1;
779 if (info0.num_pieces != info1.num_pieces)
780 return 0;
781 if (info0.width[WMode].x != info1.width[WMode].x ||
782 info0.width[WMode].y != info1.width[WMode].y)
783 return 0;
784 if (WMode && (info0.v.x != info1.v.x || info0.v.y != info1.v.y))
785 return 0;
786 if (info0.num_pieces > 0) {
787 if(level > 5)
788 return_error(gs_error_rangecheck); /* abnormal glyph recursion */
789 if (info0.num_pieces > countof(pieces0) / 2) {
790 pieces = (gs_glyph *)gs_alloc_bytes(cfont->memory,
791 sizeof(glyphs) * info0.num_pieces * 2, "compare_glyphs");
792 if (pieces == 0)
793 return_error(gs_error_VMerror);
794 }
795 info0.pieces = pieces;
796 info1.pieces = pieces + info0.num_pieces;
797 code0 = ofont->procs.glyph_info((gs_font *)ofont, glyph, &mat,
798 GLYPH_INFO_PIECES, &info0);
799 code1 = cfont->procs.glyph_info((gs_font *)cfont, glyph, &mat,
800 GLYPH_INFO_PIECES, &info1);
801 if (code0 >= 0 && code1 >= 0) {
802 code2 = memcmp(info0.pieces, info1.pieces, info0.num_pieces * sizeof(*pieces));
803 if (!code2)
804 code = compare_glyphs(cfont, ofont, pieces, info0.num_pieces, glyphs_step, level + 1);
805 else
806 code = 0; /* Quiet compiler. */
807 } else
808 code2 = code = 0;
809 if (pieces != pieces0)
810 gs_free_object(cfont->memory, pieces, "compare_glyphs");
811 if (code0 == gs_error_undefined)
812 continue;
813 if (code1 == gs_error_undefined) {
814 num_new_glyphs++;
815 if (num_new_glyphs > cfdata->glyphs_size - cfdata->num_glyphs)
816 return 0;
817 continue;
818 }
819 if (code0 < 0)
820 return code0;
821 if (code1 < 0)
822 return code1;
823 if (code2 || code == 0) {
824 return 0;
825 }
826 } else {
827 gs_glyph_data_t gdata0, gdata1;
828
829 switch(cfont->FontType) {
830 case ft_encrypted:
831 case ft_encrypted2: {
832 gs_font_type1 *font0 = (gs_font_type1 *)cfont;
833 gs_font_type1 *font1 = (gs_font_type1 *)ofont;
834
835 gdata0.memory = font0->memory;
836 gdata1.memory = font1->memory;
837 code0 = font0->data.procs.glyph_data(font0, glyph, &gdata0);
838 code1 = font1->data.procs.glyph_data(font1, glyph, &gdata1);
839 break;
840 }
841 case ft_TrueType:
842 case ft_CID_TrueType: {
843 gs_font_type42 *font0 = (gs_font_type42 *)cfont;
844 gs_font_type42 *font1 = (gs_font_type42 *)ofont;
845 uint glyph_index0 = font0->data.get_glyph_index(font0, glyph);
846 uint glyph_index1 = font1->data.get_glyph_index(font1, glyph);
847
848 gdata0.memory = font0->memory;
849 gdata1.memory = font1->memory;
850 code0 = font0->data.get_outline(font0, glyph_index0, &gdata0);
851 code1 = font1->data.get_outline(font1, glyph_index1, &gdata1);
852 break;
853 }
854 case ft_CID_encrypted: {
855 gs_font_cid0 *font0 = (gs_font_cid0 *)cfont;
856 gs_font_cid0 *font1 = (gs_font_cid0 *)ofont;
857 int fidx0, fidx1;
858
859 gdata0.memory = font0->memory;
860 gdata1.memory = font1->memory;
861 code0 = font0->cidata.glyph_data((gs_font_base *)font0, glyph, &gdata0, &fidx0);
862 code1 = font1->cidata.glyph_data((gs_font_base *)font1, glyph, &gdata1, &fidx1);
863 break;
864 }
865 default:
866 return_error(gs_error_unregistered); /* unimplemented */
867 }
868 if (code0 < 0) {
869 if (code1 >= 0)
870 gs_glyph_data_free(&gdata1, "compare_glyphs");
871 return code0;
872 }
873 if (code1 < 0) {
874 if (code0 >= 0)
875 gs_glyph_data_free(&gdata0, "compare_glyphs");
876 return code1;
877 }
878 if (gdata0.bits.size != gdata1.bits.size)
879 return 0;
880 if (memcmp(gdata0.bits.data, gdata0.bits.data, gdata0.bits.size))
881 return 0;
882 gs_glyph_data_free(&gdata0, "compare_glyphs");
883 gs_glyph_data_free(&gdata1, "compare_glyphs");
884 }
885 }
886 return 1;
887 }
888
889 /* ---------------- Individual FontTypes ---------------- */
890
891 /* ------ Type 1 ------ */
892
893 private int
copied_type1_glyph_data(gs_font_type1 * pfont,gs_glyph glyph,gs_glyph_data_t * pgd)894 copied_type1_glyph_data(gs_font_type1 * pfont, gs_glyph glyph,
895 gs_glyph_data_t *pgd)
896 {
897 gs_copied_font_data_t *const cfdata = cf_data((gs_font *)pfont);
898 gs_copied_glyph_t *pslot;
899 int code = copied_glyph_slot(cfdata, glyph, &pslot);
900
901 if (code < 0)
902 return code;
903 gs_glyph_data_from_string(pgd, pslot->gdata.data, pslot->gdata.size,
904 NULL);
905 return 0;
906 }
907
908 private int
copied_type1_subr_data(gs_font_type1 * pfont,int subr_num,bool global,gs_glyph_data_t * pgd)909 copied_type1_subr_data(gs_font_type1 * pfont, int subr_num, bool global,
910 gs_glyph_data_t *pgd)
911 {
912 gs_copied_font_data_t *const cfdata = cf_data((gs_font *)pfont);
913 const gs_subr_info_t *psi =
914 (global ? &cfdata->global_subrs : &cfdata->subrs);
915
916 if (subr_num < 0 || subr_num >= psi->count)
917 return_error(gs_error_rangecheck);
918 gs_glyph_data_from_string(pgd, psi->data + psi->starts[subr_num],
919 psi->starts[subr_num + 1] -
920 psi->starts[subr_num],
921 NULL);
922 return 0;
923 }
924
925 private int
copied_type1_seac_data(gs_font_type1 * pfont,int ccode,gs_glyph * pglyph,gs_const_string * gstr,gs_glyph_data_t * pgd)926 copied_type1_seac_data(gs_font_type1 * pfont, int ccode,
927 gs_glyph * pglyph, gs_const_string *gstr, gs_glyph_data_t *pgd)
928 {
929 /*
930 * This can only be invoked if the components have already been
931 * copied to their proper positions, so it is simple.
932 */
933 gs_glyph glyph = gs_c_known_encode((gs_char)ccode, ENCODING_INDEX_STANDARD);
934 gs_glyph glyph1;
935 int code;
936
937 if (glyph == GS_NO_GLYPH)
938 return_error(gs_error_rangecheck);
939 code = gs_c_glyph_name(glyph, gstr);
940 if (code < 0)
941 return code;
942 code = pfont->dir->global_glyph_code(pfont->memory, gstr, &glyph1);
943 if (code < 0)
944 return code;
945 if (pglyph)
946 *pglyph = glyph1;
947 if (pgd)
948 return copied_type1_glyph_data(pfont, glyph1, pgd);
949 else
950 return 0;
951 }
952
953 private int
copied_type1_push_values(void * callback_data,const fixed * values,int count)954 copied_type1_push_values(void *callback_data, const fixed *values, int count)
955 {
956 return_error(gs_error_unregistered);
957 }
958
959 private int
copied_type1_pop_value(void * callback_data,fixed * value)960 copied_type1_pop_value(void *callback_data, fixed *value)
961 {
962 return_error(gs_error_unregistered);
963 }
964
965 private int
copy_font_type1(gs_font * font,gs_font * copied)966 copy_font_type1(gs_font *font, gs_font *copied)
967 {
968 gs_font_type1 *font1 = (gs_font_type1 *)font;
969 gs_font_type1 *copied1 = (gs_font_type1 *)copied;
970 gs_copied_font_data_t *const cfdata = cf_data(copied);
971 int code;
972
973 cfdata->notdef = find_notdef((gs_font_base *)font);
974 code = copied_Encoding_alloc(copied);
975 if (code < 0)
976 return code;
977 if ((code = copy_subrs(font1, false, &cfdata->subrs, copied->memory)) < 0 ||
978 (code = copy_subrs(font1, true, &cfdata->global_subrs, copied->memory)) < 0
979 ) {
980 gs_free_object(copied->memory, cfdata->Encoding,
981 "copy_font_type1(Encoding)");
982 return code;
983 }
984 /*
985 * We don't need real push/pop procedures, because we can't do anything
986 * useful with fonts that have non-standard OtherSubrs anyway.
987 */
988 copied1->data.procs.glyph_data = copied_type1_glyph_data;
989 copied1->data.procs.subr_data = copied_type1_subr_data;
990 copied1->data.procs.seac_data = copied_type1_seac_data;
991 copied1->data.procs.push_values = copied_type1_push_values;
992 copied1->data.procs.pop_value = copied_type1_pop_value;
993 copied1->data.proc_data = 0;
994 return 0;
995 }
996
997 private int
copy_glyph_type1(gs_font * font,gs_glyph glyph,gs_font * copied,int options)998 copy_glyph_type1(gs_font *font, gs_glyph glyph, gs_font *copied, int options)
999 {
1000 gs_glyph_data_t gdata;
1001 gs_font_type1 *font1 = (gs_font_type1 *)font;
1002 int code;
1003 int rcode;
1004
1005 gdata.memory = font->memory;
1006 code = font1->data.procs.glyph_data(font1, glyph, &gdata);
1007 if (code < 0)
1008 return code;
1009 code = copy_glyph_data(font, glyph, copied, options, &gdata, NULL, 0);
1010 if (code < 0)
1011 return code;
1012 rcode = code;
1013 if (code == 0)
1014 code = copy_glyph_name(font, glyph, copied, glyph);
1015 return (code < 0 ? code : rcode);
1016 }
1017
1018 private int
copied_type1_glyph_outline(gs_font * font,int WMode,gs_glyph glyph,const gs_matrix * pmat,gx_path * ppath,double sbw[4])1019 copied_type1_glyph_outline(gs_font *font, int WMode, gs_glyph glyph,
1020 const gs_matrix *pmat, gx_path *ppath, double sbw[4])
1021 { /*
1022 * 'WMode' may be inherited from an upper font.
1023 * We ignore in because Type 1,2 charstrings do not depend on it.
1024 */
1025
1026 /*
1027 * This code duplicates much of zcharstring_outline in zchar1.c.
1028 * This is unfortunate, but we don't see a simple way to refactor the
1029 * code to avoid it.
1030 */
1031 gs_glyph_data_t gdata;
1032 gs_font_type1 *const pfont1 = (gs_font_type1 *)font;
1033 int code;
1034 const gs_glyph_data_t *pgd = &gdata;
1035 gs_type1_state cis;
1036 gs_imager_state gis;
1037
1038 gdata.memory = pfont1->memory;
1039 code = pfont1->data.procs.glyph_data(pfont1, glyph, &gdata);
1040 if (code < 0)
1041 return code;
1042 if (pgd->bits.size <= max(pfont1->data.lenIV, 0))
1043 return_error(gs_error_invalidfont);
1044 /* Initialize just enough of the imager state. */
1045 if (pmat)
1046 gs_matrix_fixed_from_matrix(&gis.ctm, pmat);
1047 else {
1048 gs_matrix imat;
1049
1050 gs_make_identity(&imat);
1051 gs_matrix_fixed_from_matrix(&gis.ctm, &imat);
1052 }
1053 gis.flatness = 0;
1054 code = gs_type1_interp_init(&cis, &gis, ppath, NULL, NULL, true, 0,
1055 pfont1);
1056 if (code < 0)
1057 return code;
1058 cis.no_grid_fitting = true;
1059 /* Continue interpreting. */
1060 for (;;) {
1061 int value;
1062
1063 code = pfont1->data.interpret(&cis, pgd, &value);
1064 switch (code) {
1065 case 0: /* all done */
1066 /* falls through */
1067 default: /* code < 0, error */
1068 return code;
1069 case type1_result_callothersubr: /* unknown OtherSubr */
1070 return_error(gs_error_rangecheck); /* can't handle it */
1071 case type1_result_sbw: /* [h]sbw, just continue */
1072 pgd = 0;
1073 type1_cis_get_metrics(&cis, sbw);
1074 }
1075 }
1076 }
1077
1078 private const gs_copied_font_procs_t copied_procs_type1 = {
1079 copy_font_type1, copy_glyph_type1, copied_char_add_encoding,
1080 named_glyph_slot_hashed,
1081 copied_encode_char, gs_type1_glyph_info, copied_type1_glyph_outline
1082 };
1083
1084 private bool
same_type1_subrs(const gs_font_type1 * cfont,const gs_font_type1 * ofont,bool global)1085 same_type1_subrs(const gs_font_type1 *cfont, const gs_font_type1 *ofont,
1086 bool global)
1087 {
1088 gs_glyph_data_t gdata0, gdata1;
1089 int i, code = 0;
1090 bool exit = false;
1091
1092 gdata0.memory = cfont->memory;
1093 gdata1.memory = ofont->memory;
1094 /* Scan the font to determine the size of the subrs. */
1095 for (i = 0; !exit; i++) {
1096 int code0 = cfont->data.procs.subr_data((gs_font_type1 *)cfont,
1097 i, global, &gdata0);
1098 int code1 = ofont->data.procs.subr_data((gs_font_type1 *)ofont,
1099 i, global, &gdata1);
1100 bool missing0, missing1;
1101
1102 if (code0 == gs_error_rangecheck && code1 == gs_error_rangecheck)
1103 return 1; /* Both arrays exceeded. */
1104 /* Some fonts use null for skiping elements in subrs array.
1105 This gives typecheck.
1106 */
1107 missing0 = (code0 == gs_error_rangecheck || code0 == gs_error_typecheck);
1108 missing1 = (code1 == gs_error_rangecheck || code1 == gs_error_typecheck);
1109 if (missing0 && missing1)
1110 continue;
1111 if (missing0 && !missing1)
1112 return 0; /* The copy has insufficient subrs. */
1113 if (missing1)
1114 continue;
1115 if (code0 < 0)
1116 code = code0, exit = true;
1117 else if (code1 < 0)
1118 code = code1, exit = true;
1119 else if (gdata0.bits.size != gdata1.bits.size)
1120 exit = true;
1121 else if (memcmp(gdata0.bits.data, gdata1.bits.data, gdata0.bits.size))
1122 exit = true;
1123 if (code0 > 0)
1124 gs_glyph_data_free(&gdata0, "same_type1_subrs");
1125 if (code1 > 0)
1126 gs_glyph_data_free(&gdata1, "same_type1_subrs");
1127 }
1128 return code;
1129 }
1130
1131 private bool
same_type1_hinting(const gs_font_type1 * cfont,const gs_font_type1 * ofont)1132 same_type1_hinting(const gs_font_type1 *cfont, const gs_font_type1 *ofont)
1133 {
1134 const gs_type1_data *d0 = &cfont->data, *d1 = &ofont->data;
1135
1136 if (d0->lenIV != d1->lenIV)
1137 return false;
1138 /*
1139 if (d0->defaultWidthX != d1->defaultWidthX)
1140 return false;
1141 if (d0->nominalWidthX != d1->nominalWidthX)
1142 return false;
1143 */
1144 if (d0->BlueFuzz != d1->BlueFuzz)
1145 return false;
1146 if (d0->BlueScale != d1->BlueScale)
1147 return false;
1148 if (d0->BlueShift != d1->BlueShift)
1149 return false;
1150 if (d0->ExpansionFactor != d1->ExpansionFactor)
1151 return false;
1152 if (d0->ForceBold != d1->ForceBold)
1153 return false;
1154 if (!compare_tables(d0->FamilyBlues, d1->FamilyBlues))
1155 return false;
1156 if (!compare_tables(d0->FamilyOtherBlues, d1->FamilyOtherBlues))
1157 return false;
1158 if (d0->LanguageGroup != d1->LanguageGroup)
1159 return false;
1160 if (!compare_tables(d0->OtherBlues, d1->OtherBlues))
1161 return false;
1162 if (d0->RndStemUp != d1->RndStemUp)
1163 return false;
1164 if (!compare_tables(d0->StdHW, d1->StdHW))
1165 return false;
1166 if (!compare_tables(d0->StemSnapH, d1->StemSnapH))
1167 return false;
1168 if (!compare_tables(d0->StemSnapV, d1->StemSnapV))
1169 return false;
1170 if (!compare_tables(d0->WeightVector, d1->WeightVector))
1171 return false;
1172 if (!same_type1_subrs(cfont, ofont, false))
1173 return false;
1174 if (!same_type1_subrs(cfont, ofont, true))
1175 return false;
1176 /*
1177 * We ignore differences in OtherSubrs because pdfwrite
1178 * must build without PS interpreter and therefore copied font
1179 * have no storage for them.
1180 */
1181 return true;
1182 }
1183
1184 /* ------ Type 42 ------ */
1185
1186 private int
copied_type42_string_proc(gs_font_type42 * font,ulong offset,uint len,const byte ** pstr)1187 copied_type42_string_proc(gs_font_type42 *font, ulong offset, uint len,
1188 const byte **pstr)
1189 {
1190 gs_copied_font_data_t *const cfdata = font->data.proc_data;
1191
1192 if (offset + len > cfdata->data_size)
1193 return_error(gs_error_rangecheck);
1194 *pstr = cfdata->data + offset;
1195 return 0;
1196 }
1197
1198 private int
copied_type42_get_outline(gs_font_type42 * font,uint glyph_index,gs_glyph_data_t * pgd)1199 copied_type42_get_outline(gs_font_type42 *font, uint glyph_index,
1200 gs_glyph_data_t *pgd)
1201 {
1202 gs_copied_font_data_t *const cfdata = font->data.proc_data;
1203 gs_copied_glyph_t *pcg;
1204
1205 if (glyph_index >= cfdata->glyphs_size)
1206 return_error(gs_error_rangecheck);
1207 pcg = &cfdata->glyphs[glyph_index];
1208 if (!pcg->used)
1209 gs_glyph_data_from_null(pgd);
1210 else
1211 gs_glyph_data_from_string(pgd, pcg->gdata.data, pcg->gdata.size, NULL);
1212 return 0;
1213 }
1214
1215 private int
copied_type42_get_metrics(gs_font_type42 * pfont,uint glyph_index,int wmode,float sbw[4])1216 copied_type42_get_metrics(gs_font_type42 * pfont, uint glyph_index,
1217 int wmode, float sbw[4])
1218 {
1219 /* Check whether we have metrics for this (glyph,wmode) pair. */
1220 gs_copied_font_data_t *const cfdata = pfont->data.proc_data;
1221 gs_copied_glyph_t *pcg;
1222
1223 if (glyph_index >= cfdata->glyphs_size)
1224 return_error(gs_error_rangecheck);
1225 pcg = &cfdata->glyphs[glyph_index];
1226 if (!(pcg->used & (HAS_SBW0 << wmode)))
1227 return_error(gs_error_undefined);
1228 return gs_type42_default_get_metrics(pfont, glyph_index, wmode, sbw);
1229 }
1230
1231 private uint
copied_type42_get_glyph_index(gs_font_type42 * font,gs_glyph glyph)1232 copied_type42_get_glyph_index(gs_font_type42 *font, gs_glyph glyph)
1233 {
1234 gs_copied_font_data_t *const cfdata = cf_data((gs_font *)font);
1235 gs_copied_glyph_t *pcg;
1236 int code = copied_glyph_slot(cfdata, glyph, &pcg);
1237
1238 if (code < 0)
1239 return GS_NO_GLYPH;
1240 return pcg - cfdata->glyphs;
1241 }
1242
1243 private int
copy_font_type42(gs_font * font,gs_font * copied)1244 copy_font_type42(gs_font *font, gs_font *copied)
1245 {
1246 gs_font_type42 *const font42 = (gs_font_type42 *)font;
1247 gs_font_type42 *const copied42 = (gs_font_type42 *)copied;
1248 gs_copied_font_data_t *const cfdata = cf_data(copied);
1249 /*
1250 * We "write" the font, aside from the glyphs, into an in-memory
1251 * structure, and access it from there.
1252 * We allocate room at the end of the copied data for fake hmtx/vmtx.
1253 */
1254 uint extra = font42->data.trueNumGlyphs * 8;
1255 stream fs;
1256 int code;
1257
1258 cfdata->notdef = find_notdef((gs_font_base *)font);
1259 code = copied_Encoding_alloc(copied);
1260 if (code < 0)
1261 return code;
1262 s_init(&fs, font->memory);
1263 swrite_position_only(&fs);
1264 code = (font->FontType == ft_TrueType ? psf_write_truetype_stripped(&fs, font42)
1265 : psf_write_cid2_stripped(&fs, (gs_font_cid2 *)font42));
1266 code = copied_data_alloc(copied, &fs, extra, code);
1267 if (code < 0)
1268 goto fail;
1269 if (font->FontType == ft_TrueType)
1270 psf_write_truetype_stripped(&fs, font42);
1271 else
1272 psf_write_cid2_stripped(&fs, (gs_font_cid2 *)font42);
1273 copied42->data.string_proc = copied_type42_string_proc;
1274 copied42->data.proc_data = cfdata;
1275 code = gs_type42_font_init(copied42);
1276 if (code < 0)
1277 goto fail2;
1278 /* gs_type42_font_init overwrites enumerate_glyph. */
1279 copied42->procs.enumerate_glyph = copied_enumerate_glyph;
1280 copied42->data.get_glyph_index = copied_type42_get_glyph_index;
1281 copied42->data.get_outline = copied_type42_get_outline;
1282 copied42->data.get_metrics = copied_type42_get_metrics;
1283 copied42->data.metrics[0].numMetrics =
1284 copied42->data.metrics[1].numMetrics =
1285 extra / 8;
1286 copied42->data.metrics[0].offset = cfdata->data_size - extra;
1287 copied42->data.metrics[1].offset = cfdata->data_size - extra / 2;
1288 copied42->data.metrics[0].length =
1289 copied42->data.metrics[1].length =
1290 extra / 2;
1291 memset(cfdata->data + cfdata->data_size - extra, 0, extra);
1292 copied42->data.numGlyphs = font42->data.numGlyphs;
1293 copied42->data.trueNumGlyphs = font42->data.trueNumGlyphs;
1294 return 0;
1295 fail2:
1296 gs_free_object(copied->memory, cfdata->data,
1297 "copy_font_type42(data)");
1298 fail:
1299 gs_free_object(copied->memory, cfdata->Encoding,
1300 "copy_font_type42(Encoding)");
1301 return code;
1302 }
1303
1304 private int
copy_glyph_type42(gs_font * font,gs_glyph glyph,gs_font * copied,int options)1305 copy_glyph_type42(gs_font *font, gs_glyph glyph, gs_font *copied, int options)
1306 {
1307 gs_glyph_data_t gdata;
1308 gs_font_type42 *font42 = (gs_font_type42 *)font;
1309 gs_font_cid2 *fontCID2 = (gs_font_cid2 *)font;
1310 gs_font_type42 *const copied42 = (gs_font_type42 *)copied;
1311 uint gid = (options & COPY_GLYPH_BY_INDEX ? glyph - GS_MIN_GLYPH_INDEX :
1312 font->FontType == ft_CID_TrueType
1313 ? fontCID2->cidata.CIDMap_proc(fontCID2, glyph)
1314 : font42->data.get_glyph_index(font42, glyph));
1315 int code;
1316 int rcode;
1317 gs_copied_font_data_t *const cfdata = cf_data(copied);
1318 gs_copied_glyph_t *pcg;
1319 float sbw[4];
1320 double factor = font42->data.unitsPerEm;
1321 int i;
1322
1323 gdata.memory = font42->memory;
1324 code = font42->data.get_outline(font42, gid, &gdata);
1325 if (code < 0)
1326 return code;
1327 code = copy_glyph_data(font, gid + GS_MIN_GLYPH_INDEX, copied, options,
1328 &gdata, NULL, 0);
1329 if (code < 0)
1330 return code;
1331 rcode = code;
1332 if (glyph < GS_MIN_CID_GLYPH)
1333 code = copy_glyph_name(font, glyph, copied,
1334 gid + GS_MIN_GLYPH_INDEX);
1335 DISCARD(copied_glyph_slot(cfdata, gid + GS_MIN_GLYPH_INDEX, &pcg)); /* can't fail */
1336 for (i = 0; i < 2; ++i) {
1337 if (font42->data.get_metrics(font42, gid, i, sbw) >= 0) {
1338 int sb = (int)(sbw[i] * factor + 0.5);
1339 uint width = (uint)(sbw[2 + i] * factor + 0.5);
1340 byte *pmetrics =
1341 cfdata->data + copied42->data.metrics[i].offset + gid * 4;
1342
1343 pmetrics[0] = (byte)(width >> 8);
1344 pmetrics[1] = (byte)width;
1345 pmetrics[2] = (byte)(sb >> 8);
1346 pmetrics[3] = (byte)sb;
1347 pcg->used |= HAS_SBW0 << i;
1348 }
1349 factor = -factor; /* values are negated for WMode = 1 */
1350 }
1351 return (code < 0 ? code : rcode);
1352 }
1353
1354 private gs_glyph
copied_type42_encode_char(gs_font * copied,gs_char chr,gs_glyph_space_t glyph_space)1355 copied_type42_encode_char(gs_font *copied, gs_char chr,
1356 gs_glyph_space_t glyph_space)
1357 {
1358 gs_copied_font_data_t *const cfdata = cf_data(copied);
1359 const gs_glyph *Encoding = cfdata->Encoding;
1360 gs_glyph glyph;
1361
1362 if (chr >= 256 || Encoding == 0)
1363 return GS_NO_GLYPH;
1364 glyph = Encoding[chr];
1365 if (glyph_space == GLYPH_SPACE_INDEX) {
1366 /* Search linearly for the glyph by name. */
1367 gs_copied_glyph_t *pcg;
1368 int code = named_glyph_slot_linear(cfdata, glyph, &pcg);
1369
1370 if (code < 0 || !pcg->used)
1371 return GS_NO_GLYPH;
1372 return GS_MIN_GLYPH_INDEX + (pcg - cfdata->glyphs);
1373 }
1374 return glyph;
1375 }
1376
1377
1378 private const gs_copied_font_procs_t copied_procs_type42 = {
1379 copy_font_type42, copy_glyph_type42, copied_char_add_encoding,
1380 named_glyph_slot_linear,
1381 copied_type42_encode_char, gs_type42_glyph_info, gs_type42_glyph_outline
1382 };
1383
1384 private inline int
access_type42_data(gs_font_type42 * pfont,ulong base,ulong length,const byte ** vptr)1385 access_type42_data(gs_font_type42 *pfont, ulong base, ulong length,
1386 const byte **vptr)
1387 {
1388 /* See ACCESS macro in gstype42.c */
1389 return pfont->data.string_proc(pfont, base, length, vptr);
1390 }
1391
1392 private inline uint
U16(const byte * p)1393 U16(const byte *p)
1394 {
1395 return ((uint)p[0] << 8) + p[1];
1396 }
1397
1398 private int
same_type42_hinting(gs_font_type42 * font0,gs_font_type42 * font1)1399 same_type42_hinting(gs_font_type42 *font0, gs_font_type42 *font1)
1400 {
1401 gs_type42_data *d0 = &font0->data, *d1 = &font1->data;
1402 gs_font_type42 *font[2];
1403 uint pos[2][3];
1404 uint len[2][3] = {{0,0,0}, {0,0,0}};
1405 int i, j, code;
1406
1407 if (d0->unitsPerEm != d1->unitsPerEm)
1408 return 0;
1409 font[0] = font0;
1410 font[1] = font1;
1411 memset(pos, 0, sizeof(pos));
1412 for (j = 0; j < 2; j++) {
1413 const byte *OffsetTable;
1414 uint numTables;
1415
1416 code = access_type42_data(font[j], 0, 12, &OffsetTable);
1417 if (code < 0)
1418 return code;
1419 numTables = U16(OffsetTable + 4);
1420 for (i = 0; i < numTables; ++i) {
1421 const byte *tab;
1422 ulong start;
1423 uint length;
1424
1425 code = access_type42_data(font[j], 12 + i * 16, 16, &tab);
1426 if (code < 0)
1427 return code;
1428 start = get_u32_msb(tab + 8);
1429 length = get_u32_msb(tab + 12);
1430 if (!memcmp("prep", tab, 4))
1431 pos[j][0] = start, len[j][0] = length;
1432 else if (!memcmp("cvt ", tab, 4))
1433 pos[j][1] = start, len[j][1] = length;
1434 else if (!memcmp("fpgm", tab, 4))
1435 pos[j][2] = start, len[j][2] = length;
1436 }
1437 }
1438 for (i = 0; i < 3; i++) {
1439 if (len[0][i] != len[1][i])
1440 return 0;
1441 }
1442 for (i = 0; i < 3; i++) {
1443 if (len[0][i] != 0) {
1444 const byte *data0, *data1;
1445
1446 code = access_type42_data(font0, pos[0][i], len[0][i], &data0);
1447 if (code < 0)
1448 return code;
1449 code = access_type42_data(font1, pos[1][i], len[1][i], &data1);
1450 if (code < 0)
1451 return code;
1452 if (memcmp(data0, data1, len[1][i]))
1453 return 0;
1454 }
1455 }
1456 return 1;
1457 }
1458
1459 #undef ACCESS
1460
1461 /* ------ CIDFont shared ------ */
1462
1463 private int
copy_font_cid_common(gs_font * font,gs_font * copied,gs_font_cid_data * pcdata)1464 copy_font_cid_common(gs_font *font, gs_font *copied, gs_font_cid_data *pcdata)
1465 {
1466 return (copy_string(copied->memory, &pcdata->CIDSystemInfo.Registry,
1467 "Registry") |
1468 copy_string(copied->memory, &pcdata->CIDSystemInfo.Ordering,
1469 "Ordering"));
1470 }
1471
1472 /* ------ CIDFontType 0 ------ */
1473
1474 private int
copied_cid0_glyph_data(gs_font_base * font,gs_glyph glyph,gs_glyph_data_t * pgd,int * pfidx)1475 copied_cid0_glyph_data(gs_font_base *font, gs_glyph glyph,
1476 gs_glyph_data_t *pgd, int *pfidx)
1477 {
1478 gs_font_cid0 *fcid0 = (gs_font_cid0 *)font;
1479 gs_copied_font_data_t *const cfdata = cf_data((gs_font *)font);
1480 gs_copied_glyph_t *pcg;
1481 int code = copied_glyph_slot(cfdata, glyph, &pcg);
1482 int fdbytes = fcid0->cidata.FDBytes;
1483 int i;
1484
1485 if (pfidx)
1486 *pfidx = 0;
1487 if (code < 0) {
1488 if (pgd)
1489 gs_glyph_data_from_null(pgd);
1490 return_error(gs_error_undefined);
1491 }
1492 if (pfidx)
1493 for (i = 0; i < fdbytes; ++i)
1494 *pfidx = (*pfidx << 8) + pcg->gdata.data[i];
1495 if (pgd)
1496 gs_glyph_data_from_string(pgd, pcg->gdata.data + fdbytes,
1497 pcg->gdata.size - fdbytes, NULL);
1498 return 0;
1499 }
1500 private int
copied_sub_type1_glyph_data(gs_font_type1 * pfont,gs_glyph glyph,gs_glyph_data_t * pgd)1501 copied_sub_type1_glyph_data(gs_font_type1 * pfont, gs_glyph glyph,
1502 gs_glyph_data_t *pgd)
1503 {
1504 return
1505 copied_cid0_glyph_data((gs_font_base *)cf_data((gs_font *)pfont)->parent,
1506 glyph, pgd, NULL);
1507 }
1508
1509 private int
cid0_subfont(gs_font * copied,gs_glyph glyph,gs_font_type1 ** pfont1)1510 cid0_subfont(gs_font *copied, gs_glyph glyph, gs_font_type1 **pfont1)
1511 {
1512 int fidx;
1513 int code = copied_cid0_glyph_data((gs_font_base *)copied, glyph, NULL,
1514 &fidx);
1515
1516 if (code >= 0) {
1517 gs_font_cid0 *font0 = (gs_font_cid0 *)copied;
1518
1519 if (fidx >= font0->cidata.FDArray_size)
1520 return_error(gs_error_unregistered); /* Must not happen. */
1521 *pfont1 = font0->cidata.FDArray[fidx];
1522 }
1523 return code;
1524 }
1525
1526 private int
copied_cid0_glyph_info(gs_font * font,gs_glyph glyph,const gs_matrix * pmat,int members,gs_glyph_info_t * info)1527 copied_cid0_glyph_info(gs_font *font, gs_glyph glyph, const gs_matrix *pmat,
1528 int members, gs_glyph_info_t *info)
1529 {
1530 gs_font_type1 *subfont1;
1531 int code = cid0_subfont(font, glyph, &subfont1);
1532
1533 if (code < 0)
1534 return code;
1535 if (members & GLYPH_INFO_WIDTH1) {
1536 /* Hack : There is no way to pass WMode from font to glyph_info,
1537 * and usually CID font has no metrics for WMode 1.
1538 * Therefore we use FontBBox as default size.
1539 * Warning : this incompletely implements the request :
1540 * other requested members are not retrieved.
1541 */
1542 gs_font_info_t finfo;
1543 int code = subfont1->procs.font_info(font, NULL, FONT_INFO_BBOX, &finfo);
1544
1545 if (code < 0)
1546 return code;
1547 info->width[1].x = 0;
1548 info->width[1].y = -finfo.BBox.q.x; /* Sic! */
1549 info->v.x = finfo.BBox.q.x / 2;
1550 info->v.y = finfo.BBox.q.y;
1551 info->members = GLYPH_INFO_WIDTH1;
1552 return 0;
1553 }
1554 return subfont1->procs.glyph_info((gs_font *)subfont1, glyph, pmat,
1555 members, info);
1556 }
1557
1558 private int
copied_cid0_glyph_outline(gs_font * font,int WMode,gs_glyph glyph,const gs_matrix * pmat,gx_path * ppath,double sbw[4])1559 copied_cid0_glyph_outline(gs_font *font, int WMode, gs_glyph glyph,
1560 const gs_matrix *pmat, gx_path *ppath, double sbw[4])
1561 {
1562 gs_font_type1 *subfont1;
1563 int code = cid0_subfont(font, glyph, &subfont1);
1564
1565 if (code < 0)
1566 return code;
1567 return subfont1->procs.glyph_outline((gs_font *)subfont1, WMode, glyph, pmat,
1568 ppath, sbw);
1569 }
1570
1571 private int
copy_font_cid0(gs_font * font,gs_font * copied)1572 copy_font_cid0(gs_font *font, gs_font *copied)
1573 {
1574 gs_font_cid0 *copied0 = (gs_font_cid0 *)copied;
1575 gs_copied_font_data_t *const cfdata = cf_data(copied);
1576 gs_font_type1 **FDArray =
1577 gs_alloc_struct_array(copied->memory, copied0->cidata.FDArray_size,
1578 gs_font_type1 *,
1579 &st_gs_font_type1_ptr_element, "FDArray");
1580 int i = 0, code;
1581
1582 if (FDArray == 0)
1583 return_error(gs_error_VMerror);
1584 code = copy_font_cid_common(font, copied, &copied0->cidata.common);
1585 if (code < 0)
1586 goto fail;
1587 for (; i < copied0->cidata.FDArray_size; ++i) {
1588 gs_font *subfont = (gs_font *)copied0->cidata.FDArray[i];
1589 gs_font_type1 *subfont1 = (gs_font_type1 *)subfont;
1590 gs_font *subcopy;
1591 gs_font_type1 *subcopy1;
1592 gs_copied_font_data_t *subdata;
1593
1594 if (i == 0) {
1595 /* copy_subrs requires a Type 1 font, even for GSubrs. */
1596 code = copy_subrs(subfont1, true, &cfdata->global_subrs,
1597 copied->memory);
1598 if (code < 0)
1599 goto fail;
1600 }
1601 code = gs_copy_font(subfont, &subfont->FontMatrix, copied->memory, &subcopy);
1602 if (code < 0)
1603 goto fail;
1604 subcopy1 = (gs_font_type1 *)subcopy;
1605 subcopy1->data.parent = NULL;
1606 subdata = cf_data(subcopy);
1607 subdata->parent = copied0;
1608 gs_free_object(copied->memory, subdata->Encoding,
1609 "copy_font_cid0(Encoding)");
1610 subdata->Encoding = 0;
1611 /*
1612 * Share the glyph data and global_subrs with the parent. This
1613 * allows copied_type1_glyph_data in the subfont to do the right
1614 * thing.
1615 */
1616 gs_free_object(copied->memory, subdata->names,
1617 "copy_font_cid0(subfont names)");
1618 gs_free_object(copied->memory, subdata->glyphs,
1619 "copy_font_cid0(subfont glyphs)");
1620 subcopy1->data.procs.glyph_data = copied_sub_type1_glyph_data;
1621 subdata->glyphs = cfdata->glyphs;
1622 subdata->glyphs_size = cfdata->glyphs_size;
1623 subdata->names = 0;
1624 subdata->global_subrs = cfdata->global_subrs;
1625 FDArray[i] = subcopy1;
1626 }
1627 cfdata->notdef = GS_MIN_CID_GLYPH;
1628 copied0->cidata.FDArray = FDArray;
1629 copied0->cidata.FDBytes =
1630 (copied0->cidata.FDArray_size <= 1 ? 0 :
1631 copied0->cidata.FDArray_size <= 256 ? 1 : 2);
1632 copied0->cidata.glyph_data = copied_cid0_glyph_data;
1633 return 0;
1634 fail:
1635 while (--i >= 0)
1636 gs_free_object(copied->memory, FDArray[i], "copy_font_cid0(subfont)");
1637 gs_free_object(copied->memory, FDArray, "FDArray");
1638 return code;
1639 }
1640
1641 private int
copy_glyph_cid0(gs_font * font,gs_glyph glyph,gs_font * copied,int options)1642 copy_glyph_cid0(gs_font *font, gs_glyph glyph, gs_font *copied, int options)
1643 {
1644 gs_glyph_data_t gdata;
1645 gs_font_cid0 *fcid0 = (gs_font_cid0 *)font;
1646 gs_font_cid0 *copied0 = (gs_font_cid0 *)copied;
1647 int fdbytes = copied0->cidata.FDBytes;
1648 int fidx;
1649 int code;
1650 byte prefix[MAX_FDBytes];
1651 int i;
1652
1653 gdata.memory = font->memory;
1654 code = fcid0->cidata.glyph_data((gs_font_base *)font, glyph,
1655 &gdata, &fidx);
1656 if (code < 0)
1657 return code;
1658 for (i = fdbytes - 1; i >= 0; --i, fidx >>= 8)
1659 prefix[i] = (byte)fidx;
1660 if (fidx != 0)
1661 return_error(gs_error_rangecheck);
1662 return copy_glyph_data(font, glyph, copied, options, &gdata, prefix, fdbytes);
1663 }
1664
1665 private const gs_copied_font_procs_t copied_procs_cid0 = {
1666 copy_font_cid0, copy_glyph_cid0, copied_no_add_encoding,
1667 named_glyph_slot_none,
1668 gs_no_encode_char, copied_cid0_glyph_info, copied_cid0_glyph_outline
1669 };
1670
1671 private int
same_cid0_hinting(const gs_font_cid0 * cfont,const gs_font_cid0 * ofont)1672 same_cid0_hinting(const gs_font_cid0 *cfont, const gs_font_cid0 *ofont)
1673 {
1674 int i;
1675
1676 if (cfont->cidata.FDArray_size != ofont->cidata.FDArray_size)
1677 return 0;
1678
1679 for (i = 0; i < cfont->cidata.FDArray_size; i++) {
1680 gs_font_type1 *subfont0 = cfont->cidata.FDArray[i];
1681 gs_font_type1 *subfont1 = ofont->cidata.FDArray[i];
1682 if (!same_type1_hinting(subfont0, subfont1))
1683 return 0;
1684 }
1685 return 1;
1686 }
1687
1688 /* ------ CIDFontType 2 ------ */
1689
1690 private int
copied_cid2_CIDMap_proc(gs_font_cid2 * fcid2,gs_glyph glyph)1691 copied_cid2_CIDMap_proc(gs_font_cid2 *fcid2, gs_glyph glyph)
1692 {
1693 uint cid = glyph - GS_MIN_CID_GLYPH;
1694 gs_copied_font_data_t *const cfdata = cf_data((gs_font *)fcid2);
1695 const ushort *CIDMap = cfdata->CIDMap;
1696
1697 if (glyph < GS_MIN_CID_GLYPH || cid >= fcid2->cidata.common.CIDCount)
1698 return_error(gs_error_rangecheck);
1699 if (CIDMap[cid] == 0xffff)
1700 return -1;
1701 return CIDMap[cid];
1702 }
1703
1704 private uint
copied_cid2_get_glyph_index(gs_font_type42 * font,gs_glyph glyph)1705 copied_cid2_get_glyph_index(gs_font_type42 *font, gs_glyph glyph)
1706 {
1707 int glyph_index = copied_cid2_CIDMap_proc((gs_font_cid2 *)font, glyph);
1708
1709 if (glyph_index < 0)
1710 return GS_NO_GLYPH;
1711 return glyph_index;
1712 }
1713
1714 private int
copy_font_cid2(gs_font * font,gs_font * copied)1715 copy_font_cid2(gs_font *font, gs_font *copied)
1716 {
1717 gs_font_cid2 *copied2 = (gs_font_cid2 *)copied;
1718 gs_copied_font_data_t *const cfdata = cf_data(copied);
1719 int code;
1720 int CIDCount = copied2->cidata.common.CIDCount;
1721 ushort *CIDMap = (ushort *)
1722 gs_alloc_byte_array(copied->memory, CIDCount, sizeof(ushort),
1723 "copy_font_cid2(CIDMap");
1724
1725 if (CIDMap == 0)
1726 return_error(gs_error_VMerror);
1727 code = copy_font_cid_common(font, copied, &copied2->cidata.common);
1728 if (code < 0 ||
1729 (code = copy_font_type42(font, copied)) < 0
1730 ) {
1731 gs_free_object(copied->memory, CIDMap, "copy_font_cid2(CIDMap");
1732 return code;
1733 }
1734 cfdata->notdef = GS_MIN_CID_GLYPH;
1735 memset(CIDMap, 0xff, CIDCount * sizeof(*CIDMap));
1736 cfdata->CIDMap = CIDMap;
1737 copied2->cidata.MetricsCount = 0;
1738 copied2->cidata.CIDMap_proc = copied_cid2_CIDMap_proc;
1739 {
1740 gs_font_type42 *const copied42 = (gs_font_type42 *)copied;
1741
1742 copied42->data.get_glyph_index = copied_cid2_get_glyph_index;
1743 }
1744 return 0;
1745 }
1746
expand_CIDMap(gs_font_cid2 * copied2,uint CIDCount)1747 private int expand_CIDMap(gs_font_cid2 *copied2, uint CIDCount)
1748 {
1749 ushort *CIDMap;
1750 gs_copied_font_data_t *const cfdata = cf_data((gs_font *)copied2);
1751
1752 if (CIDCount <= copied2->cidata.common.CIDCount)
1753 return 0;
1754 CIDMap = (ushort *)
1755 gs_alloc_byte_array(copied2->memory, CIDCount, sizeof(ushort),
1756 "copy_font_cid2(CIDMap");
1757 if (CIDMap == 0)
1758 return_error(gs_error_VMerror);
1759 memcpy(CIDMap, cfdata->CIDMap, copied2->cidata.common.CIDCount * sizeof(*CIDMap));
1760 memset(CIDMap + copied2->cidata.common.CIDCount, 0xFF,
1761 (CIDCount - copied2->cidata.common.CIDCount) * sizeof(*CIDMap));
1762 cfdata->CIDMap = CIDMap;
1763 copied2->cidata.common.CIDCount = CIDCount;
1764 return 0;
1765 }
1766
1767 private int
copy_glyph_cid2(gs_font * font,gs_glyph glyph,gs_font * copied,int options)1768 copy_glyph_cid2(gs_font *font, gs_glyph glyph, gs_font *copied, int options)
1769 {
1770 gs_font_cid2 *fcid2 = (gs_font_cid2 *)font;
1771 gs_copied_font_data_t *const cfdata = cf_data(copied);
1772 gs_font_cid2 *copied2 = (gs_font_cid2 *)copied;
1773 int gid;
1774 int code;
1775
1776 if (!(options & COPY_GLYPH_BY_INDEX)) {
1777 uint cid = glyph - GS_MIN_CID_GLYPH;
1778 int CIDCount;
1779
1780 code = expand_CIDMap(copied2, cid + 1);
1781 if (code < 0)
1782 return code;
1783 CIDCount = copied2->cidata.common.CIDCount;
1784 gid = fcid2->cidata.CIDMap_proc(fcid2, glyph);
1785 if (gid < 0 || gid >= cfdata->glyphs_size)
1786 return_error(gs_error_rangecheck);
1787 if (cid > CIDCount)
1788 return_error(gs_error_invalidaccess);
1789 if (cfdata->CIDMap[cid] != 0xffff && cfdata->CIDMap[cid] != gid)
1790 return_error(gs_error_invalidaccess);
1791 code = copy_glyph_type42(font, glyph, copied, options);
1792 if (code < 0)
1793 return code;
1794 cfdata->CIDMap[cid] = gid;
1795 } else {
1796 gid = glyph - GS_MIN_GLYPH_INDEX;
1797 if (gid < 0 || gid >= cfdata->glyphs_size)
1798 return_error(gs_error_rangecheck);
1799 code = copy_glyph_type42(font, glyph, copied, options);
1800 if (code < 0)
1801 return code;
1802 }
1803 return code;
1804 }
1805
1806 private const gs_copied_font_procs_t copied_procs_cid2 = {
1807 copy_font_cid2, copy_glyph_cid2, copied_no_add_encoding,
1808 named_glyph_slot_none,
1809 gs_no_encode_char, gs_type42_glyph_info, gs_type42_glyph_outline
1810 };
1811
1812 private int
same_cid2_hinting(const gs_font_cid2 * cfont,const gs_font_cid2 * ofont)1813 same_cid2_hinting(const gs_font_cid2 *cfont, const gs_font_cid2 *ofont)
1814 {
1815 return same_type42_hinting((gs_font_type42 *)cfont, (gs_font_type42 *)ofont);
1816 }
1817
1818 /* ---------------- Public ---------------- */
1819
1820 /*
1821 * Procedure vector for copied fonts.
1822 */
1823 private font_proc_font_info(copied_font_info);
1824 private font_proc_enumerate_glyph(copied_enumerate_glyph);
1825 private const gs_font_procs copied_font_procs = {
1826 0, /* define_font, not supported */
1827 0, /* make_font, not supported */
1828 copied_font_info,
1829 gs_default_same_font,
1830 0, /* encode_char, varies by FontType */
1831 0, /* decode_char, not supported */
1832 copied_enumerate_glyph,
1833 0, /* glyph_info, varies by FontType */
1834 0, /* glyph_outline, varies by FontType */
1835 copied_glyph_name,
1836 gs_default_init_fstack,
1837 gs_default_next_char_glyph,
1838 copied_build_char
1839 };
1840
1841 #if GLYPHS_SIZE_IS_PRIME
1842 private const int some_primes[] = {
1843 /* Arbitrary choosen prime numbers, being reasonable for a Type 1|2 font size.
1844 We start with 257 to fit 256 glyphs and .notdef .
1845 Smaller numbers aren't useful, because we don't know whether a font
1846 will add more glyphs incrementally when we allocate its stable copy.
1847 */
1848 257, 359, 521, 769, 1031, 2053,
1849 3079, 4099, 5101, 6101, 7109, 8209, 10007, 12007, 14009,
1850 16411, 20107, 26501, 32771, 48857, 65537};
1851 #endif
1852
1853 /*
1854 * Copy a font, aside from its glyphs.
1855 */
1856 int
gs_copy_font(gs_font * font,const gs_matrix * orig_matrix,gs_memory_t * mem,gs_font ** pfont_new)1857 gs_copy_font(gs_font *font, const gs_matrix *orig_matrix, gs_memory_t *mem, gs_font **pfont_new)
1858 {
1859 gs_memory_type_ptr_t fstype = gs_object_type(font->memory, font);
1860 uint fssize = gs_struct_type_size(fstype);
1861 gs_font *copied = 0;
1862 gs_copied_font_data_t *cfdata = 0;
1863 gs_font_info_t info;
1864 gs_copied_glyph_t *glyphs = 0;
1865 uint glyphs_size;
1866 gs_copied_glyph_name_t *names = 0;
1867 bool have_names = false;
1868 const gs_copied_font_procs_t *procs;
1869 int code;
1870
1871 /*
1872 * Check for a supported FontType, and compute the size of its
1873 * copied glyph table.
1874 */
1875 switch (font->FontType) {
1876 case ft_TrueType:
1877 procs = &copied_procs_type42;
1878 glyphs_size = ((gs_font_type42 *)font)->data.trueNumGlyphs;
1879 have_names = true;
1880 break;
1881 case ft_encrypted:
1882 case ft_encrypted2:
1883 procs = &copied_procs_type1;
1884 /* Count the glyphs. */
1885 glyphs_size = 0;
1886 {
1887 int index = 0;
1888 gs_glyph glyph;
1889
1890 while (font->procs.enumerate_glyph(font, &index, GLYPH_SPACE_NAME,
1891 &glyph), index != 0)
1892 ++glyphs_size;
1893 }
1894 #if GLYPHS_SIZE_IS_PRIME
1895 /*
1896 * Make glyphs_size a prime number to ensure termination of the loop in
1897 * named_glyphs_slot_hashed, q.v.
1898 * Also reserve additional slots for the case of font merging and
1899 * for possible font increments.
1900 */
1901 glyphs_size = glyphs_size * 3 / 2;
1902 if (glyphs_size < 257)
1903 glyphs_size = 257;
1904 { int i;
1905 for (i = 0; i < count_of(some_primes); i++)
1906 if (glyphs_size <= some_primes[i])
1907 break;
1908 if (i >= count_of(some_primes))
1909 return_error(gs_error_rangecheck);
1910 glyphs_size = some_primes[i];
1911 }
1912 #else
1913 /*
1914 * Make names_size a power of 2 to ensure termination of the loop in
1915 * named_glyphs_slot_hashed, q.v.
1916 */
1917 glyphs_size = glyphs_size * 3 / 2;
1918 while (glyphs_size & (glyphs_size - 1))
1919 glyphs_size = (glyphs_size | (glyphs_size - 1)) + 1;
1920 if (glyphs_size < 256) /* probably incremental font */
1921 glyphs_size = 256;
1922 #endif
1923 have_names = true;
1924 break;
1925 case ft_CID_encrypted:
1926 procs = &copied_procs_cid0;
1927 glyphs_size = ((gs_font_cid0 *)font)->cidata.common.CIDCount;
1928 break;
1929 case ft_CID_TrueType:
1930 procs = &copied_procs_cid2;
1931 /* Glyphs are indexed by GID, not by CID. */
1932 glyphs_size = ((gs_font_cid2 *)font)->data.trueNumGlyphs;
1933 break;
1934 default:
1935 return_error(gs_error_rangecheck);
1936 }
1937
1938 /* Get the font_info for copying. */
1939
1940 memset(&info, 0, sizeof(info));
1941 info.Flags_requested = ~0;
1942 code = font->procs.font_info(font, NULL, ~0, &info);
1943 if (code < 0)
1944 return code;
1945
1946 /* Allocate the generic copied information. */
1947
1948 glyphs = gs_alloc_struct_array(mem, glyphs_size, gs_copied_glyph_t,
1949 &st_gs_copied_glyph_element,
1950 "gs_copy_font(glyphs)");
1951 if (have_names != 0)
1952 names = gs_alloc_struct_array(mem, glyphs_size, gs_copied_glyph_name_t,
1953 &st_gs_copied_glyph_name_element,
1954 "gs_copy_font(names)");
1955 copied = gs_alloc_struct(mem, gs_font, fstype,
1956 "gs_copy_font(copied font)");
1957 cfdata = gs_alloc_struct(mem, gs_copied_font_data_t,
1958 &st_gs_copied_font_data,
1959 "gs_copy_font(wrapper data)");
1960 if (cfdata)
1961 memset(cfdata, 0, sizeof(*cfdata));
1962 if (glyphs == 0 || (names == 0 && have_names) || copied == 0 ||
1963 cfdata == 0
1964 ) {
1965 code = gs_note_error(gs_error_VMerror);
1966 goto fail;
1967 }
1968 cfdata->info = info;
1969 cfdata->dir = font->dir;
1970 if ((code = (copy_string(mem, &cfdata->info.Copyright,
1971 "gs_copy_font(Copyright)") |
1972 copy_string(mem, &cfdata->info.Notice,
1973 "gs_copy_font(Notice)") |
1974 copy_string(mem, &cfdata->info.FamilyName,
1975 "gs_copy_font(FamilyName)") |
1976 copy_string(mem, &cfdata->info.FullName,
1977 "gs_copy_font(FullName)"))) < 0
1978 )
1979 goto fail;
1980
1981 /* Initialize the copied font. */
1982
1983 memcpy(copied, font, fssize);
1984 copied->next = copied->prev = 0;
1985 copied->memory = mem;
1986 copied->is_resource = false;
1987 gs_notify_init(&copied->notify_list, mem);
1988 copied->base = copied;
1989 copied->FontMatrix = *orig_matrix;
1990 copied->client_data = cfdata;
1991 copied->procs = copied_font_procs;
1992 copied->procs.encode_char = procs->encode_char;
1993 copied->procs.glyph_info = procs->glyph_info;
1994 copied->procs.glyph_outline = procs->glyph_outline;
1995 {
1996 gs_font_base *bfont = (gs_font_base *)copied;
1997
1998 bfont->FAPI = 0;
1999 bfont->FAPI_font_data = 0;
2000 bfont->encoding_index = ENCODING_INDEX_UNKNOWN;
2001 code = uid_copy(&bfont->UID, mem, "gs_copy_font(UID)");
2002 if (code < 0)
2003 goto fail;
2004 }
2005
2006 cfdata->procs = procs;
2007 memset(glyphs, 0, glyphs_size * sizeof(*glyphs));
2008 cfdata->glyphs = glyphs;
2009 cfdata->glyphs_size = glyphs_size;
2010 cfdata->num_glyphs = 0;
2011 if (names)
2012 memset(names, 0, glyphs_size * sizeof(*names));
2013 cfdata->names = names;
2014 if (names != 0) {
2015 uint i;
2016
2017 for (i = 0; i < glyphs_size; ++i)
2018 names[i].glyph = GS_NO_GLYPH;
2019 }
2020
2021 /* Do FontType-specific initialization. */
2022
2023 code = procs->finish_copy_font(font, copied);
2024 if (code < 0)
2025 goto fail;
2026
2027 *pfont_new = copied;
2028 if (cfdata->notdef != GS_NO_GLYPH)
2029 code = gs_copy_glyph(font, cfdata->notdef, copied);
2030 return code;
2031
2032 fail:
2033 /* Free storage and exit. */
2034 if (cfdata) {
2035 uncopy_string(mem, &cfdata->info.FullName,
2036 "gs_copy_font(FullName)");
2037 uncopy_string(mem, &cfdata->info.FamilyName,
2038 "gs_copy_font(FamilyName)");
2039 uncopy_string(mem, &cfdata->info.Notice,
2040 "gs_copy_font(Notice)");
2041 uncopy_string(mem, &cfdata->info.Copyright,
2042 "gs_copy_font(Copyright)");
2043 gs_free_object(mem, cfdata, "gs_copy_font(wrapper data)");
2044 }
2045 gs_free_object(mem, copied, "gs_copy_font(copied font)");
2046 gs_free_object(mem, names, "gs_copy_font(names)");
2047 gs_free_object(mem, glyphs, "gs_copy_font(glyphs)");
2048 return code;
2049 }
2050
2051 /*
2052 * Copy a glyph, including any sub-glyphs.
2053 */
2054 int
gs_copy_glyph(gs_font * font,gs_glyph glyph,gs_font * copied)2055 gs_copy_glyph(gs_font *font, gs_glyph glyph, gs_font *copied)
2056 {
2057 return gs_copy_glyph_options(font, glyph, copied, 0);
2058 }
2059 int
gs_copy_glyph_options(gs_font * font,gs_glyph glyph,gs_font * copied,int options)2060 gs_copy_glyph_options(gs_font *font, gs_glyph glyph, gs_font *copied,
2061 int options)
2062 {
2063 int code;
2064 #define MAX_GLYPH_PIECES 64 /* arbitrary, but 32 is too small - bug 687698. */
2065 gs_glyph glyphs[MAX_GLYPH_PIECES];
2066 uint count = 1, i;
2067
2068 if (copied->procs.font_info != copied_font_info)
2069 return_error(gs_error_rangecheck);
2070 code = cf_data(copied)->procs->copy_glyph(font, glyph, copied, options);
2071 if (code != 0)
2072 return code;
2073 /* Copy any sub-glyphs. */
2074 glyphs[0] = glyph;
2075 code = psf_add_subset_pieces(glyphs, &count, MAX_GLYPH_PIECES, MAX_GLYPH_PIECES,
2076 font);
2077 if (code < 0)
2078 return code;
2079 if (count > MAX_GLYPH_PIECES)
2080 return_error(gs_error_limitcheck);
2081 for (i = 1; i < count; ++i) {
2082 code = gs_copy_glyph_options(font, glyphs[i], copied,
2083 (options & ~COPY_GLYPH_NO_OLD) | COPY_GLYPH_BY_INDEX);
2084 if (code < 0)
2085 return code;
2086 }
2087 /*
2088 * Because 'seac' accesses the Encoding of the font as well as the
2089 * glyphs, we have to copy the Encoding entries as well.
2090 */
2091 if (count == 1)
2092 return 0;
2093 switch (font->FontType) {
2094 case ft_encrypted:
2095 case ft_encrypted2:
2096 break;
2097 default:
2098 return 0;
2099 }
2100 #if 0 /* No need to add subglyphs to the Encoding because they always are
2101 taken from StandardEncoding (See the Type 1 spec about 'seac').
2102 Attempt to add them to the encoding can cause a conflict,
2103 if the encoding specifies different glyphs for these char codes
2104 (See the bug #687172). */
2105 {
2106 gs_copied_glyph_t *pcg;
2107 gs_glyph_data_t gdata;
2108 gs_char chars[2];
2109
2110 gdata.memory = font->memory;
2111 /* Since we just copied the glyph, copied_glyph_slot can't fail. */
2112 DISCARD(copied_glyph_slot(cf_data(copied), glyph, &pcg));
2113 gs_glyph_data_from_string(&gdata, pcg->gdata.data, pcg->gdata.size,
2114 NULL);
2115 code = gs_type1_piece_codes((gs_font_type1 *)font, &gdata, chars);
2116 if (code <= 0 || /* 0 is not possible here */
2117 (code = gs_copied_font_add_encoding(copied, chars[0], glyphs[1])) < 0 ||
2118 (code = gs_copied_font_add_encoding(copied, chars[1], glyphs[2])) < 0
2119 )
2120 return code;
2121 }
2122 #endif
2123 return 0;
2124 #undef MAX_GLYPH_PIECES
2125 }
2126
2127 /*
2128 * Add an Encoding entry to a copied font. The glyph need not already have
2129 * been copied.
2130 */
2131 int
gs_copied_font_add_encoding(gs_font * copied,gs_char chr,gs_glyph glyph)2132 gs_copied_font_add_encoding(gs_font *copied, gs_char chr, gs_glyph glyph)
2133 {
2134 gs_copied_font_data_t *const cfdata = cf_data(copied);
2135
2136 if (copied->procs.font_info != copied_font_info)
2137 return_error(gs_error_rangecheck);
2138 return cfdata->procs->add_encoding(copied, chr, glyph);
2139 }
2140
2141 /*
2142 * Copy all the glyphs and, if relevant, Encoding entries from a font. This
2143 * is equivalent to copying the glyphs and Encoding entries individually,
2144 * and returns errors under the same conditions.
2145 */
2146 int
gs_copy_font_complete(gs_font * font,gs_font * copied)2147 gs_copy_font_complete(gs_font *font, gs_font *copied)
2148 {
2149 int index, code = 0;
2150 gs_glyph_space_t space = GLYPH_SPACE_NAME;
2151 gs_glyph glyph;
2152
2153 /*
2154 * For Type 1 fonts and CIDFonts, enumerating the glyphs using
2155 * GLYPH_SPACE_NAME will cover all the glyphs. (The "names" of glyphs
2156 * in CIDFonts are CIDs, but that is not a problem.) For Type 42 fonts,
2157 * however, we have to copy by name once, so that we also copy the
2158 * name-to-GID mapping (the CharStrings dictionary in PostScript), and
2159 * then copy again by GID, to cover glyphs that don't have names.
2160 */
2161 for (;;) {
2162 for (index = 0;
2163 code >= 0 &&
2164 (font->procs.enumerate_glyph(font, &index, space, &glyph),
2165 index != 0);
2166 )
2167 code = gs_copy_glyph(font, glyph, copied);
2168 /* For Type 42 fonts, if we copied by name, now copy again by index. */
2169 if (space == GLYPH_SPACE_NAME && font->FontType == ft_TrueType)
2170 space = GLYPH_SPACE_INDEX;
2171 else
2172 break;
2173 }
2174 if (cf_data(copied)->Encoding != 0)
2175 for (index = 0; code >= 0 && index < 256; ++index) {
2176 glyph = font->procs.encode_char(font, (gs_char)index,
2177 GLYPH_SPACE_NAME);
2178 if (glyph != GS_NO_GLYPH)
2179 code = gs_copied_font_add_encoding(copied, (gs_char)index,
2180 glyph);
2181 }
2182 if (copied->FontType != ft_composite) {
2183 gs_font_base *bfont = (gs_font_base *)font;
2184 gs_font_base *bcopied = (gs_font_base *)copied;
2185
2186 bcopied->encoding_index = bfont->encoding_index;
2187 bcopied->nearest_encoding_index = bfont->nearest_encoding_index;
2188 }
2189 return code;
2190 }
2191
2192 /*
2193 * Check whether specified glyphs can be copied from another font.
2194 * It means that (1) fonts have same hinting parameters and
2195 * (2) font subsets for the specified glyph set don't include different
2196 * outlines or metrics. Possible returned values :
2197 * 0 (incompatible), 1 (compatible), < 0 (error)
2198 */
2199 int
gs_copied_can_copy_glyphs(const gs_font * cfont,const gs_font * ofont,gs_glyph * glyphs,int num_glyphs,int glyphs_step,bool check_hinting)2200 gs_copied_can_copy_glyphs(const gs_font *cfont, const gs_font *ofont,
2201 gs_glyph *glyphs, int num_glyphs, int glyphs_step,
2202 bool check_hinting)
2203 {
2204 int code = 0;
2205
2206 if (cfont == ofont)
2207 return 1;
2208 if (cfont->FontType != ofont->FontType)
2209 return 0;
2210 if (cfont->WMode != ofont->WMode)
2211 return 0;
2212 if (cfont->font_name.size == 0 || ofont->font_name.size == 0) {
2213 if (cfont->key_name.size != ofont->key_name.size ||
2214 memcmp(cfont->key_name.chars, ofont->key_name.chars,
2215 cfont->font_name.size))
2216 return 0; /* Don't allow to merge random fonts. */
2217 } else {
2218 if (cfont->font_name.size != ofont->font_name.size ||
2219 memcmp(cfont->font_name.chars, ofont->font_name.chars,
2220 cfont->font_name.size))
2221 return 0; /* Don't allow to merge random fonts. */
2222 }
2223 if (check_hinting) {
2224 switch(cfont->FontType) {
2225 case ft_encrypted:
2226 case ft_encrypted2:
2227 if (!same_type1_hinting((const gs_font_type1 *)cfont,
2228 (const gs_font_type1 *)ofont))
2229 return 0;
2230 code = 1;
2231 break;
2232 case ft_TrueType:
2233 code = same_type42_hinting((gs_font_type42 *)cfont,
2234 (gs_font_type42 *)ofont);
2235 break;
2236 case ft_CID_encrypted:
2237 if (!gs_is_CIDSystemInfo_compatible(
2238 gs_font_cid_system_info(cfont),
2239 gs_font_cid_system_info(ofont)))
2240 return 0;
2241 code = same_cid0_hinting((const gs_font_cid0 *)cfont,
2242 (const gs_font_cid0 *)ofont);
2243 break;
2244 case ft_CID_TrueType:
2245 if (!gs_is_CIDSystemInfo_compatible(
2246 gs_font_cid_system_info(cfont),
2247 gs_font_cid_system_info(ofont)))
2248 return 0;
2249 code = same_cid2_hinting((const gs_font_cid2 *)cfont,
2250 (const gs_font_cid2 *)ofont);
2251 break;
2252 default:
2253 return_error(gs_error_unregistered); /* Must not happen. */
2254 }
2255 if (code <= 0) /* an error or false */
2256 return code;
2257 }
2258 return compare_glyphs(cfont, ofont, glyphs, num_glyphs, glyphs_step, 0);
2259 }
2260
2261 /* Extension glyphs may be added to a font to resolve
2262 glyph name conflicts while conwerting a PDF Widths into Metrics.
2263 This function drops them before writing out an embedded font. */
2264 int
copied_drop_extension_glyphs(gs_font * copied)2265 copied_drop_extension_glyphs(gs_font *copied)
2266 {
2267 /* Note : This function drops 'used' flags for some glyphs
2268 and truncates glyph names. Can't use the font
2269 for outlining|rasterization|width after applying it.
2270 */
2271 gs_copied_font_data_t *const cfdata = cf_data(copied);
2272 uint gsize = cfdata->glyphs_size, i;
2273 const int sl = strlen(gx_extendeg_glyph_name_separator);
2274
2275 for (i = 0; i < gsize; i++) {
2276 gs_copied_glyph_t *pslot = &cfdata->glyphs[i];
2277 gs_copied_glyph_name_t *name;
2278 int l, j, k, i0;
2279
2280 if (!pslot->used)
2281 continue;
2282 name = &cfdata->names[i];
2283 l = name->str.size - sl, j;
2284
2285 for (j = 0; j < l; j ++)
2286 if (!memcmp(gx_extendeg_glyph_name_separator, name->str.data + j, sl))
2287 break;
2288 if (j >= l)
2289 continue;
2290 /* Found an extension name.
2291 Find the corresponding non-extended one. */
2292 i0 = i;
2293 for (k = 0; k < gsize; k++)
2294 if (cfdata->glyphs[k].used &&
2295 cfdata->names[k].str.size == j &&
2296 !memcmp(cfdata->names[k].str.data, name->str.data, j) &&
2297 !bytes_compare(pslot->gdata.data, pslot->gdata.size,
2298 cfdata->glyphs[k].gdata.data, cfdata->glyphs[k].gdata.size)) {
2299 i0 = k;
2300 break;
2301 }
2302 /* Truncate the extended glyph name. */
2303 cfdata->names[i0].str.size = j;
2304 /* Drop others with same prefix. */
2305 for (k = 0; k < gsize; k++)
2306 if (k != i0 && cfdata->glyphs[k].used &&
2307 cfdata->names[k].str.size >= j + sl &&
2308 !memcmp(cfdata->names[k].str.data, name->str.data, j) &&
2309 !memcmp(gx_extendeg_glyph_name_separator, name + j, sl) &&
2310 !bytes_compare(pslot->gdata.data, pslot->gdata.size,
2311 cfdata->glyphs[k].gdata.data, cfdata->glyphs[k].gdata.size))
2312 cfdata->glyphs[k].used = false;
2313 }
2314 return 0;
2315 }
2316