~ubuntu-branches/ubuntu/vivid/ghostscript/vivid-security

« back to all changes in this revision

Viewing changes to base/gdevpdtd.c

  • Committer: Package Import Robot
  • Author(s): Till Kamppeter
  • Date: 2013-08-09 20:01:36 UTC
  • mfrom: (1.1.37)
  • Revision ID: package-import@ubuntu.com-20130809200136-amb6zrr7hnjb5jq9
Tags: 9.08~rc1~dfsg-0ubuntu1
* New upstream release
   - Ghostscript 9.08rc1.
   - We are using the system's liblcms2 and libopenjpeg now.
* debian/patches/020130401-852e545-pxl-xl-driver-produced-drawing-commands-without-setting-color-space.patch:
  Removed patch backported from upstream.
* debian/patches/ojdk-8007925+8007926.patch,
  debian/patches/ojdk-8007927.patch,
  debian/patches/ojdk-8007929.patch,
  debian/patches/ojdk-8009654.patch: Removed patches on build in liblcms2, we
  use the system's liblcms2 now.
* debian/patches/2001_docdir_fix_for_debian.patch: Manually updated to new
  upstream source code.
* debian/patches/2003_support_multiarch.patch: Refreshed with quilt.
* debian/control: Added build dependencies on liblcms2-dev and
  libopenjpeg-dev.
* debian/rules: Check for removed lcms2/ and openjpeg/ subdirectories in
  the repackaging check again, also set build options for shared liblcms2
  and libopenjpeg libraries.
* debian/rules: Makefile.in and configure.ac are in the root directory of
  the source now and do not need to get linked from base/. Also there is no
  gstoraster and gstopxl CUPS filter in the package any more and no
  "install-cups" make target any more.
* debian/control, debian/rules, debian/ghostscript-cups.install,
  debian/ghostscript-cups.ppd-updater: Removed the ghostscript-cups binary
  package. The files are now provided by cups-filters.
* debian/symbols.common: Updated for new upstream source. Applied patch
  which dpkg-gensymbols generated for debian/libgs9.symbols to this file.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* Copyright (C) 2001-2012 Artifex Software, Inc.
2
 
   All Rights Reserved.
3
 
 
4
 
   This software is provided AS-IS with no warranty, either express or
5
 
   implied.
6
 
 
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.
10
 
 
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.
14
 
*/
15
 
 
16
 
 
17
 
/* FontDescriptor implementation for pdfwrite */
18
 
#include "math_.h"
19
 
#include "memory_.h"
20
 
#include "gx.h"
21
 
#include "gserrors.h"
22
 
#include "gsrect.h"             /* for rect_merge */
23
 
#include "gscencs.h"
24
 
#include "gxfcopy.h"
25
 
#include "gdevpdfx.h"
26
 
#include "gdevpdfo.h"           /* for object->written */
27
 
#include "gdevpdtb.h"
28
 
#include "gdevpdtd.h"
29
 
#include "gdevpdtf.h"
30
 
 
31
 
/* ================ Types and structures ================ */
32
 
 
33
 
/*
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).
39
 
 *
40
 
 * Descriptors for actual fonts have three major orthogonal properties:
41
 
 *
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).
45
 
 *
46
 
 *      - Whether the font they represent is embedded.
47
 
 *
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.
52
 
 *
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.
55
 
 */
56
 
/*
57
 
 * Start by defining the elements common to font descriptors and sub-font
58
 
 * (character class) descriptors.
59
 
 */
60
 
typedef struct pdf_font_descriptor_values_s {
61
 
    /* Required elements */
62
 
    int Ascent, CapHeight, Descent, ItalicAngle, StemV;
63
 
    gs_int_rect FontBBox;
64
 
    gs_string FontName;
65
 
    uint Flags;
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;
73
 
};
74
 
/* Flag bits */
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)
79
 
/*
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
87
 
 * correctly.
88
 
 */
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)
95
 
 
96
 
/*
97
 
 * Define a (top-level) FontDescriptor.  CID-keyed vs. non-CID-keyed fonts
98
 
 * are distinguished by their FontType.
99
 
 */
100
 
#ifndef pdf_base_font_DEFINED
101
 
#  define pdf_base_font_DEFINED
102
 
typedef struct pdf_base_font_s pdf_base_font_t;
103
 
#endif
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) */
108
 
    bool embed;
