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