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 };
BASIC_PTRS(pdf_base_font_ptrs)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
pdf_has_subset_prefix(const byte * str,uint size)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
hash(ulong v,int index,ushort w)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
pdf_add_subset_prefix(const gx_device_pdf * pdev,gs_string * pstr,byte * used,int count)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
pdf_end_fontfile(gx_device_pdf * pdev,pdf_data_writer_t * pdw)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
pdf_base_font_alloc(gx_device_pdf * pdev,pdf_base_font_t ** ppbfont,gs_font_base * font,const gs_matrix * orig_matrix,bool is_standard,bool orig_name)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 *
pdf_base_font_name(pdf_base_font_t * pbfont)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 *
pdf_base_font_font(const pdf_base_font_t * pbfont,bool complete)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
pdf_base_font_is_subset(const pdf_base_font_t * pbfont)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
pdf_base_font_drop_complete(pdf_base_font_t * pbfont)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
pdf_base_font_copy_glyph(pdf_base_font_t * pbfont,gs_glyph glyph,gs_font_base * font)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
pdf_do_subset_font(gx_device_pdf * pdev,pdf_base_font_t * pbfont,gs_id rid)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
pdf_write_FontFile_entry(gx_device_pdf * pdev,pdf_base_font_t * pbfont)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
pdf_adjust_font_name(gx_device_pdf * pdev,long id,pdf_base_font_t * pbfont)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
pdf_write_embedded_font(gx_device_pdf * pdev,pdf_base_font_t * pbfont,gs_int_rect * FontBBox,gs_id rid,cos_dict_t ** ppcd)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
pdf_write_CharSet(gx_device_pdf * pdev,pdf_base_font_t * pbfont)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
pdf_write_CIDSet(gx_device_pdf * pdev,pdf_base_font_t * pbfont,long * pcidset_id)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
pdf_is_standard_font(pdf_base_font_t * bfont)694 pdf_is_standard_font(pdf_base_font_t *bfont)
695 { return bfont->is_standard;
696 }
697
698 void
pdf_set_FontFile_object(pdf_base_font_t * bfont,cos_dict_t * pcd)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 *
pdf_get_FontFile_object(pdf_base_font_t * bfont)704 pdf_get_FontFile_object(pdf_base_font_t *bfont)
705 {
706 return bfont->FontFile;
707 }
708