1
/* Copyright (C) 2001-2012 Artifex Software, Inc.
4
This software is provided AS-IS with no warranty, either express or
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.
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.
17
/* FontDescriptor implementation for pdfwrite */
22
#include "gsrect.h" /* for rect_merge */
26
#include "gdevpdfo.h" /* for object->written */
31
/* ================ Types and structures ================ */
34
* There are many different flavors of FontDescriptor. The first division
35
* is between FontDescriptors for actual fonts, and character class entries
36
* in the FD dictionary of a CID-keyed font. The latter include metrics and
37
* a FontName but nothing else. We represent these with a different C
38
* structure (pdf_sub_font_descriptor_t).
40
* Descriptors for actual fonts have three major orthogonal properties:
42
* - Whether they represent a CID-keyed font or a name-keyed
43
* (non-CID-keyed) font. We distinguish this by the FontType
44
* of the saved font (see below).
46
* - Whether the font they represent is embedded.
48
* - Whether the font they represent is a complete font or a subset.
49
* We always track which glyphs in a font are used: client code
50
* decides whether to treat the font as a subset when the
51
* descriptor (and, if embedded, the font) is written.
53
* Note that non-embedded fonts in the base set of 14 do not have
54
* descriptors, nor do Type 0 or (synthetic bitmap) Type 3 fonts.
57
* Start by defining the elements common to font descriptors and sub-font
58
* (character class) descriptors.
60
typedef struct pdf_font_descriptor_values_s {
61
/* Required elements */
62
int Ascent, CapHeight, Descent, ItalicAngle, StemV;
66
/* Optional elements (default to 0) */
67
int AvgWidth, Leading, MaxWidth, MissingWidth, StemH, XHeight;
68
} pdf_font_descriptor_values_t;
69
typedef struct pdf_font_descriptor_common_s pdf_font_descriptor_common_t;
70
struct pdf_font_descriptor_common_s {
71
pdf_resource_common(pdf_font_descriptor_common_t);
72
pdf_font_descriptor_values_t values;
75
/*#define FONT_IS_FIXED_WIDTH (1<<0)*/ /* defined in gxfont.h */
76
#define FONT_IS_SERIF (1<<1)
77
#define FONT_IS_SYMBOLIC (1<<2)
78
#define FONT_IS_SCRIPT (1<<3)
80
* There is confusion over the meaning of the 1<<5 bit. According to the
81
* published PDF documentation, in PDF 1.1, it meant "font uses
82
* StandardEncoding", and as of PDF 1.2, it means "font uses (a subset of)
83
* the Adobe standard Latin character set"; however, Acrobat Reader 3 and 4
84
* seem to use the former interpretation, even if the font is embedded and
85
* the file is identified as a PDF 1.2 file. We have to use the former
86
* interpretation in order to produce output that Acrobat will handle
89
#define FONT_USES_STANDARD_ENCODING (1<<5) /* always used */
90
#define FONT_IS_ADOBE_ROMAN (1<<5) /* never used */
91
#define FONT_IS_ITALIC (1<<6)
92
#define FONT_IS_ALL_CAPS (1<<16)
93
#define FONT_IS_SMALL_CAPS (1<<17)
94
#define FONT_IS_FORCE_BOLD (1<<18)
97
* Define a (top-level) FontDescriptor. CID-keyed vs. non-CID-keyed fonts
98
* are distinguished by their FontType.
100
#ifndef pdf_base_font_DEFINED
101
# define pdf_base_font_DEFINED
102
typedef struct pdf_base_font_s pdf_base_font_t;
104
struct pdf_font_descriptor_s {
105
pdf_font_descriptor_common_t common;
106
pdf_base_font_t *base_font;
107
font_type FontType; /* (copied from base_font) */
109
struct cid_ { /* (CIDFonts only) */
111
char Lang[3]; /* 2 chars + \0 */
112
cos_dict_t *FD; /* value = COS_VALUE_RESOURCE */
116
* Define a sub-descriptor for a character class (FD dictionary element).
118
typedef struct pdf_sub_font_descriptor_s {
119
pdf_font_descriptor_common_t common;
120
} pdf_sub_font_descriptor_t;
123
* Font descriptors are pseudo-resources, so their GC descriptors
126
BASIC_PTRS(pdf_font_descriptor_ptrs) {
127
GC_STRING_ELT(pdf_font_descriptor_t, common.values.FontName),
128
GC_OBJ_ELT(pdf_font_descriptor_t, base_font),
129
GC_OBJ_ELT(pdf_font_descriptor_t, cid.Style),
130
GC_OBJ_ELT(pdf_font_descriptor_t, cid.FD)
132
gs_public_st_basic_super(st_pdf_font_descriptor, pdf_font_descriptor_t,
133
"pdf_font_descriptor_t", pdf_font_descriptor_ptrs,
134
pdf_font_descriptor_data, &st_pdf_resource, 0);
137
* Sub-font descriptors are also pseudo-resources.
139
BASIC_PTRS(pdf_sub_font_descriptor_ptrs) {
140
GC_STRING_ELT(pdf_sub_font_descriptor_t, common.values.FontName)
142
gs_public_st_basic_super(st_pdf_sub_font_descriptor,
143
pdf_sub_font_descriptor_t, "pdf_sub_font_descriptor_t",
144
pdf_sub_font_descriptor_ptrs, pdf_sub_font_descriptor_data,
145
&st_pdf_resource, 0);
147
/* ================ Procedures ================ */
149
/* ---------------- Private ---------------- */
151
/* Get the ID of font descriptor metrics. */
153
pdf_font_descriptor_common_id(const pdf_font_descriptor_common_t *pfdc)
155
return pdf_resource_id((const pdf_resource_t *)pfdc);
158
/* Write the common part of a FontDescriptor, aside from the final >>. */
160
write_FontDescriptor_common(gx_device_pdf *pdev,
161
const pdf_font_descriptor_common_t *pfd, bool embed)
165
param_printer_params_t params;
166
printer_param_list_t rlist;
167
gs_param_list *const plist = (gs_param_list *)&rlist;
168
char *base14_name = NULL;
170
pdf_open_separate(pdev, pdf_font_descriptor_common_id(pfd), resourceFontDescriptor);
172
stream_puts(s, "<</Type/FontDescriptor/FontName");
174
base14_name = (char *)pdf_find_base14_name(pfd->values.FontName.data, pfd->values.FontName.size);
176
pdf_put_name(pdev, (byte *)base14_name, strlen(base14_name));
178
pdf_put_name(pdev, pfd->values.FontName.data, pfd->values.FontName.size);
180
pdf_put_name(pdev, pfd->values.FontName.data, pfd->values.FontName.size);
182
pdf_write_font_bbox(pdev, &pfd->values.FontBBox);
183
params = param_printer_params_default;
184
code = s_init_param_printer(&rlist, ¶ms, s);
186
#define DESC_INT(str, memb)\
187
{str, gs_param_type_int, offset_of(pdf_font_descriptor_common_t, values.memb)}
188
static const gs_param_item_t required_items[] = {
189
DESC_INT("Ascent", Ascent),
190
DESC_INT("CapHeight", CapHeight),
191
DESC_INT("Descent", Descent),
192
DESC_INT("ItalicAngle", ItalicAngle),
193
DESC_INT("StemV", StemV),
196
static const gs_param_item_t optional_items[] = {
197
DESC_INT("AvgWidth", AvgWidth),
198
DESC_INT("Leading", Leading),
199
DESC_INT("MaxWidth", MaxWidth),
200
DESC_INT("MissingWidth", MissingWidth),
201
DESC_INT("StemH", StemH),
202
DESC_INT("XHeight", XHeight),
206
int Flags = pfd->values.Flags;
207
pdf_font_descriptor_t defaults;
210
Flags |=FONT_USES_STANDARD_ENCODING;
212
code = param_write_int(plist, "Flags", &Flags);
215
code = gs_param_write_items(plist, pfd, NULL, required_items);
218
memset(&defaults, 0, sizeof(defaults));
219
code = gs_param_write_items(plist, pfd, &defaults, optional_items);
222
s_release_param_printer(&rlist);
227
/* ---------------- Public ---------------- */
230
* Allocate a FontDescriptor, initializing the FontType and rid from the
234
pdf_font_descriptor_alloc(gx_device_pdf *pdev, pdf_font_descriptor_t **ppfd,
235
gs_font_base *font, bool embed)
237
pdf_font_descriptor_t *pfd;
238
pdf_base_font_t *pbfont;
239
int code = pdf_base_font_alloc(pdev, &pbfont, font,
240
(font->orig_FontMatrix.xx == 0 && font->orig_FontMatrix.xy == 0
241
? &font->FontMatrix : &font->orig_FontMatrix), false);
245
code = pdf_alloc_resource(pdev, resourceFontDescriptor,
246
font->id, (pdf_resource_t **)&pfd, -1L);
248
gs_free_object(pdev->pdf_memory, pbfont,
249
"pdf_font_descriptor_alloc(base_font)");
252
memset(&pfd->common.values, 0,
253
sizeof(*pfd) - offset_of(pdf_font_descriptor_t, common.values));
254
pfd->base_font = pbfont;
255
pfd->FontType = font->FontType;
261
int pdf_font_descriptor_free(gx_device_pdf *pdev, pdf_resource_t *pres)
263
pdf_font_descriptor_t *pfd = (pdf_font_descriptor_t *)pres;
264
pdf_base_font_t *pbfont = pfd->base_font;
265
gs_font *copied = (gs_font *)pbfont->copied;
267
gs_free_copied_font(copied);
268
if (pbfont && pbfont->font_name.size) {
269
gs_free_string(pdev->memory, pbfont->font_name.data, pbfont->font_name.size, "Free BaseFont FontName string");
270
pbfont->font_name.data = (byte *)0L;
271
pbfont->font_name.size = 0;
274
gs_free_object(cos_object_memory(pres->object), pbfont, "Free base font from FontDescriptor)");
276
gs_free_object(cos_object_memory(pres->object), pres->object, "free FontDescriptor object");
282
/* Get the object ID of a FontDescriptor. */
284
pdf_font_descriptor_id(const pdf_font_descriptor_t *pfd)
286
return pdf_resource_id((const pdf_resource_t *)pfd);
289
long pdf_set_font_descriptor_usage(gx_device_pdf *pdev, int parent_id, const pdf_font_descriptor_t *pfd)
291
int id = pdf_resource_id((const pdf_resource_t *)pfd);
293
pdf_record_usage_by_parent(pdev, id, parent_id);
294
if (pfd->base_font->FontFile) {
295
id = pfd->base_font->FontFile->id;
296
pdf_record_usage_by_parent(pdev, id, parent_id);
302
* Get the FontType of a FontDescriptor.
305
pdf_font_descriptor_FontType(const pdf_font_descriptor_t *pfd)
307
return pfd->FontType;
311
* Get the embedding status of a FontDescriptor.
314
pdf_font_descriptor_embedding(const pdf_font_descriptor_t *pfd)
320
* Check for subset font.
323
pdf_font_descriptor_is_subset(const pdf_font_descriptor_t *pfd)
325
return pdf_base_font_is_subset(pfd->base_font);
329
* Return a reference to the FontName of a FontDescriptor, similar to
330
* pdf_base_font_name.
332
gs_string *pdf_font_descriptor_name(pdf_font_descriptor_t *pfd)
334
return &pfd->common.values.FontName;
337
char *pdf_fontfile_hash(void *pfd)
339
pdf_font_descriptor_t *fd = (pdf_font_descriptor_t *)pfd;
342
if (fd->base_font && fd->base_font->FontFile) {
343
pcd = (cos_dict_t *)fd->base_font->FontFile;
344
if (pcd->stream_md5_valid)
345
return ((char *)pcd->stream_hash);
353
* Return the (copied, subset or complete) font associated with a FontDescriptor.
354
* This procedure probably shouldn't exist....
357
pdf_font_descriptor_font(const pdf_font_descriptor_t *pfd, bool complete)
359
return pdf_base_font_font(pfd->base_font, complete);
363
* Drop the copied complete font associated with a FontDescriptor.
366
pdf_font_descriptor_drop_complete_font(const pdf_font_descriptor_t *pfd)
368
pdf_base_font_drop_complete(pfd->base_font);
372
* Return a reference to the name of a FontDescriptor's base font, per
373
* pdf_base_font_name.
375
gs_string *pdf_font_descriptor_base_name(const pdf_font_descriptor_t *pfd)
377
return pdf_base_font_name(pfd->base_font);
381
* Copy a glyph from a font to the stable copy. Return 0 if this is a
382
* new glyph, 1 if it was already copied.
385
pdf_font_used_glyph(pdf_font_descriptor_t *pfd, gs_glyph glyph,
388
return pdf_base_font_copy_glyph(pfd->base_font, glyph, font);
391
/* Compute the FontDescriptor metrics for a font. */
393
pdf_compute_font_descriptor(gx_device_pdf *pdev, pdf_font_descriptor_t *pfd)
395
gs_font_base *bfont = pdf_base_font_font(pfd->base_font, false);
396
gs_glyph glyph, notdef;
398
int wmode = bfont->WMode;
399
int members = (GLYPH_INFO_WIDTH0 << wmode) |
400
GLYPH_INFO_BBOX | GLYPH_INFO_NUM_PIECES;
401
pdf_font_descriptor_values_t desc;
403
gs_matrix *pmat = NULL;
405
int small_descent = 0, small_height = 0;
406
bool small_present = false;
409
gs_rect bbox_colon, bbox_period, bbox_I;
410
bool is_cid = (bfont->FontType == ft_CID_encrypted ||
411
bfont->FontType == ft_CID_TrueType);
412
bool have_colon = false, have_period = false, have_I = false;
415
memset(&bbox_colon, 0, sizeof(bbox_colon)); /* quiet gcc warnings. */
416
memset(&bbox_period, 0, sizeof(bbox_period)); /* quiet gcc warnings. */
417
memset(&bbox_I, 0, sizeof(bbox_I)); /* quiet gcc warnings. */
418
memset(&desc, 0, sizeof(desc));
419
if (is_cid && bfont->FontBBox.p.x != bfont->FontBBox.q.x &&
420
bfont->FontBBox.p.y != bfont->FontBBox.q.y) {
421
int scale = (bfont->FontType == ft_TrueType || bfont->FontType == ft_CID_TrueType ? 1000 : 1);
423
desc.FontBBox.p.x = (int)(bfont->FontBBox.p.x * scale);
424
desc.FontBBox.p.y = (int)(bfont->FontBBox.p.y * scale);
425
desc.FontBBox.q.x = (int)(bfont->FontBBox.q.x * scale);
426
desc.FontBBox.q.y = (int)(bfont->FontBBox.q.y * scale);
427
desc.Ascent = desc.FontBBox.q.y;
428
members &= ~GLYPH_INFO_BBOX;
430
desc.FontBBox.p.x = desc.FontBBox.p.y = max_int;
431
desc.FontBBox.q.x = desc.FontBBox.q.y = min_int;
434
* Embedded TrueType fonts use a 1000-unit character space, but the
435
* font itself uses a 1-unit space. Compensate for this here.
437
switch (bfont->FontType) {
439
case ft_CID_TrueType:
440
gs_make_scaling(1000.0, 1000.0, &smat);
442
/* Type 3 fonts may use a FontMatrix in PDF, so we don't
443
* need to deal with non-standard matrices
446
case ft_PCL_user_defined:
447
case ft_GL2_stick_user_defined:
448
case ft_user_defined:
450
/* Other font types may use a non-standard (not 1000x1000) design grid
451
* The FontMatrix is used to map to the unit square. However PDF files
452
* don't allow FontMatrix entries, all fonts are nominally 1000x1000.
453
* If we have a font with a non-standard matrix we must account for that
454
* here by scaling the font outline.
457
gs_matrix_scale(&bfont->FontMatrix, 1000.0, 1000.0, &smat);
463
* Scan the entire glyph space to compute Ascent, Descent, FontBBox, and
464
* the fixed width if any. For non-symbolic fonts, also note the
465
* bounding boxes for Latin letters and a couple of other characters,
466
* for computing the remaining descriptor values (CapHeight,
467
* ItalicAngle, StemV, XHeight, and flags SERIF, SCRIPT, ITALIC,
468
* ALL_CAPS, and SMALL_CAPS). (The algorithms are pretty crude.)
470
notdef = GS_NO_GLYPH;
472
(bfont->procs.enumerate_glyph((gs_font *)bfont, &index,
473
(is_cid ? GLYPH_SPACE_INDEX : GLYPH_SPACE_NAME), &glyph)) >= 0 &&
476
gs_glyph_info_t info;
477
gs_const_string gname;
478
gs_glyph glyph_known_enc;
481
code = bfont->procs.glyph_info((gs_font *)bfont, glyph, pmat, members, &info);
482
if (code == gs_error_VMerror)
486
* Since this function may be indirtectly called from gx_device_finalize,
487
* we are unable to propagate error code to the interpreter.
488
* Therefore we skip it here hoping that few errors can be
489
* recovered by the integration through entire glyph set.
493
if (members & GLYPH_INFO_BBOX) {
494
/* rect_merge(desc.FontBBox, info.bbox); Expanding due to type cast :*/
495
if (info.bbox.p.x < desc.FontBBox.p.x) desc.FontBBox.p.x = (int)info.bbox.p.x;
496
if (info.bbox.q.x > desc.FontBBox.q.x) desc.FontBBox.q.x = (int)info.bbox.q.x;
497
if (info.bbox.p.y < desc.FontBBox.p.y) desc.FontBBox.p.y = (int)info.bbox.p.y;
498
if (info.bbox.q.y > desc.FontBBox.q.y) desc.FontBBox.q.y = (int)info.bbox.q.y;
499
if (!info.num_pieces)
500
desc.Ascent = max(desc.Ascent, (int)info.bbox.q.y);
502
if (notdef == GS_NO_GLYPH && gs_font_glyph_is_notdef(bfont, glyph)) {
504
desc.MissingWidth = (int)info.width[wmode].x;
506
if (info.width[wmode].y != 0)
507
fixed_width = min_int;
508
else if (fixed_width == 0)
509
fixed_width = (int)info.width[wmode].x;
510
else if (info.width[wmode].x != fixed_width)
511
fixed_width = min_int;
512
if (desc.Flags & FONT_IS_SYMBOLIC)
513
continue; /* skip Roman-only computation */
516
code = bfont->procs.glyph_name((gs_font *)bfont, glyph, &gname);
518
/* If we fail to get the glyph name, best assume this is a symbolic font */
519
desc.Flags |= FONT_IS_SYMBOLIC;
522
/* See if the glyph name is in any of the known encodings */
523
glyph_known_enc = gs_c_name_glyph(gname.data, gname.size);
524
if (glyph_known_enc == gs_no_glyph) {
525
desc.Flags |= FONT_IS_SYMBOLIC;
528
/* Finally check if the encoded glyph is in Standard Encoding */
529
/* gs_c_decode always fails to find .notdef, its always present so
530
* don't worry about it
532
if(strncmp(".notdef", (const char *)gname.data, gname.size)) {
533
position = gs_c_decode(glyph_known_enc, 0);
534
if (position == GS_NO_CHAR) {
535
desc.Flags |= FONT_IS_SYMBOLIC;
539
switch (gname.size) {
541
if (!memcmp(gname.data, "colon", 5))
542
bbox_colon = info.bbox, have_colon = true;
545
if (!memcmp(gname.data, "period", 6))
546
bbox_period = info.bbox, have_period = true;
554
if (gname.data[0] >= 'A' && gname.data[0] <= 'Z') {
555
cap_height = max(cap_height, (int)info.bbox.q.y);
556
if (gname.data[0] == 'I')
557
bbox_I = info.bbox, have_I = true;
558
} else if (gname.data[0] >= 'a' && gname.data[0] <= 'z') {
559
int y0 = (int)(info.bbox.p.y), y1 = (int)(info.bbox.q.y);
561
small_present = true;
562
switch (gname.data[0]) {
563
case 'b': case 'd': case 'f': case 'h':
564
case 'k': case 'l': case 't': /* ascender */
565
small_height = max(small_height, y1);
566
case 'i': /* anomalous ascent */
568
case 'j': /* descender with anomalous ascent */
569
small_descent = min(small_descent, y0);
571
case 'g': case 'p': case 'q': case 'y': /* descender */
572
small_descent = min(small_descent, y0);
573
default: /* no ascender or descender */
574
x_height = max(x_height, y1);
578
if (!(desc.Flags & FONT_IS_SYMBOLIC)) {
579
desc.Flags |= FONT_IS_ADOBE_ROMAN; /* required if not symbolic */
580
desc.XHeight = (int)x_height;
581
if (!small_present && (!pdev->PDFA != 0 || bfont->FontType != ft_TrueType))
582
desc.Flags |= FONT_IS_ALL_CAPS;
583
desc.CapHeight = cap_height;
585
* Look at various glyphs to determine ItalicAngle, StemV,
586
* SERIF, SCRIPT, and ITALIC.
588
if (have_colon && have_period) {
589
/* Calculate the dominant angle. */
591
(int)(atan2((bbox_colon.q.y - bbox_colon.p.y) -
592
(bbox_period.q.y - bbox_period.p.y),
593
(bbox_colon.q.x - bbox_colon.p.x) -
594
(bbox_period.q.x - bbox_period.p.x)) *
595
radians_to_degrees) - 90;
597
/* Normalize to [-90..90]. */
607
* For script or embellished fonts, we can get an angle that is
608
* slightly off from zero even for non-italic fonts.
609
* Compensate for this now.
611
if (angle <= 2 && angle >= -2)
613
desc.ItalicAngle = angle;
615
if (desc.ItalicAngle)
616
desc.Flags |= FONT_IS_ITALIC;
618
double wdot = bbox_period.q.x - bbox_period.p.x;
619
double wcolon = bbox_I.q.x - bbox_I.p.x;
620
double wI = bbox_period.q.x - bbox_period.p.x;
622
desc.StemV = (int)wdot;
623
if (wI > wcolon * 2.5 || wI > (bbox_period.q.y - bbox_period.p.y) * 0.25)
624
desc.Flags |= FONT_IS_SERIF;
627
if (desc.Ascent == 0)
628
desc.Ascent = desc.FontBBox.q.y;
629
desc.Descent = desc.FontBBox.p.y;
630
if (!(desc.Flags & (FONT_IS_SYMBOLIC | FONT_IS_ALL_CAPS)) &&
631
(small_descent > desc.Descent / 3 || desc.XHeight > small_height * 0.9) &&
632
(!pdev->PDFA != 0 || bfont->FontType != ft_TrueType)
634
desc.Flags |= FONT_IS_SMALL_CAPS;
635
if (fixed_width > 0 && (!pdev->PDFA != 0 || bfont->FontType != ft_TrueType)) {
636
desc.Flags |= FONT_IS_FIXED_WIDTH;
637
desc.AvgWidth = desc.MaxWidth = desc.MissingWidth = fixed_width;
639
if (desc.CapHeight == 0)
640
desc.CapHeight = desc.Ascent;
642
desc.StemV = (int)(desc.FontBBox.q.x * 0.15);
643
pfd->common.values = desc;
648
* Finish a FontDescriptor by computing the metric values, and then
649
* writing the associated embedded font if any.
652
pdf_finish_FontDescriptor(gx_device_pdf *pdev, pdf_resource_t *pres)
654
pdf_font_descriptor_t *pfd = (pdf_font_descriptor_t *)pres;
657
if (pfd->common.object->id == -1)
659
if (!pfd->common.object->written &&
660
(code = pdf_compute_font_descriptor(pdev, pfd)) >= 0 &&
662
(code = pdf_write_embedded_font(pdev, pfd->base_font,
664
&pfd->common.values.FontBBox,
665
pfd->common.rid, &pcd)) >= 0)
667
pdf_set_FontFile_object(pfd->base_font, pcd);
672
/* Write a FontDescriptor. */
674
pdf_write_FontDescriptor(gx_device_pdf *pdev, pdf_resource_t *pres)
676
pdf_font_descriptor_t *pfd = (pdf_font_descriptor_t *)pres;
677
font_type ftype = pfd->FontType;
682
if (pfd->common.object->written)
684
if (pfd->common.object->id == -1)
687
/* If this is a CIDFont subset, write the CIDSet now. */
689
case ft_CID_encrypted:
690
case ft_CID_TrueType:
691
if (pdf_do_subset_font(pdev, pfd->base_font, pfd->common.rid)) {
692
if (pdev->PDFA < 2) {
693
code = pdf_write_CIDSet(pdev, pfd->base_font, &cidset_id);
704
* Hack: make all embedded subset TrueType fonts "symbolic" to
705
* work around undocumented assumptions in Acrobat Reader.
707
pdf_font_descriptor_common_t fd;
710
if (pfd->embed && pfd->FontType == ft_TrueType /*&& !pdev->PDFA*/ &&
711
pdf_do_subset_font(pdev, pfd->base_font, pfd->common.rid)
714
(fd.values.Flags & ~(FONT_IS_ADOBE_ROMAN)) | FONT_IS_SYMBOLIC;
715
code = write_FontDescriptor_common(pdev, &fd, pfd->embed);
721
pprintld1(s, "/CIDSet %ld 0 R\n", cidset_id);
722
else if (pdf_do_subset_font(pdev, pfd->base_font, pfd->common.rid) &&
723
(ftype == ft_encrypted || ftype == ft_encrypted2)
725
stream_puts(s, "/CharSet");
726
code = pdf_write_CharSet(pdev, pfd->base_font);
731
code = pdf_write_FontFile_entry(pdev, pfd->base_font);
735
if (pfd->cid.Style) {
736
stream_puts(s, "/Style");
737
COS_WRITE(pfd->cid.Style, pdev);
739
if (pfd->cid.Lang[0]) {
740
pprints1(s, "/Lang(%s)", pfd->cid.Lang);
743
stream_puts(s, "/FD");
744
COS_WRITE(pfd->cid.FD, pdev);
746
stream_puts(s, ">>\n");
747
pdf_end_separate(pdev, resourceFontDescriptor);
748
pfd->common.object->written = true;
749
{ const cos_object_t *pco = (const cos_object_t *)pdf_get_FontFile_object(pfd->base_font);
751
if (pdev->is_ps2write)
752
pprintld1(s, "%%BeginResource: file (PDF FontFile obj_%ld)\n", pco->id);
753
code = COS_WRITE_OBJECT(pco, pdev, resourceNone);
762
* Release a FontDescriptor components.
765
pdf_release_FontDescriptor_components(gx_device_pdf *pdev, pdf_resource_t *pres)
767
pdf_font_descriptor_t *pfd = (pdf_font_descriptor_t *) pres;
769
gs_free_object(pdev->pdf_memory, pfd->base_font, "pdf_release_FontDescriptor_components");
770
pfd->base_font = NULL;
771
/* fixme: underimplemented. */
776
* Mark a FontDescriptor used in a text.
779
pdf_mark_font_descriptor_used(gx_device_pdf *pdev, pdf_font_descriptor_t *pfd)
781
if (pfd != NULL && pfd->common.object->id == -1)
782
pdf_reserve_object_id(pdev, (pdf_resource_t *)&pfd->common, 0);
787
* Convert True Type font descriptor into CID font descriptor for PDF/A.
790
pdf_convert_truetype_font_descriptor(gx_device_pdf *pdev, pdf_font_resource_t *pdfont)
792
pdf_font_descriptor_t *pfd = pdfont->FontDescriptor;
793
pdf_base_font_t *pbfont = pfd->base_font;
794
gs_font *pfont = (gs_font *)pbfont->copied;
796
/* Save the simple font descriptor data because CID font data overlap them. */
797
int FirstChar = pdfont->u.simple.FirstChar, LastChar = pdfont->u.simple.LastChar;
798
pdf_encoding_element_t *Encoding = pdfont->u.simple.Encoding;
799
int length_CIDSet = (pbfont->num_glyphs > LastChar ? (pbfont->num_glyphs + 7) / 8 : ((LastChar + 1) + 7 / 8));
800
int length_CIDToGIDMap = (pbfont->num_glyphs > LastChar ? pbfont->num_glyphs * sizeof(ushort) : (LastChar + 1) * sizeof(ushort));
802
pfd->FontType = ft_CID_TrueType;
803
pdfont->u.simple.Encoding = NULL; /* Drop due to overlapping against a garbager problem. */
804
pbfont->CIDSet = gs_alloc_bytes(pdev->pdf_memory, length_CIDSet,
805
"pdf_convert_truetype_font_descriptor");
806
if (pbfont->CIDSet == NULL)
807
return_error(gs_error_VMerror);
808
memset(pbfont->CIDSet, 0, length_CIDSet);
809
pdfont->u.cidfont.CIDToGIDMap = (ushort *)gs_alloc_bytes(pdev->pdf_memory,
810
length_CIDToGIDMap, "pdf_convert_truetype_font_descriptor");
811
if (pdfont->u.cidfont.CIDToGIDMap == NULL)
812
return_error(gs_error_VMerror);
813
memset(pdfont->u.cidfont.CIDToGIDMap, 0, length_CIDToGIDMap);
814
if(pdev->PDFA == 1) {
815
for (ch = FirstChar; ch <= LastChar; ch++) {
816
if (Encoding[ch].glyph != GS_NO_GLYPH) {
817
gs_glyph glyph = pfont->procs.encode_char(pfont, ch, GLYPH_SPACE_INDEX);
819
pbfont->CIDSet[ch / 8] |= 0x80 >> (ch % 8);
820
pdfont->u.cidfont.CIDToGIDMap[ch] = glyph - GS_MIN_GLYPH_INDEX;
823
/* Set the CIDSet bit for CID 0 (the /.notdef) which must always be present */
824
pbfont->CIDSet[0] |= 0x80;
826
for (ch = 0; ch <= pbfont->num_glyphs; ch++) {
827
gs_glyph glyph = pfont->procs.encode_char(pfont, ch, GLYPH_SPACE_INDEX);
829
pbfont->CIDSet[ch / 8] |= 0x80 >> (ch % 8);
830
pdfont->u.cidfont.CIDToGIDMap[ch] = glyph - GS_MIN_GLYPH_INDEX;
833
pbfont->CIDSetLength = length_CIDSet;
834
pdfont->u.cidfont.CIDToGIDMapLength = length_CIDToGIDMap / sizeof(ushort);
835
pdfont->u.cidfont.Widths2 = NULL;
836
pdfont->u.cidfont.used2 = NULL;
837
pdfont->u.cidfont.v = NULL;
841
int mark_font_descriptor_symbolic(const pdf_font_resource_t *pdfont)
843
pdf_font_descriptor_values_t *desc;
845
if(!pdfont || !pdfont->FontDescriptor)
848
desc = &pdfont->FontDescriptor->common.values;
850
if (!(desc->Flags & FONT_IS_SYMBOLIC)) {
851
desc->Flags |= FONT_IS_SYMBOLIC;
852
desc->Flags &= ~FONT_IS_ADOBE_ROMAN;