109
 
    struct cid_ {               /* (CIDFonts only) */
110
 
        cos_dict_t *Style;
111
 
        char Lang[3];           /* 2 chars + \0 */
112
 
        cos_dict_t *FD;         /* value = COS_VALUE_RESOURCE */
113
 
    } cid;
114
 
};
115
 
/*
116
 
 * Define a sub-descriptor for a character class (FD dictionary element).
117
 
 */
118
 
typedef struct pdf_sub_font_descriptor_s {
119
 
    pdf_font_descriptor_common_t common;
120
 
} pdf_sub_font_descriptor_t;
121
 
 
122
 
/*
123
 
 * Font descriptors are pseudo-resources, so their GC descriptors
124
 
 * must be public.
125
 
 */
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)
131
 
};
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);
135
 
 
136
 
/*
137
 
 * Sub-font descriptors are also pseudo-resources.
138
 
 */
139
 
BASIC_PTRS(pdf_sub_font_descriptor_ptrs) {
140
 
    GC_STRING_ELT(pdf_sub_font_descriptor_t, common.values.FontName)
141
 
};
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);
146
 
 
147
 
/* ================ Procedures ================ */
148
 
 
149
 
/* ---------------- Private ---------------- */
150
 
 
151
 
/* Get the ID of font descriptor metrics. */
152
 
static inline long
153
 
pdf_font_descriptor_common_id(const pdf_font_descriptor_common_t *pfdc)
154
 
{
155
 
    return pdf_resource_id((const pdf_resource_t *)pfdc);
156
 
}
157
 
 
158
 
/* Write the common part of a FontDescriptor, aside from the final >>. */
159
 
static int
160
 
write_FontDescriptor_common(gx_device_pdf *pdev,
161
 
                            const pdf_font_descriptor_common_t *pfd, bool embed)
162
 
{
163
 
    stream *s;
164
 
    int code;
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;
169
 
 
170
 
    pdf_open_separate(pdev, pdf_font_descriptor_common_id(pfd), resourceFontDescriptor);
171
 
    s = pdev->strm;
172
 
    stream_puts(s, "<</Type/FontDescriptor/FontName");
173
 
    if (!embed) {
174
 
        base14_name = (char *)pdf_find_base14_name(pfd->values.FontName.data, pfd->values.FontName.size);
175
 
        if(base14_name)
176
 
            pdf_put_name(pdev, (byte *)base14_name, strlen(base14_name));
177
 
        else
178
 
            pdf_put_name(pdev, pfd->values.FontName.data, pfd->values.FontName.size);
179
 
    } else
180
 
        pdf_put_name(pdev, pfd->values.FontName.data, pfd->values.FontName.size);
181
 
 
182
 
    pdf_write_font_bbox(pdev, &pfd->values.FontBBox);
183
 
    params = param_printer_params_default;
184
 
    code = s_init_param_printer(&rlist, &params, s);
185
 
    if (code >= 0) {
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),
194
 
            gs_param_item_end
195
 
        };
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),
203
 
            gs_param_item_end
204
 
        };
205
 
#undef DESC_INT
206
 
        int Flags = pfd->values.Flags;
207
 
        pdf_font_descriptor_t defaults;
208
 
 
209
 
        if (base14_name)
210
 
            Flags |=FONT_USES_STANDARD_ENCODING;
211
 
 
212
 
        code = param_write_int(plist, "Flags", &Flags);
213
 
        if (code < 0)
214
 
            return code;
215
 
        code = gs_param_write_items(plist, pfd, NULL, required_items);
216
 
        if (code < 0)
217
 
            return code;
218
 
        memset(&defaults, 0, sizeof(defaults));
219
 
        code = gs_param_write_items(plist, pfd, &defaults, optional_items);
220
 
        if (code < 0)
221
 
            return code;
222
 
        s_release_param_printer(&rlist);
223
 
    }
224
 
    return 0;
225
 
}
226
 
 
227
 
/* ---------------- Public ---------------- */
228
 
 
229
 
/*
230
 
 * Allocate a FontDescriptor, initializing the FontType and rid from the
231
 
 * gs_font.
232
 
 */
233
 
int
234
 
pdf_font_descriptor_alloc(gx_device_pdf *pdev, pdf_font_descriptor_t **ppfd,
235
 
                          gs_font_base *font, bool embed)
236
 
{
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);
242
 
 
243
 
    if (code < 0)
244
 
        return code;
245
 
    code = pdf_alloc_resource(pdev, resourceFontDescriptor,
246
 
                              font->id, (pdf_resource_t **)&pfd, -1L);
