1 /* Copyright (C) 2001-2019 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.,  1305 Grant Avenue - Suite 200, Novato,
13    CA 94945, U.S.A., +1(415)492-9861, for further information.
14 */
15 
16 
17 /* Font creation utilities */
18 #include "memory_.h"
19 #include "string_.h"
20 #include "ghost.h"
21 #include "oper.h"
22 #include "gxfixed.h"
23 #include "gscencs.h"
24 #include "gsmatrix.h"
25 #include "gxdevice.h"
26 #include "gxfont.h"
27 #include "bfont.h"
28 #include "ialloc.h"
29 #include "idict.h"
30 #include "idparam.h"
31 #include "ilevel.h"
32 #include "iname.h"
33 #include "inamedef.h"		/* for inlining name_index */
34 #include "interp.h"		/* for initial_enter_name */
35 #include "ipacked.h"
36 #include "istruct.h"
37 #include "store.h"
38 #include "gsstate.h" /* for gs_currentcpsimode() */
39 /* Structure descriptor and GC procedures for font_data */
40 public_st_font_data();
41 static
CLEAR_MARKS_PROC(font_data_clear_marks)42 CLEAR_MARKS_PROC(font_data_clear_marks)
43 {
44     ref_struct_clear_marks(cmem, vptr, offset_of(font_data, u.type42.mru_sfnts_index)/*size*/, pstype);
45 }
46 static
ENUM_PTRS_BEGIN_PROC(font_data_enum_ptrs)47 ENUM_PTRS_BEGIN_PROC(font_data_enum_ptrs)
48 {
49     return ref_struct_enum_ptrs(mem, vptr, offset_of(font_data, u.type42.mru_sfnts_index)/*size*/, index, pep, pstype, gcst);
50 }
51 ENUM_PTRS_END_PROC
52 static
RELOC_PTRS_BEGIN(font_data_reloc_ptrs)53 RELOC_PTRS_BEGIN(font_data_reloc_ptrs)
54 {
55     ref_struct_reloc_ptrs(vptr, offset_of(font_data, u.type42.mru_sfnts_index)/*size*/, pstype, gcst);
56 }
57 RELOC_PTRS_END
58 
59 /* <string|name> <font_dict> .buildfont3 <string|name> <font> */
60 /* Build a type 3 (user-defined) font. */
61 static int
zbuildfont3(i_ctx_t * i_ctx_p)62 zbuildfont3(i_ctx_t *i_ctx_p)
63 {
64     os_ptr op = osp;
65     int code;
66     build_proc_refs build;
67     gs_font_base *pfont;
68 
69     check_type(*op, t_dictionary);
70     code = build_gs_font_procs(op, &build);
71     if (code < 0)
72         return code;
73     code = build_gs_simple_font(i_ctx_p, op, &pfont, ft_user_defined,
74                                 &st_gs_font_base, &build, bf_options_none);
75     if (code < 0)
76         return code;
77     return define_gs_font(i_ctx_p, (gs_font *) pfont);
78 }
79 
80 /* Encode a character. */
81 gs_glyph
zfont_encode_char(gs_font * pfont,gs_char chr,gs_glyph_space_t gspace)82 zfont_encode_char(gs_font *pfont, gs_char chr, gs_glyph_space_t gspace)
83 {
84     font_data *pdata = pfont_data(pfont);
85     const ref *pencoding = &pdata->Encoding;
86     ulong index = chr;	/* work around VAX widening bug */
87     ref cname;
88     int code = array_get(pfont->memory, pencoding, (long)index, &cname);
89 
90     if (code < 0 || !r_has_type(&cname, t_name))
91         return GS_NO_GLYPH;
92     if (pfont->FontType == ft_user_defined && r_type(&pdata->BuildGlyph) == t_null) {
93         ref nsref, tname;
94 
95         name_string_ref(pfont->memory, &cname, &nsref);
96         if (r_size(&nsref) == 7 &&
97             !memcmp(nsref.value.const_bytes, ".notdef", r_size(&nsref))) {
98             /* A special support for high level devices.
99                They need a glyph name but the font doesn't provide one
100                due to an instandard BuildChar.
101                Such fonts don't conform to PLRM section 5.3.7,
102                but we've got real examples that we want to handle (Bug 686982).
103                Construct a name here.
104                Low level devices don't pass here, because regular PS interpretation
105                doesn't need such names.
106             */
107             char buf[20];
108             int code;
109 
110             if (gspace == GLYPH_SPACE_NOGEN)
111                 return GS_NO_GLYPH;
112             gs_sprintf(buf, "j%ld", chr); /* 'j' is arbutrary. */
113             code = name_ref(pfont->memory, (const byte *)buf, strlen(buf), &tname, 1);
114             if (code < 0) {
115                 /* Can't propagate the error due to interface limitation,
116                    return with .notdef */
117             } else
118                 cname = tname;
119         }
120     }
121     return (gs_glyph)name_index(pfont->memory, &cname);
122 }
123 
124 /* Get the name of a glyph. */
125 static int
zfont_glyph_name(gs_font * font,gs_glyph index,gs_const_string * pstr)126 zfont_glyph_name(gs_font *font, gs_glyph index, gs_const_string *pstr)
127 {
128     ref nref, sref;
129 
130     if (index >= GS_MIN_CID_GLYPH) {	/* Fabricate a numeric name. */
131         char cid_name[sizeof(gs_glyph) * 3 + 1];
132         int code;
133 
134         gs_sprintf(cid_name, "%lu", (ulong) index);
135         code = name_ref(font->memory, (const byte *)cid_name, strlen(cid_name),
136                         &nref, 1);
137         if (code < 0)
138             return code;
139     } else
140         name_index_ref(font->memory, index, &nref);
141     name_string_ref(font->memory, &nref, &sref);
142     pstr->data = sref.value.const_bytes;
143     pstr->size = r_size(&sref);
144     return 0;
145 }
146 
147 static gs_char
gs_font_map_glyph_by_dict(const gs_memory_t * mem,const ref * map,gs_glyph glyph,ushort * u,unsigned int length)148 gs_font_map_glyph_by_dict(const gs_memory_t *mem, const ref *map, gs_glyph glyph, ushort *u, unsigned int length)
149 {
150     ref *v, n;
151     uchar *unicode_return = (uchar *)u;
152     if (glyph >= GS_MIN_CID_GLYPH) {
153         uint cid = glyph - GS_MIN_CID_GLYPH;
154 
155         if (dict_find_string(map, "CIDCount", &v) > 0) {
156             /* This is a CIDDEcoding resource. */
157             make_int(&n, cid / 256);
158             if (dict_find(map, &n, &v) > 0) {
159                 ref vv;
160 
161                 if (array_get(mem, v, cid % 256, &vv) == 0 && r_type(&vv) == t_integer) {
162                     if (v->value.intval > 65535) {
163                         if (length < 4)
164                             return 4;
165                         unicode_return[0] = v->value.intval >> 24;
166                         unicode_return[1] = (v->value.intval & 0x00FF0000) >> 16;
167                         unicode_return[2] = (v->value.intval & 0x0000FF00) >> 8;
168                         unicode_return[3] = v->value.intval & 0xFF;
169                         return 4;
170                     } else {
171                         if (length < 2)
172                             return 2;
173                         unicode_return[0] = v->value.intval >> 8;
174                         unicode_return[1] = v->value.intval & 0xFF;
175                         return 2;
176                     }
177                 }
178             }
179             return 0; /* Absent in the map. */
180         }
181         /* This is GlyphNames2Unicode dictionary. */
182         make_int(&n, cid);
183     } else
184         name_index_ref(mem, glyph, &n);
185      if (dict_find(map, &n, &v) > 0) {
186         if (r_has_type(v, t_string)) {
187             int l = r_size(v);
188 
189             if (length < l)
190                 return l;
191             memcpy(unicode_return, v->value.const_bytes, l);
192             return l;
193         }
194         if (r_type(v) == t_integer) {
195             if (v->value.intval > 65535) {
196                 if (length < 4)
197                     return 4;
198                 unicode_return[0] = v->value.intval >> 24;
199                 unicode_return[1] = (v->value.intval & 0x00FF0000) >> 16;
200                 unicode_return[2] = (v->value.intval & 0x0000FF00) >> 8;
201                 unicode_return[3] = v->value.intval & 0xFF;
202                 return 4;
203             } else {
204                 if (length < 2)
205                     return 2;
206                 unicode_return[0] = v->value.intval >> 8;
207                 unicode_return[1] = v->value.intval & 0xFF;
208                 return 2;
209             }
210         }
211     }
212     return 0; /* Absent in the map. */
213 }
214 
215 /* Get Unicode UTF-16 code for a glyph. */
216 int
gs_font_map_glyph_to_unicode(gs_font * font,gs_glyph glyph,int ch,ushort * u,unsigned int length)217 gs_font_map_glyph_to_unicode(gs_font *font, gs_glyph glyph, int ch, ushort *u, unsigned int length)
218 {
219     font_data *pdata = pfont_data(font);
220     const ref *UnicodeDecoding;
221     uchar *unicode_return = (uchar *)u;
222 
223     if (r_type(&pdata->GlyphNames2Unicode) == t_dictionary) {
224         int c = gs_font_map_glyph_by_dict(font->memory,
225                                               &pdata->GlyphNames2Unicode, glyph, u, length);
226 
227         if (c != 0)
228             return c;
229         if (ch != -1) { /* -1 indicates a CIDFont */
230             /* Its possible that we have a GlyphNames2Unicode dictionary
231              * which contains integers and Unicode values, rather than names
232              * and Unicode values. This happens if the input was PDF, the font
233              * has a ToUnicode Cmap, but no Encoding. In this case we need to
234              * use the character code as an index into the dictionary. Try that
235              * now before we fall back to the UnicodeDecoding.
236              */
237             ref *v, n;
238 
239             make_int(&n, ch);
240             if (dict_find(&pdata->GlyphNames2Unicode, &n, &v) > 0) {
241                 if (r_has_type(v, t_string)) {
242                     int l = r_size(v);
243 
244                     if (l > length)
245                         return l;
246 
247                     memcpy(unicode_return, v->value.const_bytes, l * sizeof(short));
248                     return l;
249                 }
250                 if (r_type(v) == t_integer) {
251                     if (v->value.intval > 65535) {
252                         if (length < 4)
253                             return 4;
254                         unicode_return[0] = v->value.intval >> 24;
255                         unicode_return[1] = (v->value.intval & 0x00FF0000) >> 16;
256                         unicode_return[2] = (v->value.intval & 0x0000FF00) >> 8;
257                         unicode_return[3] = v->value.intval & 0xFF;
258                         return 4;
259                     } else {
260                         if (length < 2)
261                             return 2;
262                         unicode_return[0] = v->value.intval >> 8;
263                         unicode_return[1] = v->value.intval & 0xFF;
264                         return 2;
265                     }
266                 }
267             }
268         }
269         /*
270          * Fall through, because test.ps for SF bug #529103 requres
271          * to examine both tables. Due to that the Unicode Decoding resource
272          * can't be a default value for FontInfo.GlyphNames2Unicode .
273          */
274     }
275     if (glyph <= GS_MIN_CID_GLYPH && glyph != GS_NO_GLYPH) {
276         UnicodeDecoding = zfont_get_to_unicode_map(font->dir);
277         if (UnicodeDecoding != NULL && r_type(UnicodeDecoding) == t_dictionary)
278             return gs_font_map_glyph_by_dict(font->memory, UnicodeDecoding, glyph, u, length);
279     }
280     return 0; /* No map. */
281 }
282 
283 /* ------ Initialization procedure ------ */
284 
285 const op_def zbfont_op_defs[] =
286 {
287     {"2.buildfont3", zbuildfont3},
288     op_def_end(0)
289 };
290 
291 /* ------ Subroutines ------ */
292 
293 /* Convert strings to executable names for build_proc_refs. */
294 int
build_proc_name_refs(const gs_memory_t * mem,build_proc_refs * pbuild,const char * bcstr,const char * bgstr)295 build_proc_name_refs(const gs_memory_t *mem, build_proc_refs * pbuild,
296                      const char *bcstr, const char *bgstr)
297 {
298     int code;
299 
300     if (!bcstr)
301         make_null(&pbuild->BuildChar);
302     else {
303         if ((code = name_ref(mem, (const byte *)bcstr,
304                              strlen(bcstr), &pbuild->BuildChar, 0)) < 0)
305             return code;
306         r_set_attrs(&pbuild->BuildChar, a_executable);
307     }
308     if (!bgstr)
309         make_null(&pbuild->BuildGlyph);
310     else {
311         if ((code = name_ref(mem, (const byte *)bgstr,
312                              strlen(bgstr), &pbuild->BuildGlyph, 0)) < 0)
313             return code;
314         r_set_attrs(&pbuild->BuildGlyph, a_executable);
315     }
316     return 0;
317 }
318 
319 /* Get the BuildChar and/or BuildGlyph routines from a (base) font. */
320 int
build_gs_font_procs(os_ptr op,build_proc_refs * pbuild)321 build_gs_font_procs(os_ptr op, build_proc_refs * pbuild)
322 {
323     int ccode, gcode;
324     ref *pBuildChar;
325     ref *pBuildGlyph;
326 
327     check_type(*op, t_dictionary);
328     ccode = dict_find_string(op, "BuildChar", &pBuildChar);
329     gcode = dict_find_string(op, "BuildGlyph", &pBuildGlyph);
330     if (ccode <= 0) {
331         if (gcode <= 0)
332             return_error(gs_error_invalidfont);
333         make_null(&pbuild->BuildChar);
334     } else {
335         check_proc(*pBuildChar);
336         pbuild->BuildChar = *pBuildChar;
337     }
338     if (gcode <= 0)
339         make_null(&pbuild->BuildGlyph);
340     else {
341         check_proc(*pBuildGlyph);
342         pbuild->BuildGlyph = *pBuildGlyph;
343     }
344     return 0;
345 }
346 
font_with_same_UID_and_another_metrics(const gs_font * pfont0,const gs_font * pfont1)347 static int font_with_same_UID_and_another_metrics(const gs_font *pfont0, const gs_font *pfont1)
348 {
349     const gs_font_base *pbfont0 = (const gs_font_base *)pfont0;
350     const gs_font_base *pbfont1 = (const gs_font_base *)pfont1;
351 
352     if (uid_equal(&pbfont0->UID, &pbfont1->UID)) {
353         const ref *pfdict0 = &pfont_data(gs_font_parent(pbfont0))->dict;
354         const ref *pfdict1 = &pfont_data(gs_font_parent(pbfont1))->dict;
355         ref *pmdict0, *pmdict1;
356 
357         if (pbfont0->WMode || dict_find_string(pfdict0, "Metrics", &pmdict0) <= 0)
358             pmdict0 = NULL;
359         if (pbfont1->WMode || dict_find_string(pfdict1, "Metrics", &pmdict1) <= 0)
360             pmdict1 = NULL;
361         if (!pmdict0 != !pmdict1)
362             return 1;
363         if (pmdict0 != NULL && !obj_eq(pfont0->memory, pmdict0, pmdict1))
364             return 1;
365         if (!pbfont0->WMode || dict_find_string(pfdict0, "Metrics2", &pmdict0) <= 0)
366             pmdict0 = NULL;
367         if (!pbfont0->WMode || dict_find_string(pfdict1, "Metrics2", &pmdict1) <= 0)
368             pmdict1 = NULL;
369         if (!pmdict0 != !pmdict1)
370             return 1;
371         if (pmdict0 != NULL && !obj_eq(pfont0->memory, pmdict0, pmdict1))
372             return 1;
373     }
374     return 0;
375 }
376 
377 /* Do the common work for building a primitive font -- one whose execution */
378 /* algorithm is implemented in C (Type 1, Type 2, Type 4, or Type 42). */
379 /* The caller guarantees that *op is a dictionary. */
380 int
build_gs_primitive_font(i_ctx_t * i_ctx_p,os_ptr op,gs_font_base ** ppfont,font_type ftype,gs_memory_type_ptr_t pstype,const build_proc_refs * pbuild,build_font_options_t options)381 build_gs_primitive_font(i_ctx_t *i_ctx_p, os_ptr op, gs_font_base ** ppfont,
382                         font_type ftype, gs_memory_type_ptr_t pstype,
383                         const build_proc_refs * pbuild,
384                         build_font_options_t options)
385 {
386     ref *pcharstrings = 0;
387     ref CharStrings;
388     gs_font_base *pfont;
389     font_data *pdata;
390     int code;
391 
392     if (dict_find_string(op, "CharStrings", &pcharstrings) <= 0) {
393         if (!(options & bf_CharStrings_optional))
394             return_error(gs_error_invalidfont);
395     } else {
396         ref *ignore;
397 
398         if (!r_has_type(pcharstrings, t_dictionary))
399             return_error(gs_error_invalidfont);
400         if ((options & bf_notdef_required) != 0 &&
401             dict_find_string(pcharstrings, ".notdef", &ignore) <= 0
402             )
403             return_error(gs_error_invalidfont);
404         /*
405          * Since build_gs_simple_font may resize the dictionary and cause
406          * pointers to become invalid, save CharStrings.
407          */
408         CharStrings = *pcharstrings;
409     }
410     code = build_gs_outline_font(i_ctx_p, op, ppfont, ftype, pstype, pbuild,
411                                  options, build_gs_simple_font);
412     if (code != 0)
413         return code;
414     pfont = *ppfont;
415     pdata = pfont_data(pfont);
416     if (pcharstrings)
417         ref_assign(&pdata->CharStrings, &CharStrings);
418     else
419         make_null(&pdata->CharStrings);
420     /* Check that the UniqueIDs match.  This is part of the */
421     /* Adobe protection scheme, but we may as well emulate it. */
422     if (uid_is_valid(&pfont->UID) &&
423         !dict_check_uid_param(op, &pfont->UID)
424         )
425         uid_set_invalid(&pfont->UID);
426     if (uid_is_valid(&pfont->UID)) {
427         const gs_font *pfont0 = (const gs_font *)pfont;
428 
429         code = gs_font_find_similar(ifont_dir, &pfont0,
430                        font_with_same_UID_and_another_metrics);
431         if (code < 0)
432             return code; /* Must not happen. */
433         if (code)
434             uid_set_invalid(&pfont->UID);
435     }
436     return 0;
437 }
438 
439 /* Build a FDArray entry for a CIDFontType 0 font. */
440 /* Note that as of Adobe PostScript version 3011, this may be either */
441 /* a Type 1 or Type 2 font. */
442 static int
build_FDArray_sub_font(i_ctx_t * i_ctx_p,ref * op,gs_font_base ** ppfont,font_type ftype,gs_memory_type_ptr_t pstype,const build_proc_refs * pbuild,build_font_options_t ignore_options)443 build_FDArray_sub_font(i_ctx_t *i_ctx_p, ref *op,
444                        gs_font_base **ppfont,
445                        font_type ftype, gs_memory_type_ptr_t pstype,
446                        const build_proc_refs * pbuild,
447                        build_font_options_t ignore_options)
448 {
449     gs_font *pfont;
450     int code = build_gs_sub_font(i_ctx_p, op, &pfont, ftype, pstype, pbuild,
451                                  NULL, op);
452 
453     if (code >= 0)
454         *ppfont = (gs_font_base *)pfont;
455     return code;
456 }
457 int
build_gs_FDArray_font(i_ctx_t * i_ctx_p,ref * op,gs_font_base ** ppfont,font_type ftype,gs_memory_type_ptr_t pstype,const build_proc_refs * pbuild)458 build_gs_FDArray_font(i_ctx_t *i_ctx_p, ref *op,
459                       gs_font_base **ppfont,
460                       font_type ftype, gs_memory_type_ptr_t pstype,
461                       const build_proc_refs * pbuild)
462 {
463     gs_font_base *pfont;
464     font_data *pdata;
465     int code = build_gs_outline_font(i_ctx_p, op, &pfont, ftype, pstype,
466                                      pbuild, bf_options_none,
467                                      build_FDArray_sub_font);
468     static const double bbox[4] = { 0, 0, 0, 0 };
469     gs_uid uid;
470 
471     if (code < 0)
472         return code;
473     pdata = pfont_data(pfont);
474     /* Fill in members normally set by build_gs_primitive_font. */
475     make_null(&pdata->CharStrings);
476     /* Fill in members normally set by build_gs_simple_font. */
477     uid_set_invalid(&uid);
478     init_gs_simple_font(pfont, bbox, &uid);
479     pfont->encoding_index = ENCODING_INDEX_UNKNOWN;
480     pfont->nearest_encoding_index = ENCODING_INDEX_UNKNOWN;
481     /* Fill in members normally set by build_gs_font. */
482     pfont->key_name = pfont->font_name;
483     *ppfont = pfont;
484     return 0;
485 }
486 
487 /* Do the common work for building an outline font -- a non-composite font */
488 /* for which PaintType and StrokeWidth are meaningful. */
489 /* The caller guarantees that *op is a dictionary. */
490 int
build_gs_outline_font(i_ctx_t * i_ctx_p,os_ptr op,gs_font_base ** ppfont,font_type ftype,gs_memory_type_ptr_t pstype,const build_proc_refs * pbuild,build_font_options_t options,build_base_font_proc_t build_base_font)491 build_gs_outline_font(i_ctx_t *i_ctx_p, os_ptr op, gs_font_base ** ppfont,
492                       font_type ftype, gs_memory_type_ptr_t pstype,
493                       const build_proc_refs * pbuild,
494                       build_font_options_t options,
495                       build_base_font_proc_t build_base_font)
496 {
497     int painttype;
498     float strokewidth;
499     gs_font_base *pfont;
500     int code = dict_int_param(op, "PaintType", 0, 3, 0, &painttype);
501 
502     if (code < 0)
503         return code;
504     code = dict_float_param(op, "StrokeWidth", 0.0, &strokewidth);
505     if (code < 0)
506         return code;
507     code = build_base_font(i_ctx_p, op, ppfont, ftype, pstype, pbuild,
508                            options);
509     if (code != 0)
510         return code;
511     pfont = *ppfont;
512     pfont->PaintType = painttype;
513     pfont->StrokeWidth = strokewidth;
514     return 0;
515 }
516 
517 void
get_GlyphNames2Unicode(i_ctx_t * i_ctx_p,gs_font * pfont,ref * pdref)518 get_GlyphNames2Unicode(i_ctx_t *i_ctx_p, gs_font *pfont, ref *pdref)
519 {
520     ref *pfontinfo = NULL, *g2u = NULL;
521     font_data *pdata;
522 
523     if (dict_find_string(pdref, "FontInfo", &pfontinfo) <= 0 ||
524             !r_has_type(pfontinfo, t_dictionary) ||
525             dict_find_string(pfontinfo, "GlyphNames2Unicode", &g2u) <= 0 ||
526             !r_has_type(pfontinfo, t_dictionary))
527         return;
528     /*
529      * Since build_gs_font may resize the dictionary and cause
530      * pointers to become invalid, save Glyph2Unicode
531      */
532     pdata = pfont_data(pfont);
533     ref_assign_new(&pdata->GlyphNames2Unicode, g2u);
534 }
535 
536 /* Do the common work for building a font of any non-composite FontType. */
537 /* The caller guarantees that *op is a dictionary. */
538 int
build_gs_simple_font(i_ctx_t * i_ctx_p,os_ptr op,gs_font_base ** ppfont,font_type ftype,gs_memory_type_ptr_t pstype,const build_proc_refs * pbuild,build_font_options_t options)539 build_gs_simple_font(i_ctx_t *i_ctx_p, os_ptr op, gs_font_base ** ppfont,
540                      font_type ftype, gs_memory_type_ptr_t pstype,
541                      const build_proc_refs * pbuild,
542                      build_font_options_t options)
543 {
544     double bbox[4];
545     gs_uid uid;
546     int code;
547     gs_font_base *pfont;
548     uint space = ialloc_space(idmemory);
549 
550     code = font_bbox_param(imemory, op, bbox);
551     if (code < 0)
552         return code;
553     /*
554      * Make sure that we allocate uid
555      * in the same VM as the font dictionary
556      * (see build_gs_sub_font).
557      */
558     ialloc_set_space(idmemory, r_space(op));
559     code = dict_uid_param(op, &uid, 0, imemory, i_ctx_p);
560     ialloc_set_space(idmemory, space);
561     if (code < 0)
562         return code;
563     if ((options & bf_UniqueID_ignored) && uid_is_UniqueID(&uid))
564         uid_set_invalid(&uid);
565     code = build_gs_font(i_ctx_p, op, (gs_font **) ppfont, ftype, pstype,
566                          pbuild, options);
567     if (code != 0)		/* invalid or scaled font */
568         return code;
569     pfont = *ppfont;
570     pfont->procs.init_fstack = gs_default_init_fstack;
571     pfont->procs.define_font = gs_no_define_font;
572     pfont->procs.decode_glyph = gs_font_map_glyph_to_unicode;
573     pfont->procs.make_font = zbase_make_font;
574     pfont->procs.next_char_glyph = gs_default_next_char_glyph;
575     pfont->FAPI = 0;
576     pfont->FAPI_font_data = 0;
577     init_gs_simple_font(pfont, bbox, &uid);
578     lookup_gs_simple_font_encoding(pfont);
579     get_GlyphNames2Unicode(i_ctx_p, (gs_font *)pfont, op);
580     return 0;
581 }
582 
583 /* Initialize the FontBBox and UID of a non-composite font. */
584 void
init_gs_simple_font(gs_font_base * pfont,const double bbox[4],const gs_uid * puid)585 init_gs_simple_font(gs_font_base *pfont, const double bbox[4],
586                     const gs_uid *puid)
587 {
588     pfont->FontBBox.p.x = bbox[0];
589     pfont->FontBBox.p.y = bbox[1];
590     pfont->FontBBox.q.x = bbox[2];
591     pfont->FontBBox.q.y = bbox[3];
592     pfont->UID = *puid;
593 }
594 
595 /* Compare the encoding of a simple font with the registered encodings. */
596 void
lookup_gs_simple_font_encoding(gs_font_base * pfont)597 lookup_gs_simple_font_encoding(gs_font_base * pfont)
598 {
599     const ref *pfe = &pfont_data(pfont)->Encoding;
600     int index = -1;
601 
602     pfont->encoding_index = index;
603     if (r_type(pfe) == t_array && r_size(pfe) <= 256) {
604         /* Look for an encoding that's "close". */
605         uint esize = r_size(pfe);
606         int near_index = -1;
607         uint best = esize / 3;	/* must match at least this many */
608         gs_const_string fstrs[256];
609         int i;
610 
611         /* Get the string names of the glyphs in the font's Encoding. */
612         for (i = 0; i < esize; ++i) {
613             ref fchar;
614 
615             if (array_get(pfont->memory, pfe, (long)i, &fchar) < 0 ||
616                 !r_has_type(&fchar, t_name)
617                 )
618                 fstrs[i].data = 0, fstrs[i].size = 0;
619             else {
620                 ref nsref;
621 
622                 name_string_ref(pfont->memory, &fchar, &nsref);
623                 fstrs[i].data = nsref.value.const_bytes;
624                 fstrs[i].size = r_size(&nsref);
625             }
626         }
627         /* Compare them against the known encodings. */
628         for (index = 0; index < NUM_KNOWN_REAL_ENCODINGS; ++index) {
629             uint match = esize;
630 
631             for (i = esize; --i >= 0;) {
632                 gs_const_string rstr;
633 
634                 gs_c_glyph_name(gs_c_known_encode((gs_char)i, index), &rstr);
635                 if (rstr.size == fstrs[i].size &&
636                     !memcmp(rstr.data, fstrs[i].data, rstr.size)
637                     )
638                     continue;
639                 if (--match <= best)
640                     break;
641             }
642             if (match > best) {
643                 best = match;
644                 near_index = index;
645                 /* If we have a perfect match, stop now. */
646                 if (best == esize)
647                     break;
648             }
649         }
650         index = near_index;
651         if (best == esize)
652             pfont->encoding_index = index;
653     }
654     pfont->nearest_encoding_index = index;
655 }
656 
657 /* Get FontMatrix and FontName parameters. */
658 static int
sub_font_params(gs_memory_t * mem,const ref * op,gs_matrix * pmat,gs_matrix * pomat,ref * pfname)659 sub_font_params(gs_memory_t *mem, const ref *op, gs_matrix *pmat, gs_matrix *pomat, ref *pfname)
660 {
661     ref *pmatrix, *pfontname, *pfontstyle, *porigfont, *pfontinfo;
662 
663     if (dict_find_string(op, "FontMatrix", &pmatrix) <= 0 ||
664         read_matrix(mem, pmatrix, pmat) < 0
665         )
666         return_error(gs_error_invalidfont);
667     if (dict_find_string(op, "OrigFont", &porigfont) <= 0)
668         porigfont = NULL;
669     if (porigfont != NULL && !r_has_type(porigfont, t_dictionary))
670         return_error(gs_error_typecheck);
671 
672     if (pomat!= NULL) {
673         if (porigfont == NULL ||
674             dict_find_string(porigfont, "FontMatrix", &pmatrix) <= 0 ||
675             read_matrix(mem, pmatrix, pomat) < 0
676             )
677             memset(pomat, 0, sizeof(*pomat));
678     }
679     /* Use the FontInfo/OrigFontName key preferrentially (created by MS PSCRIPT driver) */
680     if ((dict_find_string((porigfont != NULL ? porigfont : op), "FontInfo", &pfontinfo) > 0) &&
681         r_has_type(pfontinfo, t_dictionary) &&
682         (dict_find_string(pfontinfo, "OrigFontName", &pfontname) > 0) && (r_has_type(pfontname, t_name) || r_has_type(pfontname, t_string))) {
683         if ((dict_find_string(pfontinfo, "OrigFontStyle", &pfontstyle) > 0) && (r_has_type(pfontname, t_name) || r_has_type(pfontname, t_string)) &&
684                 r_size(pfontstyle) > 0) {
685             const byte *tmpStr1 = pfontname->value.const_bytes;
686             const byte *tmpStr2 = pfontstyle->value.const_bytes;
687             int fssize1 = r_size(pfontname), fssize2 = r_size(pfontstyle), fssize = fssize1 + fssize2 + 1;
688             byte *sfname = gs_alloc_string(mem, fssize, "sub_font_params");
689 
690             if (sfname == NULL)
691                 return_error(gs_error_VMerror);
692             memcpy(sfname, tmpStr1, fssize1);
693             sfname[fssize1]=',' ;
694             memcpy(sfname + fssize1 + 1, tmpStr2, fssize2);
695             make_string(pfname, a_readonly, fssize, sfname);
696         } else
697             get_font_name(mem, pfname, pfontname);
698     } else if (dict_find_string((porigfont != NULL ? porigfont : op), ".Alias", &pfontname) > 0) {
699         /* If we emulate the font, we want the requested name rather than a substitute. */
700         get_font_name(mem, pfname, pfontname);
701     } else if (dict_find_string((porigfont != NULL ? porigfont : op), "FontName", &pfontname) > 0) {
702         get_font_name(mem, pfname, pfontname);
703     } else
704         make_empty_string(pfname, a_readonly);
705     return 0;
706 }
707 
708 /* Do the common work for building a font of any FontType. */
709 /* The caller guarantees that *op is a dictionary. */
710 /* op[-1] must be the key under which the font is being registered */
711 /* in FontDirectory, normally a name or string. */
712 /* Return 0 for a new font, 1 for a font made by makefont or scalefont, */
713 /* or a negative error code. */
714 int
build_gs_font(i_ctx_t * i_ctx_p,os_ptr op,gs_font ** ppfont,font_type ftype,gs_memory_type_ptr_t pstype,const build_proc_refs * pbuild,build_font_options_t options)715 build_gs_font(i_ctx_t *i_ctx_p, os_ptr op, gs_font ** ppfont, font_type ftype,
716               gs_memory_type_ptr_t pstype, const build_proc_refs * pbuild,
717               build_font_options_t options)
718 {
719     ref kname;			/* t_string */
720     ref *pftype;
721     ref *pencoding = 0;
722     bool bitmapwidths;
723     int exactsize, inbetweensize, transformedchar;
724     int wmode;
725     int code;
726     gs_font *pfont;
727     ref *pfid;
728     ref *aop = dict_access_ref(op);
729     bool cpsi_mode = gs_currentcpsimode(imemory);
730 
731     get_font_name(imemory, &kname, op - 1);
732     if (dict_find_string(op, "FontType", &pftype) <= 0 ||
733         !r_has_type(pftype, t_integer) ||
734         pftype->value.intval != (int)ftype
735         )
736         return_error(gs_error_invalidfont);
737     if (dict_find_string(op, "Encoding", &pencoding) <= 0) {
738         if (!(options & bf_Encoding_optional))
739             return_error(gs_error_invalidfont);
740         pencoding = 0;
741     } else {
742         if (!r_is_array(pencoding))
743             return_error(gs_error_invalidfont);
744     }
745     if (pencoding) {   /* observed Adobe behavior */
746         int count = r_size(pencoding);
747         int type = ftype ? t_name : t_integer;
748         bool fixit = false;
749 
750         while (count--) {
751            ref r;
752            if ((code = array_get(imemory, pencoding, count, &r)) < 0 ||
753              !(r_has_type(&r, type) || r_has_type(&r, t_null))) {
754                if (!cpsi_mode && ftype == ft_user_defined) {
755                    if (code < 0 || r_has_type(&r, t_null)) {
756                        return_error(gs_error_typecheck);
757                    }
758                    fixit = true;
759                    break;
760                }
761                else {
762                    return_error(gs_error_typecheck);
763                }
764            }
765         }
766 
767         /* For at least Type 3 fonts, Adobe Distiller will "fix" an Encoding array, as in, for example
768          * Bug 692681 where the arrays contain integers rather than names. Once the font is instantiated
769          * the integers have been converted to names.
770          * It is preferable to to this manipulation here, rather than in Postscript, because we are less
771          * restricted by read-only attributes and VM save levels.
772          */
773         if (fixit) {
774             ref penc;
775             uint size = 0;
776             char buf[32], *bptr;
777             avm_space curglob = ialloc_space(idmemory);
778             avm_space useglob = r_is_local(pencoding) ? avm_local : avm_global;
779 
780             ialloc_set_space(idmemory, useglob);
781 
782             count = r_size(pencoding);
783             if ((code = ialloc_ref_array(&penc, (r_type_attrs(pencoding) & a_readonly), count, "build_gs_font")) < 0)
784                  return code;
785 
786             while (count--) {
787                ref r;
788                if (array_get(imemory, pencoding, count, &r) < 0){
789                    return_error(gs_error_typecheck);
790                }
791                /* For type 3, we know the Encoding entries must be names */
792                if (r_has_type(&r, t_name)){
793                    ref_assign(&(penc.value.refs[count]), &r);
794                }
795                else {
796 
797                    if ((code = obj_cvs(imemory, &r, (byte *)buf, 32, &size, (const byte **)(&bptr))) < 0) {
798                        return(code);
799                    }
800                    if ((code = name_ref(imemory, (const byte *)bptr, size, &r, true)) < 0)
801                         return code;
802                    ref_assign(&(penc.value.refs[count]), &r);
803                }
804             }
805 
806             if ((code = dict_put_string(osp, "Encoding", &penc, NULL)) < 0)
807                return code;
808             ialloc_set_space(idmemory, curglob);
809         }
810     }
811     if ((code = dict_int_param(op, "WMode", 0, 1, 0, &wmode)) < 0 ||
812         (code = dict_bool_param(op, "BitmapWidths", false, &bitmapwidths)) < 0 ||
813         (code = dict_int_param(op, "ExactSize", 0, 2, fbit_use_bitmaps, &exactsize)) < 0 ||
814         (code = dict_int_param(op, "InBetweenSize", 0, 2, fbit_use_outlines, &inbetweensize)) < 0 ||
815         (code = dict_int_param(op, "TransformedChar", 0, 2, fbit_use_outlines, &transformedchar)) < 0
816         )
817         return code;
818     code = dict_find_string(op, "FID", &pfid);
819     if (code > 0 && r_has_type(pfid, t_fontID)) { /* silently ignore invalid FID per CET 13-05.ps */
820         /*
821          * If this font has a FID entry already, it might be a scaled font
822          * made by makefont or scalefont; in a Level 2 environment, it might
823          * be an existing font being registered under a second name, or a
824          * re-encoded font (which was invalid in Level 1, but dvips did it
825          * anyway).
826          */
827         pfont = r_ptr(pfid, gs_font);
828         /*
829          * If the following condition is false this is a re-encoded font,
830          * or some other questionable situation in which the FID
831          * was preserved.  Pretend the FID wasn't there.
832          */
833         if (obj_eq(pfont->memory, pfont_dict(pfont), op)) {
834             if (pfont->base == pfont) {	/* original font */
835                 if (!level2_enabled)
836                     return_error(gs_error_invalidfont);
837                 *ppfont = pfont;
838                 return 1;
839             } else {		/* This was made by makefont or scalefont. */
840                 /* Just insert the new name. */
841                 gs_matrix mat;
842                 ref fname;			/* t_string */
843 
844                 code = sub_font_params(imemory, op, &mat, NULL, &fname);
845                 if (code < 0)
846                     return code;
847                 code = 1;
848                 copy_font_name(&pfont->font_name, &fname);
849                 goto set_name;
850             }
851         }
852     }
853     /* This is a new font. */
854     if (!r_has_attr(aop, a_write))
855         return_error(gs_error_invalidaccess);
856     {
857         ref encoding;
858 
859         /*
860          * Since add_FID may resize the dictionary and cause
861          * pencoding to become invalid, save the Encoding.
862          */
863         if (pencoding) {
864             encoding = *pencoding;
865             pencoding = &encoding;
866         }
867         code = build_gs_sub_font(i_ctx_p, op, &pfont, ftype, pstype,
868                                  pbuild, pencoding, op);
869         if (code < 0)
870             return code;
871     }
872     pfont->BitmapWidths = bitmapwidths;
873     pfont->ExactSize = (fbit_type)exactsize;
874     pfont->InBetweenSize = (fbit_type)inbetweensize;
875     pfont->TransformedChar = (fbit_type)transformedchar;
876     pfont->WMode = wmode;
877     pfont->procs.font_info = zfont_info;
878     code = 0;
879 set_name:
880     copy_font_name(&pfont->key_name, &kname);
881     *ppfont = pfont;
882     return code;
883 }
884 
885 /* Create a sub-font -- a font or an entry in the FDArray of a CIDFontType 0 */
886 /* font.  Default BitmapWidths, ExactSize, InBetweenSize, TransformedChar, */
887 /* and WMode; do not fill in key_name. */
888 /* The caller guarantees that *op is a dictionary. */
889 int
build_gs_sub_font(i_ctx_t * i_ctx_p,const ref * op,gs_font ** ppfont,font_type ftype,gs_memory_type_ptr_t pstype,const build_proc_refs * pbuild,const ref * pencoding,ref * fid_op)890 build_gs_sub_font(i_ctx_t *i_ctx_p, const ref *op, gs_font **ppfont,
891                   font_type ftype, gs_memory_type_ptr_t pstype,
892                   const build_proc_refs * pbuild, const ref *pencoding,
893                   ref *fid_op)
894 {
895     gs_matrix mat, omat;
896     ref fname;			/* t_string */
897     gs_font *pfont;
898     font_data *pdata;
899     /*
900      * Make sure that we allocate the font data
901      * in the same VM as the font dictionary.
902      */
903     uint space = ialloc_space(idmemory);
904     int code = sub_font_params(imemory, op, &mat, &omat, &fname);
905 
906     if (code < 0)
907         return code;
908     ialloc_set_space(idmemory, r_space(op));
909     pfont = gs_font_alloc(imemory, pstype, &gs_font_procs_default, NULL,
910                           "buildfont(font)");
911     pdata = ialloc_struct(font_data, &st_font_data,
912                           "buildfont(data)");
913     if (pfont == 0 || pdata == 0)
914         code = gs_note_error(gs_error_VMerror);
915     else if (fid_op)
916         code = add_FID(i_ctx_p, fid_op, pfont, iimemory);
917     if (code < 0) {
918         ifree_object(pdata, "buildfont(data)");
919         ifree_object(pfont, "buildfont(font)");
920         ialloc_set_space(idmemory, space);
921         return code;
922     }
923     refset_null((ref *) pdata, sizeof(font_data) / sizeof(ref));
924     ref_assign_new(&pdata->dict, op);
925     ref_assign_new(&pdata->BuildChar, &pbuild->BuildChar);
926     ref_assign_new(&pdata->BuildGlyph, &pbuild->BuildGlyph);
927     if (pencoding)
928         ref_assign_new(&pdata->Encoding, pencoding);
929     pfont->client_data = pdata;
930     pfont->FontType = ftype;
931     pfont->FontMatrix = mat;
932     pfont->orig_FontMatrix = omat;
933     pfont->BitmapWidths = false;
934     pfont->ExactSize = fbit_use_bitmaps;
935     pfont->InBetweenSize = fbit_use_outlines;
936     pfont->TransformedChar = fbit_use_outlines;
937     pfont->WMode = 0;
938     pfont->procs.encode_char = zfont_encode_char;
939     pfont->procs.glyph_name = zfont_glyph_name;
940     ialloc_set_space(idmemory, space);
941     copy_font_name(&pfont->font_name, &fname);
942     *ppfont = pfont;
943     return 0;
944 }
945 
946 /* Get the string corresponding to a font name. */
947 /* If the font name isn't a name or a string, return an empty string. */
948 void
get_font_name(const gs_memory_t * mem,ref * pfname,const ref * op)949 get_font_name(const gs_memory_t *mem, ref * pfname, const ref * op)
950 {
951     switch (r_type(op)) {
952         case t_string:
953             *pfname = *op;
954             break;
955         case t_name:
956             name_string_ref(mem, op, pfname);
957             break;
958         default:
959             /* This is weird, but legal.... */
960             make_empty_string(pfname, a_readonly);
961     }
962 }
963 
964 /* Copy a font name into the gs_font structure. */
965 void
copy_font_name(gs_font_name * pfstr,const ref * pfname)966 copy_font_name(gs_font_name * pfstr, const ref * pfname)
967 {
968     uint size = r_size(pfname);
969 
970     if (size > gs_font_name_max)
971         size = gs_font_name_max;
972     memcpy(&pfstr->chars[0], pfname->value.const_bytes, size);
973     /* Following is only for debugging printout. */
974     pfstr->chars[size] = 0;
975     pfstr->size = size;
976 }
977 
978 /* Finish building a font, by calling gs_definefont if needed. */
979 int
define_gs_font(i_ctx_t * i_ctx_p,gs_font * pfont)980 define_gs_font(i_ctx_t *i_ctx_p, gs_font * pfont)
981 {
982     return (pfont->base == pfont && pfont->dir == 0 ?
983             /* i.e., unregistered original font */
984             gs_definefont(ifont_dir, pfont) :
985             0);
986 }
987