1 /* Copyright (C) 2002 Aladdin Enterprises. All rights reserved. 2 3 This software is provided AS-IS with no warranty, either express or 4 implied. 5 6 This software is distributed under license and may not be copied, 7 modified or distributed except as expressly authorized under the terms 8 of the license contained in the file LICENSE in this distribution. 9 10 For more information about licensing, please refer to 11 http://www.ghostscript.com/licensing/. For information on 12 commercial licensing, go to http://www.artifex.com/licensing/ or 13 contact Artifex Software, Inc., 101 Lucas Valley Road #110, 14 San Rafael, CA 94903, U.S.A., +1(415)492-9861. 15 */ 16 17 /* $Id: gdevpdtb.c,v 1.36 2005/04/25 02:23:58 igor Exp $ */ 18 /* BaseFont implementation for pdfwrite */ 19 #include "memory_.h" 20 #include "ctype_.h" 21 #include "string_.h" 22 #include "gx.h" 23 #include "gserrors.h" 24 #include "gsutil.h" /* for bytes_compare */ 25 #include "gxfcid.h" 26 #include "gxfcopy.h" 27 #include "gxfont.h" /* for gxfont42.h */ 28 #include "gxfont42.h" 29 #include "gdevpsf.h" 30 #include "gdevpdfx.h" 31 #include "gdevpdfo.h" 32 #include "gdevpdtb.h" 33 #include "gdevpdtf.h" 34 35 /* 36 * Adobe's Distiller Parameters documentation for Acrobat Distiller 5 37 * says that all fonts other than Type 1 are always subsetted; the 38 * documentation for Distiller 4 says that fonts other than Type 1 and 39 * TrueType are subsetted. We do the latter, except that we always 40 * subset large TrueType fonts. 41 */ 42 #define MAX_NO_SUBSET_GLYPHS 500 /* arbitrary */ 43 44 /* ---------------- Definitions ---------------- */ 45 46 struct pdf_base_font_s { 47 /* 48 * For the standard 14 fonts, copied == complete is a complete copy 49 * of the font, and DO_SUBSET = NO. 50 * 51 * For fonts that MAY be subsetted, copied is a partial copy, 52 * complete is a complete copy, and DO_SUBSET = UNKNOWN until 53 * pdf_font_do_subset is called. 54 * 55 * For fonts that MUST be subsetted, copied == complete is a partial 56 * copy, and DO_SUBSET = YES. 57 */ 58 gs_font_base *copied; 59 gs_font_base *complete; 60 enum { 61 DO_SUBSET_UNKNOWN = 0, 62 DO_SUBSET_NO, 63 DO_SUBSET_YES 64 } do_subset; 65 bool is_standard; 66 /* 67 * For CIDFonts, which are always subsetted, num_glyphs is CIDCount. 68 * For optionally subsetted fonts, num_glyphs is the count of glyphs 69 * in the font when originally copied. Note that if the font is 70 * downloaded incrementally, num_glyphs may be 0. 71 */ 72 int num_glyphs; 73 byte *CIDSet; /* for CIDFonts */ 74 gs_string font_name; 75 bool written; 76 cos_dict_t *FontFile; 77 }; 78 BASIC_PTRS(pdf_base_font_ptrs) { 79 GC_OBJ_ELT(pdf_base_font_t, copied), 80 GC_OBJ_ELT(pdf_base_font_t, complete), 81 GC_OBJ_ELT(pdf_base_font_t, CIDSet), 82 GC_OBJ_ELT(pdf_base_font_t, FontFile), 83 GC_STRING_ELT(pdf_base_font_t, font_name) 84 }; 85 gs_private_st_basic(st_pdf_base_font, pdf_base_font_t, "pdf_base_font_t", 86 pdf_base_font_ptrs, pdf_base_font_data); 87 88 /* ---------------- Private ---------------- */ 89 90 #define SUBSET_PREFIX_SIZE 7 /* XXXXXX+ */ 91 92 /* 93 * Determine whether a font is a subset font by examining the name. 94 */ 95 bool 96 pdf_has_subset_prefix(const byte *str, uint size) 97 { 98 int i; 99 100 if (size < SUBSET_PREFIX_SIZE || str[SUBSET_PREFIX_SIZE - 1] != '+') 101 return false; 102 for (i = 0; i < SUBSET_PREFIX_SIZE - 1; ++i) 103 if ((uint)(str[i] - 'A') >= 26) 104 return false; 105 return true; 106 } 107 108 private ulong 109 hash(ulong v, int index, ushort w) 110 { 111 return v * 3141592653u + w; 112 } 113 114 /* 115 * Add the XXXXXX+ prefix for a subset font. 116 */ 117 int 118 pdf_add_subset_prefix(const gx_device_pdf *pdev, gs_string *pstr, byte *used, int count) 119 { 120 uint size = pstr->size; 121 byte *data = gs_resize_string(pdev->pdf_memory, pstr->data, size, 122 size + SUBSET_PREFIX_SIZE, 123 "pdf_add_subset_prefix"); 124 int len = (count + 7) / 8; 125 ulong v = 0; 126 ushort t = 0; 127 int i; 128 129 if (data == 0) 130 return_error(gs_error_VMerror); 131 /* Hash the 'used' array. */ 132 for (i = 0; i < len; i += sizeof(ushort)) 133 v = hash(v, i, *(ushort *)(used + i)); 134 if (i < len) { 135 i -= sizeof(ushort); 136 memmove(&t, used + i, len - i); 137 v = hash(v, i, *(ushort *)(used + i)); 138 } 139 memmove(data + SUBSET_PREFIX_SIZE, data, size); 140 for (i = 0; i < SUBSET_PREFIX_SIZE - 1; ++i, v /= 26) 141 data[i] = 'A' + (v % 26); 142 data[SUBSET_PREFIX_SIZE - 1] = '+'; 143 pstr->data = data; 144 pstr->size = size + SUBSET_PREFIX_SIZE; 145 return 0; 146 } 147 148 /* Finish writing FontFile* data. */ 149 private int 150 pdf_end_fontfile(gx_device_pdf *pdev, pdf_data_writer_t *pdw) 151 { 152 /* We would like to call pdf_end_data, 153 but we don't want to write the object to the output file now. */ 154 return pdf_close_aside(pdw->pdev); 155 } 156 157 /* ---------------- Public ---------------- */ 158 159 /* 160 * Allocate and initialize a base font structure, making the required 161 * stable copy/ies of the gs_font. Note that this removes any XXXXXX+ 162 * font name prefix from the copy. If is_standard is true, the copy is 163 * a complete one, and adding glyphs or Encoding entries is not allowed. 164 */ 165 int 166 pdf_base_font_alloc(gx_device_pdf *pdev, pdf_base_font_t **ppbfont, 167 gs_font_base *font, const gs_matrix *orig_matrix, 168 bool is_standard, bool orig_name) 169 { 170 gs_memory_t *mem = pdev->pdf_memory; 171 gs_font *copied; 172 gs_font *complete; 173 pdf_base_font_t *pbfont = 174 gs_alloc_struct(mem, pdf_base_font_t, 175 &st_pdf_base_font, "pdf_base_font_alloc"); 176 const gs_font_name *pfname = pdf_choose_font_name((gs_font *)font, orig_name); 177 gs_const_string font_name; 178 char fnbuf[3 + sizeof(long) / 3 + 1]; /* .F#######\0 */ 179 int code; 180 181 if (pbfont == 0) 182 return_error(gs_error_VMerror); 183 code = gs_copy_font((gs_font *)font, orig_matrix, mem, &copied); 184 if (code < 0) 185 goto fail; 186 memset(pbfont, 0, sizeof(*pbfont)); 187 { 188 /* 189 * Adobe Technical Note # 5012 "The Type 42 Font Format Specification" says : 190 * 191 * There is a known bug in the TrueType rasterizer included in versions of the 192 * PostScript interpreter previous to version 2013. The problem is that the 193 * translation components of the FontMatrix, as used as an argument to the 194 * definefont or makefont operators, are ignored. Translation of user space is 195 * not affected by this bug. 196 * 197 * Besides that, we found that Adobe Acrobat Reader 4 and 5 ignore 198 * FontMatrix.ty . 199 */ 200 copied->FontMatrix.tx = copied->FontMatrix.ty = 0; 201 } 202 switch (font->FontType) { 203 case ft_encrypted: 204 case ft_encrypted2: 205 pbfont->do_subset = (is_standard ? DO_SUBSET_NO : DO_SUBSET_UNKNOWN); 206 /* We will count the number of glyphs below. */ 207 pbfont->num_glyphs = -1; 208 break; 209 case ft_TrueType: 210 pbfont->num_glyphs = ((gs_font_type42 *)font)->data.trueNumGlyphs; 211 pbfont->do_subset = 212 (pbfont->num_glyphs <= MAX_NO_SUBSET_GLYPHS ? 213 DO_SUBSET_UNKNOWN : DO_SUBSET_YES); 214 break; 215 case ft_CID_encrypted: 216 pbfont->num_glyphs = ((gs_font_cid0 *)font)->cidata.common.CIDCount; 217 goto cid; 218 case ft_CID_TrueType: 219 pbfont->num_glyphs = ((gs_font_cid2 *)font)->cidata.common.CIDCount; 220 cid: 221 pbfont->do_subset = DO_SUBSET_YES; 222 pbfont->CIDSet = 223 gs_alloc_bytes(mem, (pbfont->num_glyphs + 7) / 8, 224 "pdf_base_font_alloc(CIDSet)"); 225 if (pbfont->CIDSet == 0) { 226 code = gs_note_error(gs_error_VMerror); 227 goto fail; 228 } 229 memset(pbfont->CIDSet, 0, (pbfont->num_glyphs + 7) / 8); 230 break; 231 default: 232 code = gs_note_error(gs_error_rangecheck); 233 goto fail; 234 } 235 if (pbfont->do_subset != DO_SUBSET_YES) { 236 /* The only possibly non-subsetted fonts are Type 1/2 and Type 42. */ 237 if (is_standard) 238 complete = copied, code = 0; 239 else 240 code = gs_copy_font((gs_font *)font, &font->FontMatrix, mem, &complete); 241 if (code >= 0) 242 code = gs_copy_font_complete((gs_font *)font, complete); 243 if (pbfont->num_glyphs < 0) { /* Type 1 */ 244 int index, count; 245 gs_glyph glyph; 246 247 for (index = 0, count = 0; 248 (font->procs.enumerate_glyph((gs_font *)font, &index, 249 GLYPH_SPACE_NAME, &glyph), 250 index != 0); 251 ) 252 ++count; 253 pbfont->num_glyphs = count; 254 } 255 } else 256 complete = copied; 257 pbfont->copied = (gs_font_base *)copied; 258 pbfont->complete = (gs_font_base *)complete; 259 pbfont->is_standard = is_standard; 260 if (pfname->size > 0) { 261 font_name.data = pfname->chars; 262 font_name.size = pfname->size; 263 while (pdf_has_subset_prefix(font_name.data, font_name.size)) { 264 /* Strip off an existing subset prefix. */ 265 font_name.data += SUBSET_PREFIX_SIZE; 266 font_name.size -= SUBSET_PREFIX_SIZE; 267 } 268 } else { 269 sprintf(fnbuf, ".F%lx", (ulong)copied); 270 font_name.data = (byte *)fnbuf; 271 font_name.size = strlen(fnbuf); 272 } 273 pbfont->font_name.data = 274 gs_alloc_string(mem, font_name.size, "pdf_base_font_alloc(font_name)"); 275 if (pbfont->font_name.data == 0) 276 goto fail; 277 memcpy(pbfont->font_name.data, font_name.data, font_name.size); 278 pbfont->font_name.size = font_name.size; 279 *ppbfont = pbfont; 280 return 0; 281 fail: 282 gs_free_object(mem, pbfont, "pdf_base_font_alloc"); 283 return code; 284 } 285 286 /* 287 * Return a reference to the name of a base font. This name is guaranteed 288 * not to have a XXXXXX+ prefix. The client may change the name at will, 289 * but must not add a XXXXXX+ prefix. 290 */ 291 gs_string * 292 pdf_base_font_name(pdf_base_font_t *pbfont) 293 { 294 return &pbfont->font_name; 295 } 296 297 /* 298 * Return the (copied, subset) font associated with a base font. 299 * This procedure probably shouldn't exist.... 300 */ 301 gs_font_base * 302 pdf_base_font_font(const pdf_base_font_t *pbfont, bool complete) 303 { 304 return (complete ? pbfont->complete : pbfont->copied); 305 } 306 307 /* 308 * Check for subset font. 309 */ 310 bool 311 pdf_base_font_is_subset(const pdf_base_font_t *pbfont) 312 { 313 return pbfont->do_subset == DO_SUBSET_YES; 314 } 315 316 /* 317 * Drop the copied complete font associated with a base font. 318 */ 319 void 320 pdf_base_font_drop_complete(pdf_base_font_t *pbfont) 321 { 322 pbfont->complete = NULL; 323 } 324 325 /* 326 * Copy a glyph (presumably one that was just used) into a saved base 327 * font. Note that it is the client's responsibility to determine that 328 * the source font is compatible with the target font. (Normally they 329 * will be the same.) 330 */ 331 int 332 pdf_base_font_copy_glyph(pdf_base_font_t *pbfont, gs_glyph glyph, 333 gs_font_base *font) 334 { 335 int code = 336 gs_copy_glyph_options((gs_font *)font, glyph, 337 (gs_font *)pbfont->copied, 338 (pbfont->is_standard ? COPY_GLYPH_NO_NEW : 0)); 339 340 if (code < 0) 341 return code; 342 if (pbfont->CIDSet != 0 && 343 (uint)(glyph - GS_MIN_CID_GLYPH) < pbfont->num_glyphs 344 ) { 345 uint cid = glyph - GS_MIN_CID_GLYPH; 346 347 pbfont->CIDSet[cid >> 3] |= 0x80 >> (cid & 7); 348 } 349 return 0; 350 } 351 352 /* 353 * Determine whether a font should be subsetted. 354 */ 355 bool 356 pdf_do_subset_font(gx_device_pdf *pdev, pdf_base_font_t *pbfont, gs_id rid) 357 { 358 gs_font_base *copied = pbfont->copied; 359 360 /* 361 * If the decision has not been made already, determine whether or not 362 * to subset the font. 363 */ 364 if (pbfont->do_subset == DO_SUBSET_UNKNOWN) { 365 int max_pct = pdev->params.MaxSubsetPct; 366 bool do_subset = pdev->params.SubsetFonts && max_pct > 0; 367 368 if (do_subset && max_pct < 100) { 369 /* We want to subset iff used <= total * MaxSubsetPct / 100. */ 370 do_subset = false; 371 if (max_pct > 0) { 372 int max_subset_used = pbfont->num_glyphs * max_pct / 100; 373 int used, index; 374 gs_glyph ignore_glyph; 375 376 do_subset = true; 377 for (index = 0, used = 0; 378 (copied->procs.enumerate_glyph((gs_font *)copied, 379 &index, GLYPH_SPACE_INDEX, 380 &ignore_glyph), index != 0); 381 ) 382 if (++used > max_subset_used) { 383 do_subset = false; 384 break; 385 } 386 } 387 } 388 pbfont->do_subset = (do_subset ? DO_SUBSET_YES : DO_SUBSET_NO); 389 } 390 return (pbfont->do_subset == DO_SUBSET_YES); 391 } 392 393 /* 394 * Write the FontFile entry for an embedded font, /FontFile<n> # # R. 395 */ 396 int 397 pdf_write_FontFile_entry(gx_device_pdf *pdev, pdf_base_font_t *pbfont) 398 { 399 stream *s = pdev->strm; 400 const char *FontFile_key; 401 402 switch (pbfont->copied->FontType) { 403 case ft_TrueType: 404 case ft_CID_TrueType: 405 FontFile_key = "/FontFile2"; 406 break; 407 default: /* Type 1/2, CIDFontType 0 */ 408 if (pdev->ResourcesBeforeUsage) 409 FontFile_key = "/FontFile"; 410 else 411 FontFile_key = "/FontFile3"; 412 } 413 stream_puts(s, FontFile_key); 414 pprintld1(s, " %ld 0 R", pbfont->FontFile->id); 415 return 0; 416 } 417 418 /* 419 * Adjust font name for Acrobat Reader 3. 420 */ 421 private int 422 pdf_adjust_font_name(gx_device_pdf *pdev, long id, pdf_base_font_t *pbfont) 423 { 424 /* 425 * In contradiction with previous version of pdfwrite, 426 * this always adds a suffix. We don't check the original name 427 * for uniquity bacause the layered architecture 428 * (see gdevpdtx.h) doesn't provide an easy access for 429 * related information. 430 */ 431 int i; 432 byte *chars = (byte *)pbfont->font_name.data; /* break 'const' */ 433 byte *data; 434 uint size = pbfont->font_name.size; 435 char suffix[sizeof(long) * 2 + 2]; 436 uint suffix_size; 437 438 #define SUFFIX_CHAR '~' 439 /* 440 * If the name looks as though it has one of our unique suffixes, 441 * remove the suffix. 442 */ 443 for (i = size; 444 i > 0 && isxdigit(chars[i - 1]); 445 --i) 446 DO_NOTHING; 447 if (i < size && i > 0 && chars[i - 1] == SUFFIX_CHAR) { 448 do { 449 --i; 450 } while (i > 0 && chars[i - 1] == SUFFIX_CHAR); 451 size = i + 1; 452 } 453 /* Create a unique name. */ 454 sprintf(suffix, "%c%lx", SUFFIX_CHAR, id); 455 suffix_size = strlen(suffix); 456 data = gs_resize_string(pdev->pdf_memory, chars, size, 457 size + suffix_size, 458 "pdf_adjust_font_name"); 459 if (data == 0) 460 return_error(gs_error_VMerror); 461 memcpy(data + size, (const byte *)suffix, suffix_size); 462 pbfont->font_name.data = data; 463 pbfont->font_name.size = size + suffix_size; 464 #undef SUFFIX_CHAR 465 return 0; 466 } 467 468 /* 469 * Write an embedded font. 470 */ 471 int 472 pdf_write_embedded_font(gx_device_pdf *pdev, pdf_base_font_t *pbfont, 473 gs_int_rect *FontBBox, gs_id rid, cos_dict_t **ppcd) 474 { 475 bool do_subset = pdf_do_subset_font(pdev, pbfont, rid); 476 gs_font_base *out_font = 477 (do_subset || pbfont->complete == NULL ? pbfont->copied : pbfont->complete); 478 gs_const_string fnstr; 479 pdf_data_writer_t writer; 480 int code; 481 482 if (pbfont->written) 483 return 0; /* already written */ 484 code = pdf_begin_data_stream(pdev, &writer, DATA_STREAM_BINARY | 485 /* Don't set DATA_STREAM_ENCRYPT since we write to a temporary file. 486 See comment in pdf_begin_encrypt. */ 487 (pdev->CompressFonts ? 488 DATA_STREAM_COMPRESS : 0), 0); 489 if (code < 0) 490 return code; 491 if (pdev->CompatibilityLevel == 1.2 && 492 !do_subset && !pbfont->is_standard ) { 493 /* 494 * Due to a bug in Acrobat Reader 3, we need to generate 495 * unique font names, except base 14 fonts being not embedded. 496 * To recognize base 14 fonts here we used the knowledge 497 * that pbfont->is_standard is true for base 14 fonts only. 498 * Note that subsetted fonts already have an unique name 499 * due to subset prefix. 500 */ 501 int code = pdf_adjust_font_name(pdev, writer.pres->object->id, pbfont); 502 if (code < 0) 503 return code; 504 } 505 fnstr.data = pbfont->font_name.data; 506 fnstr.size = pbfont->font_name.size; 507 /* Now write the font (or subset). */ 508 switch (out_font->FontType) { 509 510 case ft_composite: 511 /* Nothing to embed -- the descendant fonts do it all. */ 512 code = 0; 513 break; 514 515 case ft_encrypted2: 516 if (!pdev->HaveCFF) { 517 /* Must convert to Type 1 charstrings. */ 518 return_error(gs_error_unregistered); /* Not implemented yet. */ 519 } 520 case ft_encrypted: 521 if (pdev->HavePDFWidths) { 522 code = copied_drop_extension_glyphs((gs_font *)out_font); 523 if (code < 0) 524 return code; 525 } 526 if (!pdev->HaveCFF) { 527 /* Write the type 1 font with no converting to CFF. */ 528 int lengths[3]; 529 530 code = psf_write_type1_font(writer.binary.strm, 531 (gs_font_type1 *)out_font, 532 WRITE_TYPE1_WITH_LENIV | 533 WRITE_TYPE1_EEXEC | WRITE_TYPE1_EEXEC_PAD, 534 NULL, 0, &fnstr, lengths); 535 if (lengths[0] > 0) { 536 if (code < 0) 537 return code; 538 code = cos_dict_put_c_key_int((cos_dict_t *)writer.pres->object, 539 "/Length1", lengths[0]); 540 } 541 if (lengths[1] > 0) { 542 if (code < 0) 543 return code; 544 code = cos_dict_put_c_key_int((cos_dict_t *)writer.pres->object, 545 "/Length2", lengths[1]); 546 if (code < 0) 547 return code; 548 code = cos_dict_put_c_key_int((cos_dict_t *)writer.pres->object, 549 "/Length3", lengths[2]); 550 } 551 } else { 552 /* 553 * Since we only support PDF 1.2 and later, always write Type 1 554 * fonts as Type1C (Type 2). Acrobat Reader apparently doesn't 555 * accept CFF fonts with Type 1 CharStrings, so we need to convert 556 * them. Also remove lenIV, so Type 2 fonts will compress better. 557 */ 558 #define TYPE2_OPTIONS (WRITE_TYPE2_NO_LENIV | WRITE_TYPE2_CHARSTRINGS) 559 code = cos_dict_put_string_copy((cos_dict_t *)writer.pres->object, "/Subtype", "/Type1C"); 560 if (code < 0) 561 return code; 562 code = psf_write_type2_font(writer.binary.strm, 563 (gs_font_type1 *)out_font, 564 TYPE2_OPTIONS | 565 (pdev->CompatibilityLevel < 1.3 ? WRITE_TYPE2_AR3 : 0), 566 NULL, 0, &fnstr, FontBBox); 567 } 568 goto finish; 569 570 case ft_TrueType: { 571 gs_font_type42 *const pfont = (gs_font_type42 *)out_font; 572 #define TRUETYPE_OPTIONS (WRITE_TRUETYPE_NAME | WRITE_TRUETYPE_HVMTX) 573 /* Acrobat Reader 3 doesn't handle cmap format 6 correctly. */ 574 const int options = TRUETYPE_OPTIONS | 575 (pdev->CompatibilityLevel <= 1.2 ? 576 WRITE_TRUETYPE_NO_TRIMMED_TABLE : 0) | 577 /* Generate a cmap only for incrementally downloaded fonts 578 and for subsetted fonts. */ 579 (pfont->data.numGlyphs != pfont->data.trueNumGlyphs || 580 pbfont->do_subset == DO_SUBSET_YES ? 581 WRITE_TRUETYPE_CMAP : 0); 582 stream poss; 583 584 if (pdev->HavePDFWidths) { 585 code = copied_drop_extension_glyphs((gs_font *)out_font); 586 if (code < 0) 587 return code; 588 } 589 s_init(&poss, pdev->memory); 590 swrite_position_only(&poss); 591 code = psf_write_truetype_font(&poss, pfont, options, NULL, 0, &fnstr); 592 if (code < 0) 593 return code; 594 code = cos_dict_put_c_key_int((cos_dict_t *)writer.pres->object, "/Length1", stell(&poss)); 595 if (code < 0) 596 return code; 597 if (code < 0) 598 return code; 599 code = psf_write_truetype_font(writer.binary.strm, pfont, 600 options, NULL, 0, &fnstr); 601 goto finish; 602 } 603 604 case ft_CID_encrypted: 605 code = cos_dict_put_string_copy((cos_dict_t *)writer.pres->object, "/Subtype", "/CIDFontType0C"); 606 if (code < 0) 607 return code; 608 code = psf_write_cid0_font(writer.binary.strm, 609 (gs_font_cid0 *)out_font, TYPE2_OPTIONS, 610 NULL, 0, &fnstr); 611 goto finish; 612 613 case ft_CID_TrueType: 614 /* CIDFontType 2 fonts don't use cmap, name, OS/2, or post. */ 615 #define CID2_OPTIONS WRITE_TRUETYPE_HVMTX 616 code = psf_write_cid2_font(writer.binary.strm, 617 (gs_font_cid2 *)out_font, 618 CID2_OPTIONS, NULL, 0, &fnstr); 619 finish: 620 *ppcd = (cos_dict_t *)writer.pres->object; 621 if (code < 0) { 622 pdf_end_fontfile(pdev, &writer); 623 return code; 624 } 625 code = pdf_end_fontfile(pdev, &writer); 626 break; 627 628 default: 629 code = gs_note_error(gs_error_rangecheck); 630 } 631 632 pbfont->written = true; 633 return code; 634 } 635 636 /* 637 * Write the CharSet for a subsetted font, as a PDF string. 638 */ 639 int 640 pdf_write_CharSet(gx_device_pdf *pdev, pdf_base_font_t *pbfont) 641 { 642 stream *s = pdev->strm; 643 gs_font_base *font = pbfont->copied; 644 int index; 645 gs_glyph glyph; 646 647 stream_puts(s, "("); 648 for (index = 0; 649 (font->procs.enumerate_glyph((gs_font *)font, &index, 650 GLYPH_SPACE_NAME, &glyph), 651 index != 0); 652 ) { 653 gs_const_string gstr; 654 int code = font->procs.glyph_name((gs_font *)font, glyph, &gstr); 655 656 /* Don't include .notdef. */ 657 if (code >= 0 && 658 bytes_compare(gstr.data, gstr.size, (const byte *)".notdef", 7) 659 ) 660 pdf_put_name(pdev, gstr.data, gstr.size); 661 } 662 stream_puts(s, ")"); 663 return 0; 664 } 665 666 /* 667 * Write the CIDSet object for a subsetted CIDFont. 668 */ 669 int 670 pdf_write_CIDSet(gx_device_pdf *pdev, pdf_base_font_t *pbfont, 671 long *pcidset_id) 672 { 673 pdf_data_writer_t writer; 674 int code; 675 676 code = pdf_begin_data_stream(pdev, &writer, 677 DATA_STREAM_BINARY | 678 (pdev->CompressFonts ? DATA_STREAM_COMPRESS : 0), 679 gs_no_id); 680 if (code < 0) 681 return code; 682 stream_write(writer.binary.strm, pbfont->CIDSet, 683 (pbfont->num_glyphs + 7) / 8); 684 code = pdf_end_data(&writer); 685 if (code < 0) 686 return code; 687 *pcidset_id = pdf_resource_id(writer.pres); 688 return 0; 689 } 690 /* 691 * Check whether a base font is standard. 692 */ 693 bool 694 pdf_is_standard_font(pdf_base_font_t *bfont) 695 { return bfont->is_standard; 696 } 697 698 void 699 pdf_set_FontFile_object(pdf_base_font_t *bfont, cos_dict_t *pcd) 700 { 701 bfont->FontFile = pcd; 702 } 703 const cos_dict_t * 704 pdf_get_FontFile_object(pdf_base_font_t *bfont) 705 { 706 return bfont->FontFile; 707 } 708