247
 
    if (code < 0) {
248
 
        gs_free_object(pdev->pdf_memory, pbfont,
249
 
                       "pdf_font_descriptor_alloc(base_font)");
250
 
        return code;
251
 
    }
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;
256
 
    pfd->embed = embed;
257
 
    *ppfd = pfd;
258
 
    return 0;
259
 
}
260
 
 
261
 
int pdf_font_descriptor_free(gx_device_pdf *pdev, pdf_resource_t *pres)
262
 
{
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;
266
 
 
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;
272
 
    }
273
 
    if (pbfont)
274
 
        gs_free_object(cos_object_memory(pres->object), pbfont, "Free base font from FontDescriptor)");
275
 
    if (pres->object) {
276
 
        gs_free_object(cos_object_memory(pres->object), pres->object, "free FontDescriptor object");
277
 
        pres->object = NULL;
278
 
    }
279
 
    return 0;
280
 
}
281
 
 
282
 
/* Get the object ID of a FontDescriptor. */
283
 
long
284
 
pdf_font_descriptor_id(const pdf_font_descriptor_t *pfd)
285
 
{
286
 
    return pdf_resource_id((const pdf_resource_t *)pfd);
287
 
}
288
 
 
289
 
long pdf_set_font_descriptor_usage(gx_device_pdf *pdev, int parent_id, const pdf_font_descriptor_t *pfd)
290
 
{
291
 
    int id = pdf_resource_id((const pdf_resource_t *)pfd);
292
 
 
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);
297
 
    }
298
 
    return 0;
299
 
}
300
 
 
301
 
/*
302
 
 * Get the FontType of a FontDescriptor.
303
 
 */
304
 
font_type
305
 
pdf_font_descriptor_FontType(const pdf_font_descriptor_t *pfd)
306
 
{
307
 
    return pfd->FontType;
308
 
}
309
 
 
310
 
/*
311
 
 * Get the embedding status of a FontDescriptor.
312
 
 */
313
 
bool
314
 
pdf_font_descriptor_embedding(const pdf_font_descriptor_t *pfd)
315
 
{
316
 
    return pfd->embed;
317
 
}
318
 
 
319
 
/*
320
 
 * Check for subset font.
321
 
 */
322
 
bool
323
 
pdf_font_descriptor_is_subset(const pdf_font_descriptor_t *pfd)
324
 
{
325
 
    return pdf_base_font_is_subset(pfd->base_font);
326
 
}
327
 
 
328
 
/*
329
 
 * Return a reference to the FontName of a FontDescriptor, similar to
330
 
 * pdf_base_font_name.
331
 
 */
332
 
gs_string *pdf_font_descriptor_name(pdf_font_descriptor_t *pfd)
333
 
{
334
 
    return &pfd->common.values.FontName;
335
 
}
336
 
 
337
 
char *pdf_fontfile_hash(void *pfd)
338
 
{
339
 
    pdf_font_descriptor_t *fd = (pdf_font_descriptor_t *)pfd;
340
 
    cos_dict_t *pcd;
341
 
 
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);
346
 
        else
347
 
            return 0;
348
 
    } else
349
 
        return 0;
350
 
}
351
 
 
352
 
/*
353
 
 * Return the (copied, subset or complete) font associated with a FontDescriptor.
354
 
 * This procedure probably shouldn't exist....
355
 
 */
356
 
gs_font_base *
357
 
pdf_font_descriptor_font(const pdf_font_descriptor_t *pfd, bool complete)
358
 
{
359
 
    return pdf_base_font_font(pfd->base_font, complete);
360
 
}
361
 
 
362
 
/*
363
 
 * Drop the copied complete font associated with a FontDescriptor.
364
 
 */
365
 
void
366
 
pdf_font_descriptor_drop_complete_font(const pdf_font_descriptor_t *pfd)
367
 
{
368
 
    pdf_base_font_drop_complete(pfd->base_font);
369
 
}
370
 
 
371
 
/*
372
 
 * Return a reference to the name of a FontDescriptor's base font, per
373
 
 * pdf_base_font_name.
374
 
 */
375
 
gs_string *pdf_font_descriptor_base_name(const pdf_font_descriptor_t *pfd)
376
 
{
377
 
    return pdf_base_font_name(pfd->base_font);
378
 
}
379
 
 
380
 
/*
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.
383
 
 */
384
 
int
385
 
pdf_font_used_glyph(pdf_font_descriptor_t *pfd, gs_glyph glyph,
386
 
                    gs_font_base *font)
