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