1 /* Copyright (C) 2001-2012 Artifex Software, Inc.
2 All Rights Reserved.
3
4 This software is provided AS-IS with no warranty, either express or
5 implied.
6
7 This software is distributed under license and may not be copied,
8 modified or distributed except as expressly authorized under the terms
9 of the license contained in the file LICENSE in this distribution.
10
11 Refer to licensing information at http://www.artifex.com or contact
12 Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael,
13 CA 94903, U.S.A., +1(415)492-9861, for further information.
14 */
15
16
17 /* CIDFontType 0 operators */
18 #include "memory_.h"
19 #include "ghost.h"
20 #include "oper.h"
21 #include "gsmatrix.h"
22 #include "gsccode.h"
23 #include "gsstruct.h"
24 #include "gxfcid.h"
25 #include "gxfont1.h"
26 #include "gxalloc.h" /* for gs_ref_memory_t */
27 #include "stream.h" /* for files.h */
28 #include "bfont.h"
29 #include "files.h"
30 #include "ichar.h"
31 #include "ichar1.h"
32 #include "icid.h"
33 #include "idict.h"
34 #include "idparam.h"
35 #include "ifcid.h"
36 #include "ifont1.h"
37 #include "ifont2.h"
38 #include "ifont42.h"
39 #include "store.h"
40 #include "imain.h"
41 #include "iapi.h"
42 #include "iminst.h"
43
44 /* Type 1 font procedures (defined in zchar1.c) */
45 font_proc_glyph_outline(zcharstring_glyph_outline);
46
47 /* ---------------- CIDFontType 0 (FontType 9) ---------------- */
48
49 /* ------ Accessing ------ */
50
51 /* Parse a multi-byte integer from a string. */
52 static int
get_index(gs_glyph_data_t * pgd,int count,ulong * pval)53 get_index(gs_glyph_data_t *pgd, int count, ulong *pval)
54 {
55 int i;
56
57 if (pgd->bits.size < count)
58 return_error(e_rangecheck);
59 *pval = 0;
60 for (i = 0; i < count; ++i)
61 *pval = (*pval << 8) + pgd->bits.data[i];
62 pgd->bits.data += count;
63 pgd->bits.size -= count;
64 return 0;
65 }
66
67 /* Get bytes from GlyphData or DataSource. */
68 static int
cid0_read_bytes(gs_font_cid0 * pfont,ulong base,uint count,byte * buf,gs_glyph_data_t * pgd)69 cid0_read_bytes(gs_font_cid0 *pfont, ulong base, uint count, byte *buf,
70 gs_glyph_data_t *pgd)
71 {
72 const font_data *pfdata = pfont_data(pfont);
73 byte *data = buf;
74 gs_font *gdfont = 0; /* pfont if newly allocated, 0 if not */
75 int code = 0;
76
77 /* Check for overflow. */
78 if (base != (long)base || base > base + count)
79 return_error(e_rangecheck);
80 if (r_has_type(&pfdata->u.cid0.DataSource, t_null)) {
81 /* Get the bytes from GlyphData (a string or array of strings). */
82 const ref *pgdata = &pfdata->u.cid0.GlyphData;
83
84 if (r_has_type(pgdata, t_string)) { /* single string */
85 uint size = r_size(pgdata);
86
87 if (base >= size || count > size - base)
88 return_error(e_rangecheck);
89 data = pgdata->value.bytes + base;
90 } else { /* array of strings */
91 /*
92 * The algorithm is similar to the one in
93 * string_array_access_proc in zfont42.c, but it also has to
94 * deal with the case where the requested string crosses array
95 * elements.
96 */
97 ulong skip = base;
98 uint copied = 0;
99 uint index = 0;
100 ref rstr;
101 uint size;
102
103 for (;; skip -= size, ++index) {
104 int code = array_get(pfont->memory, pgdata, index, &rstr);
105
106 if (code < 0)
107 return code;
108 if (!r_has_type(&rstr, t_string))
109 return_error(e_typecheck);
110 size = r_size(&rstr);
111 if (skip < size)
112 break;
113 }
114 size -= skip;
115 if (count <= size) {
116 data = rstr.value.bytes + skip;
117 } else { /* multiple strings needed */
118 if (data == 0) { /* no buffer provided */
119 data = gs_alloc_string(pfont->memory, count,
120 "cid0_read_bytes");
121 if (data == 0)
122 return_error(e_VMerror);
123 gdfont = (gs_font *)pfont; /* newly allocated */
124 }
125 memcpy(data, rstr.value.bytes + skip, size);
126 copied = size;
127 while (copied < count) {
128 int code = array_get(pfont->memory, pgdata, ++index, &rstr);
129
130 if (code < 0)
131 goto err;
132 if (!r_has_type(&rstr, t_string)) {
133 code = gs_note_error(e_typecheck);
134 goto err;
135 }
136 size = r_size(&rstr);
137 if (size > count - copied)
138 size = count - copied;
139 memcpy(data + copied, rstr.value.bytes, size);
140 copied += size;
141 }
142 }
143 }
144 } else {
145 /* Get the bytes from DataSource (a stream). */
146 stream *s;
147 uint nread;
148 i_ctx_t *i_ctx_p = get_minst_from_memory(pfont->memory)->i_ctx_p;
149
150 check_read_known_file(i_ctx_p, s, &pfdata->u.cid0.DataSource, return_error);
151 if (sseek(s, base) < 0)
152 return_error(e_ioerror);
153 if (data == 0) { /* no buffer provided */
154 data = gs_alloc_string(pfont->memory, count, "cid0_read_bytes");
155 if (data == 0)
156 return_error(e_VMerror);
157 gdfont = (gs_font *)pfont; /* newly allocated */
158 }
159 if (sgets(s, data, count, &nread) < 0 || nread != count) {
160 code = gs_note_error(e_ioerror);
161 goto err;
162 }
163 }
164 gs_glyph_data_from_string(pgd, data, count, gdfont);
165 return code;
166 err:
167 if (data != buf)
168 gs_free_string(pfont->memory, data, count, "cid0_read_bytes");
169 return code;
170 }
171
172 /* Get the CharString data for a CIDFontType 0 font. */
173 /* This is the glyph_data procedure in the font itself. */
174 /* Note that pgd may be NULL. */
175 static int
z9_glyph_data(gs_font_base * pbfont,gs_glyph glyph,gs_glyph_data_t * pgd,int * pfidx)176 z9_glyph_data(gs_font_base *pbfont, gs_glyph glyph, gs_glyph_data_t *pgd,
177 int *pfidx)
178 {
179 gs_font_cid0 *pfont = (gs_font_cid0 *)pbfont;
180 const font_data *pfdata = pfont_data(pfont);
181 long glyph_index = (long)(glyph - gs_min_cid_glyph);
182 gs_glyph_data_t gdata;
183 ulong fidx;
184 int code;
185
186 gdata.memory = pfont->memory;
187 if (!r_has_type(&pfdata->u.cid0.GlyphDirectory, t_null)) {
188 code = font_gdir_get_outline(pfont->memory,
189 &pfdata->u.cid0.GlyphDirectory,
190 glyph_index, &gdata);
191 if (code < 0)
192 return code;
193 /* Get the definition from GlyphDirectory. */
194 if (!gdata.bits.data)
195 return_error(e_rangecheck);
196 code = get_index(&gdata, pfont->cidata.FDBytes, &fidx);
197 if (code < 0)
198 return code;
199 if (fidx >= pfont->cidata.FDArray_size)
200 return_error(e_rangecheck);
201 if (pgd)
202 *pgd = gdata;
203 *pfidx = (int)fidx;
204 return code;
205 }
206 /* Get the definition from the binary data (GlyphData or DataSource). */
207 if (glyph_index < 0 || glyph_index >= pfont->cidata.common.CIDCount) {
208 *pfidx = 0;
209 if (pgd)
210 gs_glyph_data_from_null(pgd);
211 return_error(e_rangecheck);
212 }
213 {
214 byte fd_gd[(MAX_FDBytes + MAX_GDBytes) * 2];
215 uint num_bytes = pfont->cidata.FDBytes + pfont->cidata.common.GDBytes;
216 ulong base = pfont->cidata.CIDMapOffset + glyph_index * num_bytes;
217 ulong gidx, fidx_next, gidx_next;
218 int rcode = cid0_read_bytes(pfont, base, (ulong)(num_bytes * 2), fd_gd,
219 &gdata);
220 gs_glyph_data_t orig_data;
221
222 if (rcode < 0)
223 return rcode;
224 orig_data = gdata;
225 if ((code = get_index(&gdata, pfont->cidata.FDBytes, &fidx)) < 0 ||
226 (code = get_index(&gdata, pfont->cidata.common.GDBytes, &gidx)) < 0 ||
227 (code = get_index(&gdata, pfont->cidata.FDBytes, &fidx_next)) < 0 ||
228 (code = get_index(&gdata, pfont->cidata.common.GDBytes, &gidx_next)) < 0
229 )
230 DO_NOTHING;
231 gs_glyph_data_free(&orig_data, "z9_glyph_data");
232 if (code < 0)
233 return code;
234 /*
235 * Some CID fonts (from Adobe!) have invalid font indexes for
236 * missing glyphs. Handle this now.
237 */
238 if (gidx_next <= gidx) { /* missing glyph */
239 *pfidx = 0;
240 if (pgd)
241 gs_glyph_data_from_null(pgd);
242 return_error(e_undefined);
243 }
244 if (fidx >= pfont->cidata.FDArray_size)
245 return_error(e_rangecheck);
246 *pfidx = (int)fidx;
247 if (pgd == 0)
248 return 0;
249 return cid0_read_bytes(pfont, gidx, gidx_next - gidx, NULL, pgd);
250 }
251 }
252
253 /* Get the outline of a CIDFontType 0 glyph. */
254 static int
z9_glyph_outline(gs_font * font,int WMode,gs_glyph glyph,const gs_matrix * pmat,gx_path * ppath,double sbw[4])255 z9_glyph_outline(gs_font *font, int WMode, gs_glyph glyph, const gs_matrix *pmat,
256 gx_path *ppath, double sbw[4])
257 {
258 gs_font_cid0 *const pfcid = (gs_font_cid0 *)font;
259 ref gref;
260 gs_glyph_data_t gdata;
261 int code, fidx, ocode;
262
263 gdata.memory = font->memory;
264 code = pfcid->cidata.glyph_data((gs_font_base *)pfcid, glyph, &gdata,
265 &fidx);
266 if (code < 0)
267 return code;
268 glyph_ref(font->memory, glyph, &gref);
269 ocode = zcharstring_outline(pfcid->cidata.FDArray[fidx], WMode, &gref, &gdata,
270 pmat, ppath, sbw);
271 gs_glyph_data_free(&gdata, "z9_glyph_outline");
272 return ocode;
273 }
274
275 static int
z9_glyph_info(gs_font * font,gs_glyph glyph,const gs_matrix * pmat,int members,gs_glyph_info_t * info)276 z9_glyph_info(gs_font *font, gs_glyph glyph, const gs_matrix *pmat,
277 int members, gs_glyph_info_t *info)
278 { /* fixme : same as z11_glyph_info. */
279 int wmode = (members & GLYPH_INFO_WIDTH0 ? 0 : 1);
280
281 return z1_glyph_info_generic(font, glyph, pmat, members, info,
282 &gs_default_glyph_info, wmode);
283 }
284
285 /*
286 * The "fonts" in the FDArray don't have access to their outlines -- the
287 * outlines are always provided externally. Replace the accessor procedures
288 * with ones that will give an error if called.
289 */
290 static int
z9_FDArray_glyph_data(gs_font_type1 * pfont,gs_glyph glyph,gs_glyph_data_t * pgd)291 z9_FDArray_glyph_data(gs_font_type1 * pfont, gs_glyph glyph,
292 gs_glyph_data_t *pgd)
293 {
294 return_error(e_invalidfont);
295 }
296 static int
z9_FDArray_seac_data(gs_font_type1 * pfont,int ccode,gs_glyph * pglyph,gs_const_string * gstr,gs_glyph_data_t * pgd)297 z9_FDArray_seac_data(gs_font_type1 *pfont, int ccode, gs_glyph *pglyph,
298 gs_const_string *gstr, gs_glyph_data_t *pgd)
299 {
300 return_error(e_invalidfont);
301 }
302
303 /* ------ Defining ------ */
304
305 /* Get one element of a FDArray. */
306 static int
fd_array_element(i_ctx_t * i_ctx_p,gs_font_type1 ** ppfont,ref * prfd)307 fd_array_element(i_ctx_t *i_ctx_p, gs_font_type1 **ppfont, ref *prfd)
308 {
309 charstring_font_refs_t refs;
310 gs_type1_data data1;
311 build_proc_refs build;
312 gs_font_base *pbfont;
313 gs_font_type1 *pfont;
314 /*
315 * Standard CIDFontType 0 fonts have Type 1 fonts in the FDArray, but
316 * CFF CIDFontType 0 fonts have Type 2 fonts there.
317 */
318 int fonttype = 1; /* default */
319 int code = charstring_font_get_refs(prfd, &refs);
320
321 if (code < 0 ||
322 (code = dict_int_param(prfd, "FontType", 1, 2, 1, &fonttype)) < 0
323 )
324 return code;
325 /*
326 * We don't handle the alternate Subr representation (SubrCount,
327 * SDBytes, SubrMapOffset) here: currently that is handled in
328 * PostScript code (lib/gs_cidfn.ps).
329 */
330 switch (fonttype) {
331 case 1:
332 data1.interpret = gs_type1_interpret;
333 data1.subroutineNumberBias = 0;
334 data1.lenIV = DEFAULT_LENIV_1;
335 code = charstring_font_params(imemory, prfd, &refs, &data1);
336 if (code < 0)
337 return code;
338 code = build_proc_name_refs(imemory, &build,
339 "%Type1BuildChar", "%Type1BuildGlyph");
340 break;
341 case 2:
342 code = type2_font_params(prfd, &refs, &data1);
343 if (code < 0)
344 return code;
345 code = charstring_font_params(imemory, prfd, &refs, &data1);
346 if (code < 0)
347 return code;
348 code = build_proc_name_refs(imemory, &build,
349 "%Type2BuildChar", "%Type2BuildGlyph");
350 break;
351 default: /* can't happen */
352 return_error(e_Fatal);
353 }
354 if (code < 0)
355 return code;
356 code = build_gs_FDArray_font(i_ctx_p, prfd, &pbfont, fonttype,
357 &st_gs_font_type1, &build);
358 if (code < 0)
359 return code;
360 pfont = (gs_font_type1 *)pbfont;
361 pbfont->FAPI = NULL;
362 pbfont->FAPI_font_data = NULL;
363 charstring_font_init(pfont, &refs, &data1);
364 pfont->data.procs.glyph_data = z9_FDArray_glyph_data;
365 pfont->data.procs.seac_data = z9_FDArray_seac_data;
366 *ppfont = pfont;
367 return 0;
368 }
369
370 static int
notify_remove_font_type9(void * proc_data,void * event_data)371 notify_remove_font_type9(void *proc_data, void *event_data)
372 { /* Likely type 9 font descendents are never released explicitly.
373 So releaseing a type 9 font we must reset pointers in descendents.
374 */
375 /* gs_font_finalize passes event_data == NULL, so check it here. */
376 if (event_data == NULL) {
377 gs_font_cid0 *pfcid = proc_data;
378 int i;
379
380 for (i = 0; i < pfcid->cidata.FDArray_size; ++i) {
381 if (pfcid->cidata.FDArray[i]->data.parent == (gs_font_base *)pfcid)
382 pfcid->cidata.FDArray[i]->data.parent = NULL;
383 }
384 }
385 return 0;
386 }
387
388 /* <string|name> <font_dict> .buildfont9 <string|name> <font> */
389 static int
zbuildfont9(i_ctx_t * i_ctx_p)390 zbuildfont9(i_ctx_t *i_ctx_p)
391 {
392 os_ptr op = osp;
393 build_proc_refs build;
394 int code = build_proc_name_refs(imemory, &build, NULL, "%Type9BuildGlyph");
395 gs_font_cid_data common;
396 ref GlyphDirectory, GlyphData, DataSource;
397 ref *prfda, cfnstr;
398 ref *pCIDFontName, CIDFontName;
399 gs_font_type1 **FDArray;
400 uint FDArray_size;
401 int FDBytes;
402 uint CIDMapOffset;
403 gs_font_base *pfont;
404 gs_font_cid0 *pfcid;
405 uint i;
406
407 /*
408 * If the CIDFont's data have been loaded into VM, GlyphData will be
409 * a string or an array of strings; if they are loaded incrementally
410 * from a file, GlyphData will be an integer, and DataSource will be
411 * a (reusable) stream.
412 */
413 if (code < 0 ||
414 (code = cid_font_data_param(op, &common, &GlyphDirectory)) < 0 ||
415 (code = dict_find_string(op, "FDArray", &prfda)) < 0 ||
416 (code = dict_find_string(op, "CIDFontName", &pCIDFontName)) <= 0 ||
417 (code = dict_int_param(op, "FDBytes", 0, MAX_FDBytes, -1, &FDBytes)) < 0
418 )
419 return code;
420 /*
421 * Since build_gs_simple_font may resize the dictionary and cause
422 * pointers to become invalid, save CIDFontName
423 */
424 CIDFontName = *pCIDFontName;
425 if (r_has_type(&GlyphDirectory, t_null)) {
426 /* Standard CIDFont, require GlyphData and CIDMapOffset. */
427 ref *pGlyphData;
428
429 if ((code = dict_find_string(op, "GlyphData", &pGlyphData)) < 0 ||
430 (code = dict_uint_param(op, "CIDMapOffset", 0, max_uint - 1,
431 max_uint, &CIDMapOffset)) < 0)
432 return code;
433 GlyphData = *pGlyphData;
434 if (r_has_type(&GlyphData, t_integer)) {
435 ref *pds;
436 stream *ignore_s;
437
438 if ((code = dict_find_string(op, "DataSource", &pds)) < 0)
439 return code;
440 check_read_file(i_ctx_p, ignore_s, pds);
441 DataSource = *pds;
442 } else {
443 if (!r_has_type(&GlyphData, t_string) && !r_is_array(&GlyphData))
444 return_error(e_typecheck);
445 make_null(&DataSource);
446 }
447 } else {
448 make_null(&GlyphData);
449 make_null(&DataSource);
450 CIDMapOffset = 0;
451 }
452 if (!r_is_array(prfda))
453 return_error(e_invalidfont);
454 FDArray_size = r_size(prfda);
455 if (FDArray_size == 0)
456 return_error(e_invalidfont);
457 FDArray = ialloc_struct_array(FDArray_size, gs_font_type1 *,
458 &st_gs_font_type1_ptr_element,
459 "buildfont9(FDarray)");
460 if (FDArray == 0)
461 return_error(e_VMerror);
462 memset(FDArray, 0, sizeof(gs_font_type1 *) * FDArray_size);
463 for (i = 0; i < FDArray_size; ++i) {
464 ref rfd;
465
466 array_get(imemory, prfda, (long)i, &rfd);
467 code = fd_array_element(i_ctx_p, &FDArray[i], &rfd);
468 if (code < 0)
469 goto fail;
470 }
471 code = build_gs_outline_font(i_ctx_p, op, &pfont, ft_CID_encrypted,
472 &st_gs_font_cid0, &build,
473 bf_Encoding_optional | bf_UniqueID_ignored,
474 build_gs_simple_font);
475 if (code < 0)
476 goto fail;
477 if (code == 1) {
478 /* The font already has a FID, don't need to build it again.
479 Release FDArray and return normally.
480 fixme: FDArray fonts are thrown for garbager.
481 We're not safe to build them after
482 build_gs_simple_font(..., &pfont, ...),
483 because a failure in building them would throw
484 an underbuilt font with unclear consequences.
485 */
486 ifree_object(FDArray, "buildfont9(FDarray)");
487 return 0;
488 }
489 pfont->procs.enumerate_glyph = gs_font_cid0_enumerate_glyph;
490 pfont->procs.glyph_outline = z9_glyph_outline;
491 pfont->procs.glyph_info = z9_glyph_info;
492 pfcid = (gs_font_cid0 *)pfont;
493 pfcid->cidata.common = common;
494 pfcid->cidata.CIDMapOffset = CIDMapOffset;
495 pfcid->cidata.FDArray = FDArray;
496 pfcid->cidata.FDArray_size = FDArray_size;
497 pfcid->cidata.FDBytes = FDBytes;
498 pfcid->cidata.glyph_data = z9_glyph_data;
499 pfcid->cidata.proc_data = 0; /* for GC */
500 if (pfcid->font_name.size == 0) {
501 get_font_name(imemory, &cfnstr, &CIDFontName);
502 copy_font_name(&pfcid->font_name, &cfnstr);
503 }
504 ref_assign(&pfont_data(pfont)->u.cid0.GlyphDirectory, &GlyphDirectory);
505 ref_assign(&pfont_data(pfont)->u.cid0.GlyphData, &GlyphData);
506 ref_assign(&pfont_data(pfont)->u.cid0.DataSource, &DataSource);
507 code = define_gs_font(i_ctx_p, (gs_font *)pfont);
508 if (code >= 0)
509 code = gs_notify_register(&pfont->notify_list, notify_remove_font_type9, pfont);
510 if (code >= 0) {
511 for (i = 0; i < FDArray_size; ++i) {
512 FDArray[i]->dir = pfont->dir;
513 FDArray[i]->data.parent = pfont;
514 }
515 return code;
516 }
517 fail:
518 ifree_object(FDArray, "buildfont9(FDarray)");
519 return code;
520 }
521
522 /* <cid9font> <cid> .type9mapcid <charstring> <font_index> */
523 int
ztype9mapcid(i_ctx_t * i_ctx_p)524 ztype9mapcid(i_ctx_t *i_ctx_p)
525 {
526 os_ptr op = osp;
527 gs_font *pfont;
528 gs_font_cid0 *pfcid;
529 int code = font_param(op - 1, &pfont);
530 gs_glyph_data_t gdata;
531 int fidx;
532
533 if (code < 0)
534 return code;
535 if (pfont->FontType != ft_CID_encrypted)
536 return_error(e_invalidfont);
537 check_type(*op, t_integer);
538 pfcid = (gs_font_cid0 *)pfont;
539 gdata.memory = pfont->memory;
540 code = pfcid->cidata.glyph_data((gs_font_base *)pfcid,
541 (gs_glyph)(gs_min_cid_glyph + op->value.intval),
542 &gdata, &fidx);
543
544 /* return code; original error-sensitive & fragile code */
545 if (code < 0) { /* failed to load glyph data, put CID 0 */
546 int default_fallback_CID = 0 ;
547
548 if_debug2('J', "[J]ztype9cidmap() use CID %d instead of glyph-missing CID %d\n", default_fallback_CID, op->value.intval);
549
550 op->value.intval = default_fallback_CID;
551
552 /* reload glyph for default_fallback_CID */
553
554 code = pfcid->cidata.glyph_data((gs_font_base *)pfcid,
555 (gs_glyph)(gs_min_cid_glyph + default_fallback_CID),
556 &gdata, &fidx);
557
558 if (code < 0) {
559 if_debug1('J', "[J]ztype9cidmap() could not load default glyph (CID %d)\n", op->value.intval);
560 return_error(e_invalidfont);
561 }
562
563 }
564
565 /****** FOLLOWING IS NOT GENERAL W.R.T. ALLOCATION OF GLYPH DATA ******/
566 make_const_string(op - 1,
567 a_readonly | imemory_space((gs_ref_memory_t *)pfont->memory),
568 gdata.bits.size,
569 gdata.bits.data);
570 make_int(op, fidx);
571 return code;
572 }
573
574 /* ------ Initialization procedure ------ */
575
576 const op_def zfcid0_op_defs[] =
577 {
578 {"2.buildfont9", zbuildfont9},
579 {"2.type9mapcid", ztype9mapcid},
580 op_def_end(0)
581 };
582