387
 
{
388
 
    return pdf_base_font_copy_glyph(pfd->base_font, glyph, font);
389
 
}
390
 
 
391
 
/* Compute the FontDescriptor metrics for a font. */
392
 
int
393
 
pdf_compute_font_descriptor(gx_device_pdf *pdev, pdf_font_descriptor_t *pfd)
394
 
{
395
 
    gs_font_base *bfont = pdf_base_font_font(pfd->base_font, false);
396
 
    gs_glyph glyph, notdef;
397
 
    int index;
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;
402
 
    gs_matrix smat;
403
 
    gs_matrix *pmat = NULL;
404
 
    int fixed_width = 0;
405
 
    int small_descent = 0, small_height = 0;
406
 
    bool small_present = false;
407
 
    int x_height = 0;
408
 
    int cap_height = 0;
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;
413
 
    int code;
414
 
 
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);
422
 
 
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;
429
 
    } else {
430
 
        desc.FontBBox.p.x = desc.FontBBox.p.y = max_int;
431
 
        desc.FontBBox.q.x = desc.FontBBox.q.y = min_int;
432
 
    }
433
 
    /*
434
 
     * Embedded TrueType fonts use a 1000-unit character space, but the
435
 
     * font itself uses a 1-unit space.  Compensate for this here.
436
 
     */
437
 
    switch (bfont->FontType) {
438
 
    case ft_TrueType:
439
 
    case ft_CID_TrueType:
440
 
        gs_make_scaling(1000.0, 1000.0, &smat);
441
 
        pmat = &smat;
442
 
        /* Type 3 fonts may use a FontMatrix in PDF, so we don't
443
 
         * need to deal with non-standard matrices
444
 
         */
445
 
    case ft_GL2_531:
446
 
    case ft_PCL_user_defined:
447
 
    case ft_GL2_stick_user_defined:
448
 
    case ft_user_defined:
449
 
        break;
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.
455
 
         */
456
 
    default:
457
 
        gs_matrix_scale(&bfont->FontMatrix, 1000.0, 1000.0, &smat);
458
 
        pmat = &smat;
459
 
        break;
460
 
    }
461
 
 
462
 
    /*
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.)
469
 
     */
470
 
    notdef = GS_NO_GLYPH;
471
 
    for (index = 0;
472
 
         (bfont->procs.enumerate_glyph((gs_font *)bfont, &index,
473
 
                (is_cid ? GLYPH_SPACE_INDEX : GLYPH_SPACE_NAME), &glyph)) >= 0 &&
474
 
             index != 0;
475
 
         ) {
476
 
        gs_glyph_info_t info;
477
 
        gs_const_string gname;
478
 
        gs_glyph glyph_known_enc;
479
 
        gs_char position=0;
480
 
 
481
 
        code = bfont->procs.glyph_info((gs_font *)bfont, glyph, pmat, members, &info);
482
 
        if (code == gs_error_VMerror)
483
 
            return code;
484
 
        if (code < 0) {
485
 
            /*
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.
490
 
             */
491
 
            continue;
492
 
        }
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);
501
 
        }
502
 
        if (notdef == GS_NO_GLYPH && gs_font_glyph_is_notdef(bfont, glyph)) {
503
 
            notdef = glyph;
504
 
            desc.MissingWidth = (int)info.width[wmode].x;
505
 
        }
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 */
514
 
        if (is_cid)
515
 
            continue;
516
 
        code = bfont->procs.glyph_name((gs_font *)bfont, glyph, &gname);
517
 
        if (code < 0) {
518
 
            /* If we fail to get the glyph name, best assume this is a symbolic font */
519
 
            desc.Flags |= FONT_IS_SYMBOLIC;
520
 
            continue;
521
 
        }
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;
526
 
            continue;
527
 
        }
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
531
 
         */
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;
536
 
                continue;
537
 
            }
538
 
        }
539
 
        switch (gname.size) {
540
 
        case 5:
541
 
            if (!memcmp(gname.data, "colon", 5))
542
 
                bbox_colon = info.bbox, have_colon = true;
543
 
            continue;
544
 
        case 6:
545
 
            if (!memcmp(gname.data, "period", 6))
546
 
                bbox_period = info.bbox, have_period = true;
547
 
            continue;
548
 
        case 1:
549
 
            break;
550
 
        default:
551
 
            continue;
552
 
        }
553
 
 
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);
560
 
 
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 */
567
 
                break;
568
 
            case 'j':           /* descender with anomalous ascent */
