Warning: Attempt to read property "date" on null in /usr/local/www/websvn.planix.org/blame.php on line 247

Warning: Attempt to read property "msg" on null in /usr/local/www/websvn.planix.org/blame.php on line 247
WebSVN – planix.SVN – Blame – /os/branches/feature_tlsv12/sys/src/cmd/gs/src/gdevpdtb.c – Rev 2

Subversion Repositories planix.SVN

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 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
}