1 /* Copyright (C) 2000 Aladdin Enterprises. All rights reserved. 2 3 This software is provided AS-IS with no warranty, either express or 4 implied. 5 6 This software is distributed under license and may not be copied, 7 modified or distributed except as expressly authorized under the terms 8 of the license contained in the file LICENSE in this distribution. 9 10 For more information about licensing, please refer to 11 http://www.ghostscript.com/licensing/. For information on 12 commercial licensing, go to http://www.artifex.com/licensing/ or 13 contact Artifex Software, Inc., 101 Lucas Valley Road #110, 14 San Rafael, CA 94903, U.S.A., +1(415)492-9861. 15 */ 16 17 /* $Id: zfcid0.c,v 1.25 2004/11/19 04:39:11 ray Exp $ */ 18 /* CIDFontType 0 operators */ 19 #include "memory_.h" 20 #include "ghost.h" 21 #include "oper.h" 22 #include "gsmatrix.h" 23 #include "gsccode.h" 24 #include "gsstruct.h" 25 #include "gxfcid.h" 26 #include "gxfont1.h" 27 #include "gxalloc.h" /* for gs_ref_memory_t */ 28 #include "stream.h" /* for files.h */ 29 #include "bfont.h" 30 #include "files.h" 31 #include "ichar.h" 32 #include "ichar1.h" 33 #include "icid.h" 34 #include "idict.h" 35 #include "idparam.h" 36 #include "ifcid.h" 37 #include "ifont1.h" 38 #include "ifont2.h" 39 #include "ifont42.h" 40 #include "store.h" 41 42 /* Type 1 font procedures (defined in zchar1.c) */ 43 font_proc_glyph_outline(zcharstring_glyph_outline); 44 45 /* ---------------- CIDFontType 0 (FontType 9) ---------------- */ 46 47 /* ------ Accessing ------ */ 48 49 /* Parse a multi-byte integer from a string. */ 50 private int 51 get_index(gs_glyph_data_t *pgd, int count, ulong *pval) 52 { 53 int i; 54 55 if (pgd->bits.size < count) 56 return_error(e_rangecheck); 57 *pval = 0; 58 for (i = 0; i < count; ++i) 59 *pval = (*pval << 8) + pgd->bits.data[i]; 60 pgd->bits.data += count; 61 pgd->bits.size -= count; 62 return 0; 63 } 64 65 /* Get bytes from GlyphData or DataSource. */ 66 private int 67 cid0_read_bytes(gs_font_cid0 *pfont, ulong base, uint count, byte *buf, 68 gs_glyph_data_t *pgd) 69 { 70 const font_data *pfdata = pfont_data(pfont); 71 byte *data = buf; 72 gs_font *gdfont = 0; /* pfont if newly allocated, 0 if not */ 73 int code = 0; 74 75 /* Check for overflow. */ 76 if (base != (long)base || base > base + count) 77 return_error(e_rangecheck); 78 if (r_has_type(&pfdata->u.cid0.DataSource, t_null)) { 79 /* Get the bytes from GlyphData (a string or array of strings). */ 80 const ref *pgdata = &pfdata->u.cid0.GlyphData; 81 82 if (r_has_type(pgdata, t_string)) { /* single string */ 83 uint size = r_size(pgdata); 84 85 if (base >= size || count > size - base) 86 return_error(e_rangecheck); 87 data = pgdata->value.bytes + base; 88 } else { /* array of strings */ 89 /* 90 * The algorithm is similar to the one in 91 * string_array_access_proc in zfont42.c, but it also has to 92 * deal with the case where the requested string crosses array 93 * elements. 94 */ 95 ulong skip = base; 96 uint copied = 0; 97 uint index = 0; 98 ref rstr; 99 uint size; 100 101 for (;; skip -= size, ++index) { 102 int code = array_get(pfont->memory, pgdata, index, &rstr); 103 104 if (code < 0) 105 return code; 106 if (!r_has_type(&rstr, t_string)) 107 return_error(e_typecheck); 108 size = r_size(&rstr); 109 if (skip < size) 110 break; 111 } 112 size -= skip; 113 if (count <= size) { 114 data = rstr.value.bytes + skip; 115 } else { /* multiple strings needed */ 116 if (data == 0) { /* no buffer provided */ 117 data = gs_alloc_string(pfont->memory, count, 118 "cid0_read_bytes"); 119 if (data == 0) 120 return_error(e_VMerror); 121 gdfont = (gs_font *)pfont; /* newly allocated */ 122 } 123 memcpy(data, rstr.value.bytes + skip, size); 124 copied = size; 125 while (copied < count) { 126 int code = array_get(pfont->memory, pgdata, ++index, &rstr); 127 128 if (code < 0) 129 goto err; 130 if (!r_has_type(&rstr, t_string)) { 131 code = gs_note_error(e_typecheck); 132 goto err; 133 } 134 size = r_size(&rstr); 135 if (size > count - copied) 136 size = count - copied; 137 memcpy(data + copied, rstr.value.bytes, size); 138 copied += size; 139 } 140 } 141 } 142 } else { 143 /* Get the bytes from DataSource (a stream). */ 144 stream *s; 145 uint nread; 146 147 check_read_known_file(s, &pfdata->u.cid0.DataSource, return_error); 148 if (sseek(s, base) < 0) 149 return_error(e_ioerror); 150 if (data == 0) { /* no buffer provided */ 151 data = gs_alloc_string(pfont->memory, count, "cid0_read_bytes"); 152 if (data == 0) 153 return_error(e_VMerror); 154 gdfont = (gs_font *)pfont; /* newly allocated */ 155 } 156 if (sgets(s, data, count, &nread) < 0 || nread != count) { 157 code = gs_note_error(e_ioerror); 158 goto err; 159 } 160 } 161 gs_glyph_data_from_string(pgd, data, count, gdfont); 162 return code; 163 err: 164 if (data != buf) 165 gs_free_string(pfont->memory, data, count, "cid0_read_bytes"); 166 return code; 167 } 168 169 /* Get the CharString data for a CIDFontType 0 font. */ 170 /* This is the glyph_data procedure in the font itself. */ 171 /* Note that pgd may be NULL. */ 172 private int 173 z9_glyph_data(gs_font_base *pbfont, gs_glyph glyph, gs_glyph_data_t *pgd, 174 int *pfidx) 175 { 176 gs_font_cid0 *pfont = (gs_font_cid0 *)pbfont; 177 const font_data *pfdata = pfont_data(pfont); 178 long glyph_index = (long)(glyph - gs_min_cid_glyph); 179 gs_glyph_data_t gdata; 180 ulong fidx; 181 int code; 182 183 gdata.memory = pfont->memory; 184 if (!r_has_type(&pfdata->u.cid0.GlyphDirectory, t_null)) { 185 code = font_gdir_get_outline(pfont->memory, 186 &pfdata->u.cid0.GlyphDirectory, 187 glyph_index, &gdata); 188 if (code < 0) 189 return code; 190 /* Get the definition from GlyphDirectory. */ 191 if (!gdata.bits.data) 192 return_error(e_rangecheck); 193 code = get_index(&gdata, pfont->cidata.FDBytes, &fidx); 194 if (code < 0) 195 return code; 196 if (fidx >= pfont->cidata.FDArray_size) 197 return_error(e_rangecheck); 198 if (pgd) 199 *pgd = gdata; 200 *pfidx = (int)fidx; 201 return code; 202 } 203 /* Get the definition from the binary data (GlyphData or DataSource). */ 204 if (glyph_index < 0 || glyph_index >= pfont->cidata.common.CIDCount) { 205 *pfidx = 0; 206 if (pgd) 207 gs_glyph_data_from_null(pgd); 208 return_error(e_rangecheck); 209 } 210 { 211 byte fd_gd[(MAX_FDBytes + MAX_GDBytes) * 2]; 212 uint num_bytes = pfont->cidata.FDBytes + pfont->cidata.common.GDBytes; 213 ulong base = pfont->cidata.CIDMapOffset + glyph_index * num_bytes; 214 ulong gidx, fidx_next, gidx_next; 215 int rcode = cid0_read_bytes(pfont, base, (ulong)(num_bytes * 2), fd_gd, 216 &gdata); 217 gs_glyph_data_t orig_data; 218 219 if (rcode < 0) 220 return rcode; 221 orig_data = gdata; 222 if ((code = get_index(&gdata, pfont->cidata.FDBytes, &fidx)) < 0 || 223 (code = get_index(&gdata, pfont->cidata.common.GDBytes, &gidx)) < 0 || 224 (code = get_index(&gdata, pfont->cidata.FDBytes, &fidx_next)) < 0 || 225 (code = get_index(&gdata, pfont->cidata.common.GDBytes, &gidx_next)) < 0 226 ) 227 DO_NOTHING; 228 gs_glyph_data_free(&orig_data, "z9_glyph_data"); 229 if (code < 0) 230 return code; 231 /* 232 * Some CID fonts (from Adobe!) have invalid font indexes for 233 * missing glyphs. Handle this now. 234 */ 235 if (gidx_next <= gidx) { /* missing glyph */ 236 *pfidx = 0; 237 if (pgd) 238 gs_glyph_data_from_null(pgd); 239 return_error(e_undefined); 240 } 241 if (fidx >= pfont->cidata.FDArray_size) 242 return_error(e_rangecheck); 243 *pfidx = (int)fidx; 244 if (pgd == 0) 245 return 0; 246 return cid0_read_bytes(pfont, gidx, gidx_next - gidx, NULL, pgd); 247 } 248 } 249 250 /* Get the outline of a CIDFontType 0 glyph. */ 251 private int 252 z9_glyph_outline(gs_font *font, int WMode, gs_glyph glyph, const gs_matrix *pmat, 253 gx_path *ppath, double sbw[4]) 254 { 255 gs_font_cid0 *const pfcid = (gs_font_cid0 *)font; 256 ref gref; 257 gs_glyph_data_t gdata; 258 int code, fidx, ocode; 259 260 gdata.memory = font->memory; 261 code = pfcid->cidata.glyph_data((gs_font_base *)pfcid, glyph, &gdata, 262 &fidx); 263 if (code < 0) 264 return code; 265 glyph_ref(font->memory, glyph, &gref); 266 ocode = zcharstring_outline(pfcid->cidata.FDArray[fidx], WMode, &gref, &gdata, 267 pmat, ppath, sbw); 268 gs_glyph_data_free(&gdata, "z9_glyph_outline"); 269 return ocode; 270 } 271 272 private int 273 z9_glyph_info(gs_font *font, gs_glyph glyph, const gs_matrix *pmat, 274 int members, gs_glyph_info_t *info) 275 { /* fixme : same as z11_glyph_info. */ 276 int wmode = (members & GLYPH_INFO_WIDTH0 ? 0 : 1); 277 278 return z1_glyph_info_generic(font, glyph, pmat, members, info, 279 &gs_default_glyph_info, wmode); 280 } 281 282 283 /* 284 * The "fonts" in the FDArray don't have access to their outlines -- the 285 * outlines are always provided externally. Replace the accessor procedures 286 * with ones that will give an error if called. 287 */ 288 private int 289 z9_FDArray_glyph_data(gs_font_type1 * pfont, gs_glyph glyph, 290 gs_glyph_data_t *pgd) 291 { 292 return_error(e_invalidfont); 293 } 294 private int 295 z9_FDArray_seac_data(gs_font_type1 *pfont, int ccode, gs_glyph *pglyph, 296 gs_const_string *gstr, gs_glyph_data_t *pgd) 297 { 298 return_error(e_invalidfont); 299 } 300 301 /* ------ Defining ------ */ 302 303 /* Get one element of a FDArray. */ 304 private int 305 fd_array_element(i_ctx_t *i_ctx_p, gs_font_type1 **ppfont, ref *prfd) 306 { 307 charstring_font_refs_t refs; 308 gs_type1_data data1; 309 build_proc_refs build; 310 gs_font_base *pbfont; 311 gs_font_type1 *pfont; 312 /* 313 * Standard CIDFontType 0 fonts have Type 1 fonts in the FDArray, but 314 * CFF CIDFontType 0 fonts have Type 2 fonts there. 315 */ 316 int fonttype = 1; /* default */ 317 int code = charstring_font_get_refs(prfd, &refs); 318 319 if (code < 0 || 320 (code = dict_int_param(prfd, "FontType", 1, 2, 1, &fonttype)) < 0 321 ) 322 return code; 323 /* 324 * We don't handle the alternate Subr representation (SubrCount, 325 * SDBytes, SubrMapOffset) here: currently that is handled in 326 * PostScript code (lib/gs_cidfn.ps). 327 */ 328 switch (fonttype) { 329 case 1: 330 data1.interpret = gs_type1_interpret; 331 data1.subroutineNumberBias = 0; 332 data1.lenIV = DEFAULT_LENIV_1; 333 code = charstring_font_params(imemory, prfd, &refs, &data1); 334 if (code < 0) 335 return code; 336 code = build_proc_name_refs(imemory, &build, 337 "%Type1BuildChar", "%Type1BuildGlyph"); 338 break; 339 case 2: 340 code = type2_font_params(prfd, &refs, &data1); 341 if (code < 0) 342 return code; 343 code = charstring_font_params(imemory, prfd, &refs, &data1); 344 if (code < 0) 345 return code; 346 code = build_proc_name_refs(imemory, &build, 347 "%Type2BuildChar", "%Type2BuildGlyph"); 348 break; 349 default: /* can't happen */ 350 return_error(e_Fatal); 351 } 352 if (code < 0) 353 return code; 354 code = build_gs_FDArray_font(i_ctx_p, prfd, &pbfont, fonttype, 355 &st_gs_font_type1, &build); 356 if (code < 0) 357 return code; 358 pfont = (gs_font_type1 *)pbfont; 359 pbfont->FAPI = NULL; 360 pbfont->FAPI_font_data = NULL; 361 charstring_font_init(pfont, &refs, &data1); 362 pfont->data.procs.glyph_data = z9_FDArray_glyph_data; 363 pfont->data.procs.seac_data = z9_FDArray_seac_data; 364 *ppfont = pfont; 365 return 0; 366 } 367 368 369 370 private int 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 private int 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(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_simple_font(i_ctx_p, op, &pfont, ft_CID_encrypted, 472 &st_gs_font_cid0, &build, 473 bf_Encoding_optional | 474 bf_UniqueID_ignored); 475 if (code < 0) 476 goto fail; 477 pfont->procs.enumerate_glyph = gs_font_cid0_enumerate_glyph; 478 pfont->procs.glyph_outline = z9_glyph_outline; 479 pfont->procs.glyph_info = z9_glyph_info; 480 pfcid = (gs_font_cid0 *)pfont; 481 pfcid->cidata.common = common; 482 pfcid->cidata.CIDMapOffset = CIDMapOffset; 483 pfcid->cidata.FDArray = FDArray; 484 pfcid->cidata.FDArray_size = FDArray_size; 485 pfcid->cidata.FDBytes = FDBytes; 486 pfcid->cidata.glyph_data = z9_glyph_data; 487 pfcid->cidata.proc_data = 0; /* for GC */ 488 get_font_name(imemory, &cfnstr, &CIDFontName); 489 copy_font_name(&pfcid->font_name, &cfnstr); 490 ref_assign(&pfont_data(pfont)->u.cid0.GlyphDirectory, &GlyphDirectory); 491 ref_assign(&pfont_data(pfont)->u.cid0.GlyphData, &GlyphData); 492 ref_assign(&pfont_data(pfont)->u.cid0.DataSource, &DataSource); 493 code = define_gs_font((gs_font *)pfont); 494 if (code >= 0) 495 code = gs_notify_register(&pfont->notify_list, notify_remove_font_type9, pfont); 496 if (code >= 0) { 497 for (i = 0; i < FDArray_size; ++i) { 498 FDArray[i]->dir = pfont->dir; 499 FDArray[i]->data.parent = pfont; 500 } 501 return code; 502 } 503 fail: 504 ifree_object(FDArray, "buildfont9(FDarray)"); 505 return code; 506 } 507 508 /* <cid9font> <cid> .type9mapcid <charstring> <font_index> */ 509 int 510 ztype9mapcid(i_ctx_t *i_ctx_p) 511 { 512 os_ptr op = osp; 513 gs_font *pfont; 514 gs_font_cid0 *pfcid; 515 int code = font_param(op - 1, &pfont); 516 gs_glyph_data_t gdata; 517 int fidx; 518 519 if (code < 0) 520 return code; 521 if (pfont->FontType != ft_CID_encrypted) 522 return_error(e_invalidfont); 523 check_type(*op, t_integer); 524 pfcid = (gs_font_cid0 *)pfont; 525 gdata.memory = pfont->memory; 526 code = pfcid->cidata.glyph_data((gs_font_base *)pfcid, 527 (gs_glyph)(gs_min_cid_glyph + op->value.intval), 528 &gdata, &fidx); 529 530 /* return code; original error-sensitive & fragile code */ 531 if (code < 0) { /* failed to load glyph data, put CID 0 */ 532 int default_fallback_CID = 0 ; 533 534 if_debug2('J', "[J]ztype9cidmap() use CID %d instead of glyph-missing CID %d\n", default_fallback_CID, op->value.intval); 535 536 op->value.intval = default_fallback_CID; 537 538 /* reload glyph for default_fallback_CID */ 539 540 code = pfcid->cidata.glyph_data((gs_font_base *)pfcid, 541 (gs_glyph)(gs_min_cid_glyph + default_fallback_CID), 542 &gdata, &fidx); 543 544 if (code < 0) { 545 if_debug1('J', "[J]ztype9cidmap() could not load default glyph (CID %d)\n", op->value.intval); 546 return_error(e_invalidfont); 547 } 548 549 } 550 551 /****** FOLLOWING IS NOT GENERAL W.R.T. ALLOCATION OF GLYPH DATA ******/ 552 make_const_string(op - 1, 553 a_readonly | imemory_space((gs_ref_memory_t *)pfont->memory), 554 gdata.bits.size, 555 gdata.bits.data); 556 make_int(op, fidx); 557 return code; 558 } 559 560 /* ------ Initialization procedure ------ */ 561 562 const op_def zfcid0_op_defs[] = 563 { 564 {"2.buildfont9", zbuildfont9}, 565 {"2.type9mapcid", ztype9mapcid}, 566 op_def_end(0) 567 }; 568