569
 
                small_descent = min(small_descent, y0);
570
 
                break;
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);
575
 
            }
576
 
        }
577
 
    }
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;
584
 
        /*
585
 
         * Look at various glyphs to determine ItalicAngle, StemV,
586
 
         * SERIF, SCRIPT, and ITALIC.
587
 
         */
588
 
        if (have_colon && have_period) {
589
 
            /* Calculate the dominant angle. */
590
 
            int 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;
596
 
 
597
 
            /* Normalize to [-90..90]. */
598
 
            while (angle > 90)
599
 
                angle -= 180;
600
 
            while (angle < -90)
601
 
                angle += 180;
602
 
            if (angle < -30)
603
 
                angle = -30;
604
 
            else if (angle > 30)
605
 
                angle = 30;
606
 
            /*
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.
610
 
             */
611
 
            if (angle <= 2 && angle >= -2)
612
 
                angle = 0;
613
 
            desc.ItalicAngle = angle;
614
 
        }
615
 
        if (desc.ItalicAngle)
616
 
            desc.Flags |= FONT_IS_ITALIC;
617
 
        if (have_I) {
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;
621
 
 
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;
625
 
        }
626
 
    }
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)
633
 
        )
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;
638
 
    }
639
 
    if (desc.CapHeight == 0)
640
 
        desc.CapHeight = desc.Ascent;
641
 
    if (desc.StemV == 0)
642
 
        desc.StemV = (int)(desc.FontBBox.q.x * 0.15);
643
 
    pfd->common.values = desc;
644
 
    return 0;
645
 
}
646
 
 
647
 
/*
648
 
 * Finish a FontDescriptor by computing the metric values, and then
649
 
 * writing the associated embedded font if any.
650
 
 */
651
 
int
652
 
pdf_finish_FontDescriptor(gx_device_pdf *pdev, pdf_resource_t *pres)
653
 
{
654
 
    pdf_font_descriptor_t *pfd = (pdf_font_descriptor_t *)pres;
655
 
    int code = 0;
656
 
    cos_dict_t *pcd = 0;
657
 
    if (pfd->common.object->id == -1)
658
 
        return 0;
659
 
    if (!pfd->common.object->written &&
660
 
        (code = pdf_compute_font_descriptor(pdev, pfd)) >= 0 &&
661
 
        (!pfd->embed ||
662
 
         (code = pdf_write_embedded_font(pdev, pfd->base_font,
663
 
                                pfd->FontType,
664
 
                                &pfd->common.values.FontBBox,
665
 
                                pfd->common.rid, &pcd)) >= 0)
666
 
        ) {
667
 
        pdf_set_FontFile_object(pfd->base_font, pcd);
668
 
    }
669
 
    return code;
670
 
}
671
 
 
672
 
/* Write a FontDescriptor. */
673
 
int
674
 
pdf_write_FontDescriptor(gx_device_pdf *pdev, pdf_resource_t *pres)
675
 
{
676
 
    pdf_font_descriptor_t *pfd = (pdf_font_descriptor_t *)pres;
677
 
    font_type ftype = pfd->FontType;
678
 
    long cidset_id = 0;
679
 
    int code = 0;
680
 
    stream *s;
681
 
 
682
 
    if (pfd->common.object->written)
683
 
        return 0;
684
 
    if (pfd->common.object->id == -1)
685
 
        return 0;
686
 
 
687
 
    /* If this is a CIDFont subset, write the CIDSet now. */
688
 
    switch (ftype) {
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);
694
 
                if (code < 0)
695
 
                    return code;
696
 
            }
697
 
        }
698
 
    default:
699
 
        break;
700
 
    }
701
 
 
702
 
    {
703
 
        /*
704
 
         * Hack: make all embedded subset TrueType fonts "symbolic" to
705
 
         * work around undocumented assumptions in Acrobat Reader.
706
 
         */
707
 
        pdf_font_descriptor_common_t fd;
708
 
 
709
 
        fd = pfd->common;
710
 
        if (pfd->embed && pfd->FontType == ft_TrueType /*&& !pdev->PDFA*/ &&
711
 
            pdf_do_subset_font(pdev, pfd->base_font, pfd->common.rid)
712
 
            )
713
 
            fd.values.Flags =
714
 
                (fd.values.Flags & ~(FONT_IS_ADOBE_ROMAN)) | FONT_IS_SYMBOLIC;
715
 
        code = write_FontDescriptor_common(pdev, &fd, pfd->embed);
716
 
    }
