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