717
 
    if (code < 0)
718
 
        return code;
719
 
    s = pdev->strm;
720
 
    if (cidset_id != 0)
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)
724
 
             ) {
725
 
        stream_puts(s, "/CharSet");
726
 
        code = pdf_write_CharSet(pdev, pfd->base_font);
727
 
        if (code < 0)
728
 
            return code;
729
 
    }
730
 
    if (pfd->embed) {
731
 
        code = pdf_write_FontFile_entry(pdev, pfd->base_font);
732
 
        if (code < 0)
733
 
            return code;
734
 
    }
735
 
    if (pfd->cid.Style) {
736
 
        stream_puts(s, "/Style");
737
 
        COS_WRITE(pfd->cid.Style, pdev);
738
 
    }
739
 
    if (pfd->cid.Lang[0]) {
740
 
        pprints1(s, "/Lang(%s)", pfd->cid.Lang);
741
 
    }
742
 
    if (pfd->cid.FD) {
743
 
        stream_puts(s, "/FD");
744
 
        COS_WRITE(pfd->cid.FD, pdev);
745
 
    }
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);
750
 
        if (pco != NULL) {
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);
754
 
            if (code < 0)
755
 
                return code;
756
 
        }
757
 
    }
758
 
    return 0;
759
 
}
760
 
 
761
 
/*
762
 
 * Release a FontDescriptor components.
763
 
 */
764
 
int
765
 
pdf_release_FontDescriptor_components(gx_device_pdf *pdev, pdf_resource_t *pres)
766
 
{
767
 
    pdf_font_descriptor_t *pfd = (pdf_font_descriptor_t *) pres;
768
 
 
769
 
    gs_free_object(pdev->pdf_memory, pfd->base_font, "pdf_release_FontDescriptor_components");
770
 
    pfd->base_font = NULL;
771
 
    /* fixme: underimplemented. */
772
 
    return 0;
773
 
}
774
 
 
775
 
/*
776
 
 * Mark a FontDescriptor used in a text.
777
 
 */
778
 
int
779
 
pdf_mark_font_descriptor_used(gx_device_pdf *pdev, pdf_font_descriptor_t *pfd)
780
 
{
781
 
    if (pfd != NULL && pfd->common.object->id == -1)
782
 
        pdf_reserve_object_id(pdev, (pdf_resource_t *)&pfd->common, 0);
783
 
    return 0;
784
 
}
785
 
 
786
 
/*
787
 
 * Convert True Type font descriptor into CID font descriptor for PDF/A.
788
 
 */
789
 
int
790
 
pdf_convert_truetype_font_descriptor(gx_device_pdf *pdev, pdf_font_resource_t *pdfont)
791
 
{
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;
795
 
    gs_char ch;
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));
801
 
 
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);
818
 
 
819
 
                pbfont->CIDSet[ch / 8] |= 0x80 >> (ch % 8);
820
 
                pdfont->u.cidfont.CIDToGIDMap[ch] = glyph - GS_MIN_GLYPH_INDEX;
821
 
            }
822
 
        }
823
 
        /* Set the CIDSet bit for CID 0 (the /.notdef) which must always be present */
824
 
        pbfont->CIDSet[0] |= 0x80;
825
 
    } else {
826
 
        for (ch = 0; ch <= pbfont->num_glyphs; ch++) {
827
 
            gs_glyph glyph = pfont->procs.encode_char(pfont, ch, GLYPH_SPACE_INDEX);
828
 
 
829
 
            pbfont->CIDSet[ch / 8] |= 0x80 >> (ch % 8);
830
 
            pdfont->u.cidfont.CIDToGIDMap[ch] = glyph - GS_MIN_GLYPH_INDEX;
831
 
        }
832
 
    }
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;
838
 
    return 0;
839
 
}
840
 
 
841
 
int mark_font_descriptor_symbolic(const pdf_font_resource_t *pdfont)
842
 
{
843
 
    pdf_font_descriptor_values_t *desc;
844
 
 
845
 
    if(!pdfont || !pdfont->FontDescriptor)
846
 
        return 0;
847
 
 
848
 
    desc = &pdfont->FontDescriptor->common.values;
849
 
 
850
 
    if (!(desc->Flags & FONT_IS_SYMBOLIC)) {
851
 
        desc->Flags |= FONT_IS_SYMBOLIC;
852
 
        desc->Flags &= ~FONT_IS_ADOBE_ROMAN;
853
 
    }
854
 
    return 1;
855
 
}