~rafalcieslak256/ubuntu/quantal/cairo/build_test

« back to all changes in this revision

Viewing changes to .pc/05_fix_glyph_advance.patch/src/cairo-type1-subset.c

  • Committer: Bazaar Package Importer
  • Author(s): Marcel Stimberg
  • Date: 2010-10-25 00:56:57 UTC
  • mfrom: (28.1.2 experimental)
  • Revision ID: james.westby@ubuntu.com-20101025005657-mxkvwjucuglwoub6
Tags: 1.10.0-1ubuntu3
debian/patches/05_fix_glyph_advance.patch
Backport upstream fix for broken print output in evince. (LP: #661724)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* cairo - a vector graphics library with display and print output
 
2
 *
 
3
 * Copyright © 2006 Red Hat, Inc
 
4
 *
 
5
 * This library is free software; you can redistribute it and/or
 
6
 * modify it either under the terms of the GNU Lesser General Public
 
7
 * License version 2.1 as published by the Free Software Foundation
 
8
 * (the "LGPL") or, at your option, under the terms of the Mozilla
 
9
 * Public License Version 1.1 (the "MPL"). If you do not alter this
 
10
 * notice, a recipient may use your version of this file under either
 
11
 * the MPL or the LGPL.
 
12
 *
 
13
 * You should have received a copy of the LGPL along with this library
 
14
 * in the file COPYING-LGPL-2.1; if not, write to the Free Software
 
15
 * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
 
16
 * You should have received a copy of the MPL along with this library
 
17
 * in the file COPYING-MPL-1.1
 
18
 *
 
19
 * The contents of this file are subject to the Mozilla Public License
 
20
 * Version 1.1 (the "License"); you may not use this file except in
 
21
 * compliance with the License. You may obtain a copy of the License at
 
22
 * http://www.mozilla.org/MPL/
 
23
 *
 
24
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
 
25
 * OF ANY KIND, either express or implied. See the LGPL or the MPL for
 
26
 * the specific language governing rights and limitations.
 
27
 *
 
28
 * The Original Code is the cairo graphics library.
 
29
 *
 
30
 * The Initial Developer of the Original Code is Red Hat, Inc.
 
31
 *
 
32
 * Contributor(s):
 
33
 *      Kristian Høgsberg <krh@redhat.com>
 
34
 */
 
35
 
 
36
/*
 
37
 * Useful links:
 
38
 * http://partners.adobe.com/public/developer/en/font/T1_SPEC.PDF
 
39
 */
 
40
 
 
41
 
 
42
#define _BSD_SOURCE /* for snprintf(), strdup() */
 
43
#include "cairoint.h"
 
44
#include "cairo-error-private.h"
 
45
 
 
46
#if CAIRO_HAS_FONT_SUBSET
 
47
 
 
48
#include "cairo-type1-private.h"
 
49
#include "cairo-scaled-font-subsets-private.h"
 
50
#include "cairo-output-stream-private.h"
 
51
 
 
52
/* XXX: Eventually, we need to handle other font backends */
 
53
#if CAIRO_HAS_FT_FONT
 
54
 
 
55
#include "cairo-ft-private.h"
 
56
 
 
57
#include <ft2build.h>
 
58
#include FT_FREETYPE_H
 
59
#include FT_OUTLINE_H
 
60
#include FT_TYPE1_TABLES_H
 
61
 
 
62
#include <ctype.h>
 
63
 
 
64
typedef struct _cairo_type1_font_subset {
 
65
    cairo_scaled_font_subset_t *scaled_font_subset;
 
66
 
 
67
    struct {
 
68
        cairo_unscaled_font_t *unscaled_font;
 
69
        unsigned int font_id;
 
70
        char *base_font;
 
71
        unsigned int num_glyphs;
 
72
        long x_min, y_min, x_max, y_max;
 
73
        long ascent, descent;
 
74
 
 
75
        const char    *data;
 
76
        unsigned long  header_size;
 
77
        unsigned long  data_size;
 
78
        unsigned long  trailer_size;
 
79
    } base;
 
80
 
 
81
    FT_Face face;
 
82
    int num_glyphs;
 
83
 
 
84
    struct {
 
85
        int subset_index;
 
86
        double width;
 
87
        char *name;
 
88
    } *glyphs;
 
89
 
 
90
    cairo_output_stream_t *output;
 
91
    cairo_array_t contents;
 
92
 
 
93
    const char *rd, *nd;
 
94
 
 
95
    char *type1_data;
 
96
    unsigned int type1_length;
 
97
    char *type1_end;
 
98
 
 
99
    char *header_segment;
 
100
    int header_segment_size;
 
101
    char *eexec_segment;
 
102
    int eexec_segment_size;
 
103
    cairo_bool_t eexec_segment_is_ascii;
 
104
 
 
105
    char *cleartext;
 
106
    char *cleartext_end;
 
107
 
 
108
    int header_size;
 
109
 
 
110
    unsigned short eexec_key;
 
111
    cairo_bool_t hex_encode;
 
112
    int hex_column;
 
113
} cairo_type1_font_subset_t;
 
114
 
 
115
 
 
116
static cairo_status_t
 
117
_cairo_type1_font_subset_init (cairo_type1_font_subset_t  *font,
 
118
                               cairo_unscaled_font_t      *unscaled_font,
 
119
                               cairo_bool_t                hex_encode)
 
120
{
 
121
    cairo_ft_unscaled_font_t *ft_unscaled_font;
 
122
    cairo_status_t status;
 
123
    FT_Face face;
 
124
    PS_FontInfoRec font_info;
 
125
    int i, j;
 
126
 
 
127
    ft_unscaled_font = (cairo_ft_unscaled_font_t *) unscaled_font;
 
128
 
 
129
    face = _cairo_ft_unscaled_font_lock_face (ft_unscaled_font);
 
130
    if (unlikely (face == NULL))
 
131
        return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
132
 
 
133
    if (FT_Get_PS_Font_Info(face, &font_info) != 0) {
 
134
        status = CAIRO_INT_STATUS_UNSUPPORTED;
 
135
        goto fail1;
 
136
    }
 
137
 
 
138
    /* OpenType/CFF fonts also have a PS_FontInfoRec */
 
139
#if HAVE_FT_LOAD_SFNT_TABLE
 
140
    if (FT_IS_SFNT (face)) {
 
141
        status = CAIRO_INT_STATUS_UNSUPPORTED;
 
142
        goto fail1;
 
143
    }
 
144
#endif
 
145
 
 
146
    memset (font, 0, sizeof (*font));
 
147
    font->base.unscaled_font = _cairo_unscaled_font_reference (unscaled_font);
 
148
    font->base.num_glyphs = face->num_glyphs;
 
149
    font->base.x_min = face->bbox.xMin;
 
150
    font->base.y_min = face->bbox.yMin;
 
151
    font->base.x_max = face->bbox.xMax;
 
152
    font->base.y_max = face->bbox.yMax;
 
153
    font->base.ascent = face->ascender;
 
154
    font->base.descent = face->descender;
 
155
 
 
156
    if (face->family_name) {
 
157
        font->base.base_font = strdup (face->family_name);
 
158
        if (unlikely (font->base.base_font == NULL)) {
 
159
            status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
160
            goto fail2;
 
161
        }
 
162
        for (i = 0, j = 0; font->base.base_font[j]; j++) {
 
163
            if (font->base.base_font[j] == ' ')
 
164
                continue;
 
165
            font->base.base_font[i++] = font->base.base_font[j];
 
166
        }
 
167
        font->base.base_font[i] = '\0';
 
168
    }
 
169
 
 
170
    font->glyphs = calloc (face->num_glyphs, sizeof font->glyphs[0]);
 
171
    if (unlikely (font->glyphs == NULL)) {
 
172
        status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
173
        goto fail3;
 
174
    }
 
175
 
 
176
    font->hex_encode = hex_encode;
 
177
    font->num_glyphs = 0;
 
178
    for (i = 0; i < face->num_glyphs; i++)
 
179
        font->glyphs[i].subset_index = -1;
 
180
 
 
181
    _cairo_array_init (&font->contents, sizeof (char));
 
182
 
 
183
    _cairo_ft_unscaled_font_unlock_face (ft_unscaled_font);
 
184
 
 
185
    return CAIRO_STATUS_SUCCESS;
 
186
 
 
187
 fail3:
 
188
    if (font->base.base_font)
 
189
        free (font->base.base_font);
 
190
 fail2:
 
191
    _cairo_unscaled_font_destroy (unscaled_font);
 
192
 fail1:
 
193
    _cairo_ft_unscaled_font_unlock_face (ft_unscaled_font);
 
194
 
 
195
    return status;
 
196
}
 
197
 
 
198
static void
 
199
cairo_type1_font_subset_use_glyph (cairo_type1_font_subset_t *font, int glyph)
 
200
{
 
201
    if (font->glyphs[glyph].subset_index >= 0)
 
202
        return;
 
203
 
 
204
    font->glyphs[glyph].subset_index = font->num_glyphs++;
 
205
}
 
206
 
 
207
static cairo_bool_t
 
208
is_ps_delimiter(int c)
 
209
{
 
210
    static const char delimiters[] = "()[]{}<>/% \t\r\n";
 
211
 
 
212
    return strchr (delimiters, c) != NULL;
 
213
}
 
214
 
 
215
static const char *
 
216
find_token (const char *buffer, const char *end, const char *token)
 
217
{
 
218
    int i, length;
 
219
    /* FIXME: find substring really must be find_token */
 
220
 
 
221
    if (buffer == NULL)
 
222
        return NULL;
 
223
 
 
224
    length = strlen (token);
 
225
    for (i = 0; buffer + i < end - length + 1; i++)
 
226
        if (memcmp (buffer + i, token, length) == 0)
 
227
            if ((i == 0 || token[0] == '/' || is_ps_delimiter(buffer[i - 1])) &&
 
228
                (buffer + i == end - length || is_ps_delimiter(buffer[i + length])))
 
229
                return buffer + i;
 
230
 
 
231
    return NULL;
 
232
}
 
233
 
 
234
static cairo_status_t
 
235
cairo_type1_font_subset_find_segments (cairo_type1_font_subset_t *font)
 
236
{
 
237
    unsigned char *p;
 
238
    const char *eexec_token;
 
239
    int size, i;
 
240
 
 
241
    p = (unsigned char *) font->type1_data;
 
242
    font->type1_end = font->type1_data + font->type1_length;
 
243
    if (p[0] == 0x80 && p[1] == 0x01) {
 
244
        font->header_segment_size =
 
245
            p[2] | (p[3] << 8) | (p[4] << 16) | (p[5] << 24);
 
246
        font->header_segment = (char *) p + 6;
 
247
 
 
248
        p += 6 + font->header_segment_size;
 
249
        font->eexec_segment_size =
 
250
            p[2] | (p[3] << 8) | (p[4] << 16) | (p[5] << 24);
 
251
        font->eexec_segment = (char *) p + 6;
 
252
        font->eexec_segment_is_ascii = (p[1] == 1);
 
253
 
 
254
        p += 6 + font->eexec_segment_size;
 
255
        while (p < (unsigned char *) (font->type1_end) && p[1] != 0x03) {
 
256
            size = p[2] | (p[3] << 8) | (p[4] << 16) | (p[5] << 24);
 
257
            p += 6 + size;
 
258
        }
 
259
        font->type1_end = (char *) p;
 
260
    } else {
 
261
        eexec_token = find_token ((char *) p, font->type1_end, "eexec");
 
262
        if (eexec_token == NULL)
 
263
            return CAIRO_INT_STATUS_UNSUPPORTED;
 
264
 
 
265
        font->header_segment_size = eexec_token - (char *) p + strlen ("eexec\n");
 
266
        font->header_segment = (char *) p;
 
267
        font->eexec_segment_size = font->type1_length - font->header_segment_size;
 
268
        font->eexec_segment = (char *) p + font->header_segment_size;
 
269
        font->eexec_segment_is_ascii = TRUE;
 
270
        for (i = 0; i < 4; i++) {
 
271
            if (!isxdigit(font->eexec_segment[i]))
 
272
                font->eexec_segment_is_ascii = FALSE;
 
273
        }
 
274
    }
 
275
 
 
276
    return CAIRO_STATUS_SUCCESS;
 
277
}
 
278
 
 
279
/* Search for the definition of key and erase it by overwriting with spaces.
 
280
 * This function is looks for definitions of the form:
 
281
 *
 
282
 * /key1 1234 def
 
283
 * /key2 [12 34 56] def
 
284
 *
 
285
 * ie a key defined as an integer or array of integers.
 
286
 *
 
287
 */
 
288
static void
 
289
cairo_type1_font_erase_dict_key (cairo_type1_font_subset_t *font,
 
290
                                 const char *key)
 
291
{
 
292
    const char *start, *p, *segment_end;
 
293
 
 
294
    segment_end = font->header_segment + font->header_segment_size;
 
295
 
 
296
    start = font->header_segment;
 
297
    do {
 
298
        start = find_token (start, segment_end, key);
 
299
        if (start) {
 
300
            p = start + strlen(key);
 
301
            /* skip integers or array of integers */
 
302
            while (p < segment_end &&
 
303
                   (_cairo_isspace(*p) ||
 
304
                    _cairo_isdigit(*p) ||
 
305
                    *p == '[' ||
 
306
                    *p == ']'))
 
307
            {
 
308
                p++;
 
309
            }
 
310
 
 
311
            if (p + 3 < segment_end && memcmp(p, "def", 3) == 0) {
 
312
                /* erase definition of the key */
 
313
                memset((char *) start, ' ', p + 3 - start);
 
314
            }
 
315
            start += strlen(key);
 
316
        }
 
317
    } while (start);
 
318
}
 
319
 
 
320
static cairo_status_t
 
321
cairo_type1_font_subset_write_header (cairo_type1_font_subset_t *font,
 
322
                                         const char *name)
 
323
{
 
324
    const char *start, *end, *segment_end;
 
325
    unsigned int i;
 
326
 
 
327
    /* FIXME:
 
328
     * This function assumes that /FontName always appears
 
329
     * before /Encoding. This appears to always be the case with Type1
 
330
     * fonts.
 
331
     *
 
332
     * The more recently added code for removing the UniqueID and XUID
 
333
     * keys can not make any assumptions about the position of the
 
334
     * keys in the dictionary so it is implemented by overwriting the
 
335
     * key definition with spaces before we start copying the font to
 
336
     * the output.
 
337
     *
 
338
     * This code should be rewritten to not make any assumptions about
 
339
     * the order of dictionary keys. This will allow UniqueID to be
 
340
     * stripped out instead of leaving a bunch of spaces in the
 
341
     * output.
 
342
     */
 
343
    cairo_type1_font_erase_dict_key (font, "/UniqueID");
 
344
    cairo_type1_font_erase_dict_key (font, "/XUID");
 
345
 
 
346
    segment_end = font->header_segment + font->header_segment_size;
 
347
 
 
348
    /* Type 1 fonts created by Fontforge have some PostScript code at
 
349
     * the start of the font that skips the font if the printer has a
 
350
     * cached copy of the font with the same unique id. This breaks
 
351
     * our subsetted font so we disable it by searching for the
 
352
     * PostScript operator "known" when used to check for the
 
353
     * "/UniqueID" dictionary key. We append " pop false " after it to
 
354
     * pop the result of this check off the stack and replace it with
 
355
     * "false" to make the PostScript code think "/UniqueID" does not
 
356
     * exist.
 
357
     */
 
358
    end = font->header_segment;
 
359
    start = find_token (font->header_segment, segment_end, "/UniqueID");
 
360
    if (start) {
 
361
        start += 9;
 
362
        while (start < segment_end && _cairo_isspace (*start))
 
363
            start++;
 
364
        if (start + 5 < segment_end && memcmp(start, "known", 5) == 0) {
 
365
            _cairo_output_stream_write (font->output, font->header_segment,
 
366
                                        start + 5 - font->header_segment);
 
367
            _cairo_output_stream_printf (font->output, " pop false ");
 
368
            end = start + 5;
 
369
        }
 
370
    }
 
371
 
 
372
    start = find_token (end, segment_end, "/FontName");
 
373
    if (start == NULL)
 
374
        return CAIRO_INT_STATUS_UNSUPPORTED;
 
375
 
 
376
    _cairo_output_stream_write (font->output, end,
 
377
                                start - end);
 
378
 
 
379
    _cairo_output_stream_printf (font->output, "/FontName /%s def", name);
 
380
 
 
381
    end = find_token (start, segment_end, "def");
 
382
    if (end == NULL)
 
383
        return CAIRO_INT_STATUS_UNSUPPORTED;
 
384
    end += 3;
 
385
 
 
386
    start = find_token (end, segment_end, "/Encoding");
 
387
    if (start == NULL)
 
388
        return CAIRO_INT_STATUS_UNSUPPORTED;
 
389
    _cairo_output_stream_write (font->output, end, start - end);
 
390
 
 
391
    _cairo_output_stream_printf (font->output,
 
392
                                 "/Encoding 256 array\n"
 
393
                                 "0 1 255 {1 index exch /.notdef put} for\n");
 
394
    for (i = 1; i < font->base.num_glyphs; i++) {
 
395
        if (font->glyphs[i].subset_index < 0)
 
396
            continue;
 
397
        _cairo_output_stream_printf (font->output,
 
398
                                     "dup %d /%s put\n",
 
399
                                     font->glyphs[i].subset_index,
 
400
                                     font->glyphs[i].name);
 
401
    }
 
402
    _cairo_output_stream_printf (font->output, "readonly def");
 
403
 
 
404
    end = find_token (start, segment_end, "def");
 
405
    if (end == NULL)
 
406
        return CAIRO_INT_STATUS_UNSUPPORTED;
 
407
    end += 3;
 
408
 
 
409
    _cairo_output_stream_write (font->output, end, segment_end - end);
 
410
 
 
411
    return font->output->status;
 
412
}
 
413
 
 
414
static int
 
415
hex_to_int (int ch)
 
416
{
 
417
    if (ch <= '9')
 
418
        return ch - '0';
 
419
    else if (ch <= 'F')
 
420
        return ch - 'A' + 10;
 
421
    else
 
422
        return ch - 'a' + 10;
 
423
}
 
424
 
 
425
static cairo_status_t
 
426
cairo_type1_font_subset_write_encrypted (cairo_type1_font_subset_t *font,
 
427
                                         const char *data, unsigned int length)
 
428
{
 
429
    const unsigned char *in, *end;
 
430
    int c, p;
 
431
    static const char hex_digits[16] = "0123456789abcdef";
 
432
    char digits[3];
 
433
 
 
434
    in = (const unsigned char *) data;
 
435
    end = (const unsigned char *) data + length;
 
436
    while (in < end) {
 
437
        p = *in++;
 
438
        c = p ^ (font->eexec_key >> 8);
 
439
        font->eexec_key = (c + font->eexec_key) * CAIRO_TYPE1_ENCRYPT_C1 + CAIRO_TYPE1_ENCRYPT_C2;
 
440
 
 
441
        if (font->hex_encode) {
 
442
            digits[0] = hex_digits[c >> 4];
 
443
            digits[1] = hex_digits[c & 0x0f];
 
444
            digits[2] = '\n';
 
445
            font->hex_column += 2;
 
446
 
 
447
            if (font->hex_column == 78) {
 
448
                _cairo_output_stream_write (font->output, digits, 3);
 
449
                font->hex_column = 0;
 
450
            } else {
 
451
                _cairo_output_stream_write (font->output, digits, 2);
 
452
            }
 
453
        } else {
 
454
            digits[0] = c;
 
455
            _cairo_output_stream_write (font->output, digits, 1);
 
456
        }
 
457
    }
 
458
 
 
459
    return font->output->status;
 
460
}
 
461
 
 
462
static cairo_status_t
 
463
cairo_type1_font_subset_decrypt_eexec_segment (cairo_type1_font_subset_t *font)
 
464
{
 
465
    unsigned short r = CAIRO_TYPE1_PRIVATE_DICT_KEY;
 
466
    unsigned char *in, *end;
 
467
    char *out;
 
468
    int c, p;
 
469
    int i;
 
470
 
 
471
    in = (unsigned char *) font->eexec_segment;
 
472
    end = (unsigned char *) in + font->eexec_segment_size;
 
473
 
 
474
    font->cleartext = malloc (font->eexec_segment_size);
 
475
    if (unlikely (font->cleartext == NULL))
 
476
        return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
477
 
 
478
    out = font->cleartext;
 
479
    while (in < end) {
 
480
        if (font->eexec_segment_is_ascii) {
 
481
            c = *in++;
 
482
            if (_cairo_isspace (c))
 
483
                continue;
 
484
            c = (hex_to_int (c) << 4) | hex_to_int (*in++);
 
485
        } else {
 
486
            c = *in++;
 
487
        }
 
488
        p = c ^ (r >> 8);
 
489
        r = (c + r) * CAIRO_TYPE1_ENCRYPT_C1 + CAIRO_TYPE1_ENCRYPT_C2;
 
490
 
 
491
        *out++ = p;
 
492
    }
 
493
    font->cleartext_end = out;
 
494
 
 
495
    /* Overwrite random bytes with spaces.
 
496
     *
 
497
     * The first 4 bytes of the cleartext are the random bytes
 
498
     * required by the encryption algorithm. When encrypting the
 
499
     * cleartext, the first ciphertext byte must not be a white space
 
500
     * character and the first 4 bytes must not be an ASCII Hex
 
501
     * character. Some fonts do not check that their randomly chosen
 
502
     * bytes results in ciphertext that complies with this
 
503
     * restriction. This may cause problems for some PDF consumers. By
 
504
     * replacing the random bytes with spaces, the first four bytes of
 
505
     * ciphertext will always be 0xf9, 0x83, 0xef, 0x00 which complies
 
506
     * with this restriction. Using spaces also means we don't have to
 
507
     * skip over the random bytes when parsing the cleartext.
 
508
     */
 
509
    for (i = 0; i < 4 && i < font->eexec_segment_size; i++)
 
510
        font->cleartext[i] = ' ';
 
511
 
 
512
    return CAIRO_STATUS_SUCCESS;
 
513
}
 
514
 
 
515
static const char *
 
516
skip_token (const char *p, const char *end)
 
517
{
 
518
    while (p < end && _cairo_isspace(*p))
 
519
        p++;
 
520
 
 
521
    while (p < end && !_cairo_isspace(*p))
 
522
        p++;
 
523
 
 
524
    if (p == end)
 
525
        return NULL;
 
526
 
 
527
    return p;
 
528
}
 
529
 
 
530
static int
 
531
cairo_type1_font_subset_lookup_glyph (cairo_type1_font_subset_t *font,
 
532
                                      const char *glyph_name, int length)
 
533
{
 
534
    unsigned int i;
 
535
 
 
536
    for (i = 0; i < font->base.num_glyphs; i++) {
 
537
        if (font->glyphs[i].name &&
 
538
            strncmp (font->glyphs[i].name, glyph_name, length) == 0 &&
 
539
            font->glyphs[i].name[length] == '\0')
 
540
            return i;
 
541
    }
 
542
 
 
543
    return -1;
 
544
}
 
545
 
 
546
static cairo_status_t
 
547
cairo_type1_font_subset_get_glyph_names_and_widths (cairo_type1_font_subset_t *font)
 
548
{
 
549
    unsigned int i;
 
550
    char buffer[256];
 
551
    FT_Error error;
 
552
 
 
553
    /* Get glyph names and width using the freetype API */
 
554
    for (i = 0; i < font->base.num_glyphs; i++) {
 
555
        if (font->glyphs[i].name != NULL)
 
556
            continue;
 
557
 
 
558
        error = FT_Load_Glyph (font->face, i,
 
559
                               FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING |
 
560
                               FT_LOAD_NO_BITMAP | FT_LOAD_IGNORE_TRANSFORM);
 
561
        if (error != FT_Err_Ok) {
 
562
            /* propagate fatal errors from FreeType */
 
563
            if (error == FT_Err_Out_Of_Memory)
 
564
                return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
565
 
 
566
            return CAIRO_INT_STATUS_UNSUPPORTED;
 
567
        }
 
568
 
 
569
        font->glyphs[i].width = font->face->glyph->linearHoriAdvance / 65536.0; /* 16.16 format */
 
570
 
 
571
        error = FT_Get_Glyph_Name(font->face, i, buffer, sizeof buffer);
 
572
        if (error != FT_Err_Ok) {
 
573
            /* propagate fatal errors from FreeType */
 
574
            if (error == FT_Err_Out_Of_Memory)
 
575
                return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
576
 
 
577
            return CAIRO_INT_STATUS_UNSUPPORTED;
 
578
        }
 
579
 
 
580
        font->glyphs[i].name = strdup (buffer);
 
581
        if (unlikely (font->glyphs[i].name == NULL))
 
582
            return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
583
    }
 
584
 
 
585
    return CAIRO_STATUS_SUCCESS;
 
586
}
 
587
 
 
588
static void
 
589
cairo_type1_font_subset_decrypt_charstring (const unsigned char *in, int size, unsigned char *out)
 
590
{
 
591
    unsigned short r = CAIRO_TYPE1_CHARSTRING_KEY;
 
592
    int c, p, i;
 
593
 
 
594
    for (i = 0; i < size; i++) {
 
595
        c = *in++;
 
596
        p = c ^ (r >> 8);
 
597
        r = (c + r) * CAIRO_TYPE1_ENCRYPT_C1 + CAIRO_TYPE1_ENCRYPT_C2;
 
598
        *out++ = p;
 
599
    }
 
600
}
 
601
 
 
602
static const unsigned char *
 
603
cairo_type1_font_subset_decode_integer (const unsigned char *p, int *integer)
 
604
{
 
605
    if (*p <= 246) {
 
606
        *integer = *p++ - 139;
 
607
    } else if (*p <= 250) {
 
608
        *integer = (p[0] - 247) * 256 + p[1] + 108;
 
609
        p += 2;
 
610
    } else if (*p <= 254) {
 
611
        *integer = -(p[0] - 251) * 256 - p[1] - 108;
 
612
        p += 2;
 
613
    } else {
 
614
        *integer = (p[1] << 24) | (p[2] << 16) | (p[3] << 8) | p[4];
 
615
        p += 5;
 
616
    }
 
617
 
 
618
    return p;
 
619
}
 
620
 
 
621
#if 0
 
622
/*
 
623
 * The two tables that follow are generated using this perl code:
 
624
 */
 
625
 
 
626
@encoding = (
 
627
        /*   0 */
 
628
        NULL,           NULL,           NULL,           NULL,
 
629
        NULL,           NULL,           NULL,           NULL,
 
630
        NULL,           NULL,           NULL,           NULL,
 
631
        NULL,           NULL,           NULL,           NULL,
 
632
        /*  16 */
 
633
        NULL,           NULL,           NULL,           NULL,
 
634
        NULL,           NULL,           NULL,           NULL,
 
635
        NULL,           NULL,           NULL,           NULL,
 
636
        NULL,           NULL,           NULL,           NULL,
 
637
        /*  32 */
 
638
        "space",        "exclam",       "quotedbl",     "numbersign",
 
639
        "dollar",       "percent",      "ampersand",    "quoteright",
 
640
        "parenleft",    "parenright",   "asterisk",     "plus",
 
641
        "comma",        "hyphen",       "period",       "slash",
 
642
        /*  48 */
 
643
        "zero",         "one",          "two",          "three",
 
644
        "four",         "five",         "six",          "seven",
 
645
        "eight",        "nine",         "colon",        "semicolon",
 
646
        "less",         "equal",        "greater",      "question",
 
647
        /*  64 */
 
648
        "at",           "A",            "B",            "C",
 
649
        "D",            "E",            "F",            "G",
 
650
        "H",            "I",            "J",            "K",
 
651
        "L",            "M",            "N",            "O",
 
652
        /*  80 */
 
653
        "P",            "Q",            "R",            "S",
 
654
        "T",            "U",            "V",            "W",
 
655
        "X",            "Y",            "Z",            "bracketleft",
 
656
        "backslash",    "bracketright", "asciicircum",  "underscore",
 
657
        /*  96 */
 
658
        "quoteleft",    "a",            "b",            "c",
 
659
        "d",            "e",            "f",            "g",
 
660
        "h",            "i",            "j",            "k",
 
661
        "l",            "m",            "n",            "o",
 
662
        /* 112 */
 
663
        "p",            "q",            "r",            "s",
 
664
        "t",            "u",            "v",            "w",
 
665
        "x",            "y",            "z",            "braceleft",
 
666
        "bar",          "braceright",   "asciitilde",   NULL,
 
667
        /* 128 */
 
668
        NULL,           NULL,           NULL,           NULL,
 
669
        NULL,           NULL,           NULL,           NULL,
 
670
        NULL,           NULL,           NULL,           NULL,
 
671
        NULL,           NULL,           NULL,           NULL,
 
672
        /* 144 */
 
673
        NULL,           NULL,           NULL,           NULL,
 
674
        NULL,           NULL,           NULL,           NULL,
 
675
        NULL,           NULL,           NULL,           NULL,
 
676
        NULL,           NULL,           NULL,           NULL,
 
677
        /* 160 */
 
678
        NULL,           "exclamdown",   "cent",         "sterling",
 
679
        "fraction",     "yen",          "florin",       "section",
 
680
        "currency",     "quotesingle",  "quotedblleft", "guillemotleft",
 
681
        "guilsinglleft","guilsinglright","fi",          "fl",
 
682
        /* 176 */
 
683
        NULL,           "endash",       "dagger",       "daggerdbl",
 
684
        "periodcentered",NULL,          "paragraph",    "bullet",
 
685
        "quotesinglbase","quotedblbase","quotedblright","guillemotright",
 
686
        "ellipsis",     "perthousand",  NULL,           "questiondown",
 
687
        /* 192 */
 
688
        NULL,           "grave",        "acute",        "circumflex",
 
689
        "tilde",        "macron",       "breve",        "dotaccent",
 
690
        "dieresis",     NULL,           "ring",         "cedilla",
 
691
        NULL,           "hungarumlaut", "ogonek",       "caron",
 
692
        /* 208 */
 
693
        "emdash",       NULL,           NULL,           NULL,
 
694
        NULL,           NULL,           NULL,           NULL,
 
695
        NULL,           NULL,           NULL,           NULL,
 
696
        NULL,           NULL,           NULL,           NULL,
 
697
        /* 224 */
 
698
        NULL,           "AE",           NULL,           "ordfeminine",
 
699
        NULL,           NULL,           NULL,           NULL,
 
700
        "Lslash",       "Oslash",       "OE",           "ordmasculine",
 
701
        NULL,           NULL,           NULL,           NULL,
 
702
        /* 240 */
 
703
        NULL,           "ae",           NULL,           NULL,
 
704
        NULL,           "dotlessi",     NULL,           NULL,
 
705
        "lslash",       "oslash",       "oe",           "germandbls",
 
706
        NULL,           NULL,           NULL,           NULL
 
707
        );
 
708
 
 
709
print "static const char ps_standard_encoding_symbol[] = {\n";
 
710
$s = qq( "\\0");
 
711
for $sym (@encoding) {
 
712
    if (! ($sym eq NULL)) {
 
713
        $ss = qq( "$sym\\0");
 
714
        if (length($s) + length($ss) > 78) {
 
715
          print qq( $s\n);
 
716
          $s = "";
 
717
        }
 
718
        $s .= $ss;
 
719
    }
 
720
}
 
721
print qq( $s\n);
 
722
print "};\n\n";
 
723
print "static const int16_t ps_standard_encoding_offset[256] = {\n";
 
724
$offset = 1;
 
725
$s = qq();
 
726
for $sym (@encoding) {
 
727
    if (! ($sym eq NULL)) {
 
728
        $ss = qq( $offset/*$sym*/,);
 
729
        $offset += length($sym) + 1;
 
730
    } else {
 
731
        $ss = qq( 0,);
 
732
    }
 
733
    if (length($s) + length($ss) > 78) {
 
734
      print qq( $s\n);
 
735
      $s = "";
 
736
    }
 
737
    $s .= $ss;
 
738
}
 
739
print qq( $s\n);
 
740
print "};\n";
 
741
exit;
 
742
#endif
 
743
 
 
744
static const char ps_standard_encoding_symbol[] = {
 
745
  "\0" "space\0" "exclam\0" "quotedbl\0" "numbersign\0" "dollar\0" "percent\0"
 
746
  "ampersand\0" "quoteright\0" "parenleft\0" "parenright\0" "asterisk\0"
 
747
  "plus\0" "comma\0" "hyphen\0" "period\0" "slash\0" "zero\0" "one\0" "two\0"
 
748
  "three\0" "four\0" "five\0" "six\0" "seven\0" "eight\0" "nine\0" "colon\0"
 
749
  "semicolon\0" "less\0" "equal\0" "greater\0" "question\0" "at\0" "A\0" "B\0"
 
750
  "C\0" "D\0" "E\0" "F\0" "G\0" "H\0" "I\0" "J\0" "K\0" "L\0" "M\0" "N\0" "O\0"
 
751
  "P\0" "Q\0" "R\0" "S\0" "T\0" "U\0" "V\0" "W\0" "X\0" "Y\0" "Z\0"
 
752
  "bracketleft\0" "backslash\0" "bracketright\0" "asciicircum\0" "underscore\0"
 
753
  "quoteleft\0" "a\0" "b\0" "c\0" "d\0" "e\0" "f\0" "g\0" "h\0" "i\0" "j\0"
 
754
  "k\0" "l\0" "m\0" "n\0" "o\0" "p\0" "q\0" "r\0" "s\0" "t\0" "u\0" "v\0" "w\0"
 
755
  "x\0" "y\0" "z\0" "braceleft\0" "bar\0" "braceright\0" "asciitilde\0"
 
756
  "exclamdown\0" "cent\0" "sterling\0" "fraction\0" "yen\0" "florin\0"
 
757
  "section\0" "currency\0" "quotesingle\0" "quotedblleft\0" "guillemotleft\0"
 
758
  "guilsinglleft\0" "guilsinglright\0" "fi\0" "fl\0" "endash\0" "dagger\0"
 
759
  "daggerdbl\0" "periodcentered\0" "paragraph\0" "bullet\0" "quotesinglbase\0"
 
760
  "quotedblbase\0" "quotedblright\0" "guillemotright\0" "ellipsis\0"
 
761
  "perthousand\0" "questiondown\0" "grave\0" "acute\0" "circumflex\0" "tilde\0"
 
762
  "macron\0" "breve\0" "dotaccent\0" "dieresis\0" "ring\0" "cedilla\0"
 
763
  "hungarumlaut\0" "ogonek\0" "caron\0" "emdash\0" "AE\0" "ordfeminine\0"
 
764
  "Lslash\0" "Oslash\0" "OE\0" "ordmasculine\0" "ae\0" "dotlessi\0" "lslash\0"
 
765
  "oslash\0" "oe\0" "germandbls\0"
 
766
};
 
767
 
 
768
static const int16_t ps_standard_encoding_offset[256] = {
 
769
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 
770
  0, 0, 0, 0, 0, 0, 1/*space*/, 7/*exclam*/, 14/*quotedbl*/, 23/*numbersign*/,
 
771
  34/*dollar*/, 41/*percent*/, 49/*ampersand*/, 59/*quoteright*/,
 
772
  70/*parenleft*/, 80/*parenright*/, 91/*asterisk*/, 100/*plus*/, 105/*comma*/,
 
773
  111/*hyphen*/, 118/*period*/, 125/*slash*/, 131/*zero*/, 136/*one*/,
 
774
  140/*two*/, 144/*three*/, 150/*four*/, 155/*five*/, 160/*six*/, 164/*seven*/,
 
775
  170/*eight*/, 176/*nine*/, 181/*colon*/, 187/*semicolon*/, 197/*less*/,
 
776
  202/*equal*/, 208/*greater*/, 216/*question*/, 225/*at*/, 228/*A*/, 230/*B*/,
 
777
  232/*C*/, 234/*D*/, 236/*E*/, 238/*F*/, 240/*G*/, 242/*H*/, 244/*I*/,
 
778
  246/*J*/, 248/*K*/, 250/*L*/, 252/*M*/, 254/*N*/, 256/*O*/, 258/*P*/,
 
779
  260/*Q*/, 262/*R*/, 264/*S*/, 266/*T*/, 268/*U*/, 270/*V*/, 272/*W*/,
 
780
  274/*X*/, 276/*Y*/, 278/*Z*/, 280/*bracketleft*/, 292/*backslash*/,
 
781
  302/*bracketright*/, 315/*asciicircum*/, 327/*underscore*/, 338/*quoteleft*/,
 
782
  348/*a*/, 350/*b*/, 352/*c*/, 354/*d*/, 356/*e*/, 358/*f*/, 360/*g*/,
 
783
  362/*h*/, 364/*i*/, 366/*j*/, 368/*k*/, 370/*l*/, 372/*m*/, 374/*n*/,
 
784
  376/*o*/, 378/*p*/, 380/*q*/, 382/*r*/, 384/*s*/, 386/*t*/, 388/*u*/,
 
785
  390/*v*/, 392/*w*/, 394/*x*/, 396/*y*/, 398/*z*/, 400/*braceleft*/,
 
786
  410/*bar*/, 414/*braceright*/, 425/*asciitilde*/, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 
787
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 
788
  436/*exclamdown*/, 447/*cent*/, 452/*sterling*/, 461/*fraction*/, 470/*yen*/,
 
789
  474/*florin*/, 481/*section*/, 489/*currency*/, 498/*quotesingle*/,
 
790
  510/*quotedblleft*/, 523/*guillemotleft*/, 537/*guilsinglleft*/,
 
791
  551/*guilsinglright*/, 566/*fi*/, 569/*fl*/, 0, 572/*endash*/, 579/*dagger*/,
 
792
  586/*daggerdbl*/, 596/*periodcentered*/, 0, 611/*paragraph*/, 621/*bullet*/,
 
793
  628/*quotesinglbase*/, 643/*quotedblbase*/, 656/*quotedblright*/,
 
794
  670/*guillemotright*/, 685/*ellipsis*/, 694/*perthousand*/, 0,
 
795
  706/*questiondown*/, 0, 719/*grave*/, 725/*acute*/, 731/*circumflex*/,
 
796
  742/*tilde*/, 748/*macron*/, 755/*breve*/, 761/*dotaccent*/, 771/*dieresis*/,
 
797
  0, 780/*ring*/, 785/*cedilla*/, 0, 793/*hungarumlaut*/, 806/*ogonek*/,
 
798
  813/*caron*/, 819/*emdash*/, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 
799
  826/*AE*/, 0, 829/*ordfeminine*/, 0, 0, 0, 0, 841/*Lslash*/, 848/*Oslash*/,
 
800
  855/*OE*/, 858/*ordmasculine*/, 0, 0, 0, 0, 0, 871/*ae*/, 0, 0, 0,
 
801
  874/*dotlessi*/, 0, 0, 883/*lslash*/, 890/*oslash*/, 897/*oe*/,
 
802
  900/*germandbls*/, 0, 0, 0, 0,
 
803
};
 
804
 
 
805
#define ps_standard_encoding(index) ((index) ? ps_standard_encoding_symbol+ps_standard_encoding_offset[(index)] : NULL)
 
806
 
 
807
static cairo_status_t
 
808
use_standard_encoding_glyph (cairo_type1_font_subset_t *font, int index)
 
809
{
 
810
    const char *glyph_name;
 
811
 
 
812
    if (index < 0 || index > 255)
 
813
        return CAIRO_STATUS_SUCCESS;
 
814
 
 
815
    glyph_name = ps_standard_encoding(index);
 
816
    if (glyph_name == NULL)
 
817
        return CAIRO_STATUS_SUCCESS;
 
818
 
 
819
    index = cairo_type1_font_subset_lookup_glyph (font,
 
820
                                                  glyph_name,
 
821
                                                  strlen(glyph_name));
 
822
    if (index < 0)
 
823
        return CAIRO_INT_STATUS_UNSUPPORTED;
 
824
 
 
825
    cairo_type1_font_subset_use_glyph (font, index);
 
826
 
 
827
    return CAIRO_STATUS_SUCCESS;
 
828
}
 
829
 
 
830
#define TYPE1_CHARSTRING_COMMAND_ESCAPE         (12)
 
831
#define TYPE1_CHARSTRING_COMMAND_SEAC           (32 + 6)
 
832
 
 
833
static cairo_status_t
 
834
cairo_type1_font_subset_look_for_seac(cairo_type1_font_subset_t *font,
 
835
                                      const char *name, int name_length,
 
836
                                      const char *encrypted_charstring, int encrypted_charstring_length)
 
837
{
 
838
    cairo_status_t status;
 
839
    unsigned char *charstring;
 
840
    const unsigned char *end;
 
841
    const unsigned char *p;
 
842
    int stack[5], sp, value;
 
843
    int command;
 
844
 
 
845
    charstring = malloc (encrypted_charstring_length);
 
846
    if (unlikely (charstring == NULL))
 
847
        return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
848
 
 
849
    cairo_type1_font_subset_decrypt_charstring ((const unsigned char *)
 
850
                                                encrypted_charstring,
 
851
                                                encrypted_charstring_length,
 
852
                                                charstring);
 
853
    end = charstring + encrypted_charstring_length;
 
854
 
 
855
    p = charstring + 4;
 
856
    sp = 0;
 
857
 
 
858
    while (p < end) {
 
859
        if (*p < 32) {
 
860
            command = *p++;
 
861
 
 
862
            if (command == TYPE1_CHARSTRING_COMMAND_ESCAPE)
 
863
                command = 32 + *p++;
 
864
 
 
865
            switch (command) {
 
866
            case TYPE1_CHARSTRING_COMMAND_SEAC:
 
867
                /* The seac command takes five integer arguments.  The
 
868
                 * last two are glyph indices into the PS standard
 
869
                 * encoding give the names of the glyphs that this
 
870
                 * glyph is composed from.  All we need to do is to
 
871
                 * make sure those glyphs are present in the subset
 
872
                 * under their standard names. */
 
873
                status = use_standard_encoding_glyph (font, stack[3]);
 
874
                if (unlikely (status))
 
875
                    return status;
 
876
 
 
877
                status = use_standard_encoding_glyph (font, stack[4]);
 
878
                if (unlikely (status))
 
879
                    return status;
 
880
 
 
881
                sp = 0;
 
882
                break;
 
883
 
 
884
            default:
 
885
                sp = 0;
 
886
                break;
 
887
            }
 
888
        } else {
 
889
            /* integer argument */
 
890
            p = cairo_type1_font_subset_decode_integer (p, &value);
 
891
            if (sp < 5)
 
892
                stack[sp++] = value;
 
893
        }
 
894
    }
 
895
 
 
896
    free (charstring);
 
897
 
 
898
    return CAIRO_STATUS_SUCCESS;
 
899
}
 
900
 
 
901
static cairo_status_t
 
902
write_used_glyphs (cairo_type1_font_subset_t *font,
 
903
                   const char *name, int name_length,
 
904
                   const char *charstring, int charstring_length)
 
905
{
 
906
    cairo_status_t status;
 
907
    char buffer[256];
 
908
    int length;
 
909
 
 
910
    length = snprintf (buffer, sizeof buffer,
 
911
                       "/%.*s %d %s ",
 
912
                       name_length, name, charstring_length, font->rd);
 
913
    status = cairo_type1_font_subset_write_encrypted (font, buffer, length);
 
914
    if (unlikely (status))
 
915
        return status;
 
916
 
 
917
    status = cairo_type1_font_subset_write_encrypted (font,
 
918
                                                      charstring,
 
919
                                                      charstring_length);
 
920
    if (unlikely (status))
 
921
        return status;
 
922
 
 
923
    length = snprintf (buffer, sizeof buffer, "%s\n", font->nd);
 
924
    status = cairo_type1_font_subset_write_encrypted (font, buffer, length);
 
925
    if (unlikely (status))
 
926
        return status;
 
927
 
 
928
    return CAIRO_STATUS_SUCCESS;
 
929
}
 
930
 
 
931
typedef cairo_status_t (*glyph_func_t) (cairo_type1_font_subset_t *font,
 
932
                                        const char *name, int name_length,
 
933
                                        const char *charstring, int charstring_length);
 
934
 
 
935
static cairo_status_t
 
936
cairo_type1_font_subset_for_each_glyph (cairo_type1_font_subset_t *font,
 
937
                                        const char *dict_start,
 
938
                                        const char *dict_end,
 
939
                                        glyph_func_t func,
 
940
                                        const char **dict_out)
 
941
{
 
942
    int charstring_length, name_length, glyph_index;
 
943
    const char *p, *charstring, *name;
 
944
    char *end;
 
945
 
 
946
    /* We're looking at '/' in the name of the first glyph.  The glyph
 
947
     * definitions are on the form:
 
948
     *
 
949
     *   /name 23 RD <23 binary bytes> ND
 
950
     *
 
951
     * or alternatively using -| and |- instead of RD and ND.
 
952
     *
 
953
     * We parse the glyph name and see if it is in the subset.  If it
 
954
     * is, we call the specified callback with the glyph name and
 
955
     * glyph data, otherwise we just skip it.  We need to parse
 
956
     * through a glyph definition; we can't just find the next '/',
 
957
     * since the binary data could contain a '/'.
 
958
     */
 
959
 
 
960
    p = dict_start;
 
961
 
 
962
    while (*p == '/') {
 
963
        name = p + 1;
 
964
        p = skip_token (p, dict_end);
 
965
        name_length = p - name;
 
966
 
 
967
        charstring_length = strtol (p, &end, 10);
 
968
        if (p == end)
 
969
            return CAIRO_INT_STATUS_UNSUPPORTED;
 
970
 
 
971
        /* Skip past -| or RD to binary data.  There is exactly one space
 
972
         * between the -| or RD token and the encrypted data, thus '+ 1'. */
 
973
        charstring = skip_token (end, dict_end) + 1;
 
974
 
 
975
        /* Skip binary data and |- or ND token. */
 
976
        p = skip_token (charstring + charstring_length, dict_end);
 
977
        while (p < dict_end && _cairo_isspace(*p))
 
978
            p++;
 
979
 
 
980
        /* In case any of the skip_token() calls above reached EOF, p will
 
981
         * be equal to dict_end. */
 
982
        if (p == dict_end)
 
983
            return CAIRO_INT_STATUS_UNSUPPORTED;
 
984
 
 
985
        glyph_index = cairo_type1_font_subset_lookup_glyph (font,
 
986
                                                            name, name_length);
 
987
        if (font->glyphs[glyph_index].subset_index >= 0) {
 
988
            cairo_status_t status = func (font,
 
989
                                          name, name_length,
 
990
                                          charstring, charstring_length);
 
991
            if (unlikely (status))
 
992
                return status;
 
993
        }
 
994
    }
 
995
 
 
996
    *dict_out = p;
 
997
 
 
998
    return CAIRO_STATUS_SUCCESS;
 
999
}
 
1000
 
 
1001
 
 
1002
static cairo_status_t
 
1003
cairo_type1_font_subset_write_private_dict (cairo_type1_font_subset_t *font,
 
1004
                                            const char                *name)
 
1005
{
 
1006
    cairo_status_t status;
 
1007
    const char *p, *charstrings, *dict_start;
 
1008
    const char *closefile_token;
 
1009
    char buffer[32], *glyph_count_end;
 
1010
    int num_charstrings, length;
 
1011
 
 
1012
    /* The private dict holds hint information, common subroutines and
 
1013
     * the actual glyph definitions (charstrings).
 
1014
     *
 
1015
     * FIXME: update this comment.
 
1016
     *
 
1017
     * What we do here is scan directly the /CharString token, which
 
1018
     * marks the beginning of the glyph definitions.  Then we parse
 
1019
     * through the glyph definitions and weed out the glyphs not in
 
1020
     * our subset.  Everything else before and after the glyph
 
1021
     * definitions is copied verbatim to the output.  It might be
 
1022
     * worthwile to figure out which of the common subroutines are
 
1023
     * used by the glyphs in the subset and get rid of the rest. */
 
1024
 
 
1025
    /* FIXME: The /Subrs array contains binary data and could
 
1026
     * conceivably have "/CharStrings" in it, so we might need to skip
 
1027
     * this more cleverly. */
 
1028
    charstrings = find_token (font->cleartext, font->cleartext_end, "/CharStrings");
 
1029
    if (charstrings == NULL)
 
1030
        return CAIRO_INT_STATUS_UNSUPPORTED;
 
1031
 
 
1032
    /* Scan past /CharStrings and the integer following it. */
 
1033
    p = charstrings + strlen ("/CharStrings");
 
1034
    num_charstrings = strtol (p, &glyph_count_end, 10);
 
1035
    if (p == glyph_count_end)
 
1036
        return CAIRO_INT_STATUS_UNSUPPORTED;
 
1037
 
 
1038
    /* Look for a '/' which marks the beginning of the first glyph
 
1039
     * definition. */
 
1040
    for (p = glyph_count_end; p < font->cleartext_end; p++)
 
1041
        if (*p == '/')
 
1042
            break;
 
1043
    if (p == font->cleartext_end)
 
1044
        return CAIRO_INT_STATUS_UNSUPPORTED;
 
1045
    dict_start = p;
 
1046
 
 
1047
    status = cairo_type1_font_subset_get_glyph_names_and_widths (font);
 
1048
    if (unlikely (status))
 
1049
        return status;
 
1050
 
 
1051
    /* Now that we have the private dictionary broken down in
 
1052
     * sections, do the first pass through the glyph definitions to
 
1053
     * figure out which subrs and othersubrs are use and which extra
 
1054
     * glyphs may be required by the seac operator. */
 
1055
    status = cairo_type1_font_subset_for_each_glyph (font,
 
1056
                                                     dict_start,
 
1057
                                                     font->cleartext_end,
 
1058
                                                     cairo_type1_font_subset_look_for_seac,
 
1059
                                                     &p);
 
1060
    if (unlikely (status))
 
1061
        return status;
 
1062
 
 
1063
    closefile_token = find_token (p, font->cleartext_end, "closefile");
 
1064
    if (closefile_token == NULL)
 
1065
        return CAIRO_INT_STATUS_UNSUPPORTED;
 
1066
 
 
1067
    status = cairo_type1_font_subset_get_glyph_names_and_widths (font);
 
1068
    if (unlikely (status))
 
1069
        return status;
 
1070
 
 
1071
    /* We're ready to start outputting. First write the header,
 
1072
     * i.e. the public part of the font dict.*/
 
1073
    status = cairo_type1_font_subset_write_header (font, name);
 
1074
    if (unlikely (status))
 
1075
        return status;
 
1076
 
 
1077
    font->base.header_size = _cairo_output_stream_get_position (font->output);
 
1078
 
 
1079
 
 
1080
    /* Start outputting the private dict.  First output everything up
 
1081
     * to the /CharStrings token. */
 
1082
    status = cairo_type1_font_subset_write_encrypted (font, font->cleartext,
 
1083
                                                 charstrings - font->cleartext);
 
1084
    if (unlikely (status))
 
1085
        return status;
 
1086
 
 
1087
    /* Write out new charstring count */
 
1088
    length = snprintf (buffer, sizeof buffer,
 
1089
                       "/CharStrings %d", font->num_glyphs);
 
1090
    status = cairo_type1_font_subset_write_encrypted (font, buffer, length);
 
1091
    if (unlikely (status))
 
1092
        return status;
 
1093
 
 
1094
    /* Write out text between the charstring count and the first
 
1095
     * charstring definition */
 
1096
    status = cairo_type1_font_subset_write_encrypted (font, glyph_count_end,
 
1097
                                                  dict_start - glyph_count_end);
 
1098
    if (unlikely (status))
 
1099
        return status;
 
1100
 
 
1101
    /* Write out the charstring definitions for each of the glyphs in
 
1102
     * the subset. */
 
1103
    status = cairo_type1_font_subset_for_each_glyph (font,
 
1104
                                                     dict_start,
 
1105
                                                     font->cleartext_end,
 
1106
                                                     write_used_glyphs,
 
1107
                                                     &p);
 
1108
    if (unlikely (status))
 
1109
        return status;
 
1110
 
 
1111
    /* Output what's left between the end of the glyph definitions and
 
1112
     * the end of the private dict to the output. */
 
1113
    status = cairo_type1_font_subset_write_encrypted (font, p,
 
1114
                                closefile_token - p + strlen ("closefile") + 1);
 
1115
    if (unlikely (status))
 
1116
        return status;
 
1117
 
 
1118
    if (font->hex_encode)
 
1119
        _cairo_output_stream_write (font->output, "\n", 1);
 
1120
 
 
1121
    return CAIRO_STATUS_SUCCESS;
 
1122
}
 
1123
 
 
1124
static cairo_status_t
 
1125
cairo_type1_font_subset_write_trailer(cairo_type1_font_subset_t *font)
 
1126
{
 
1127
    const char *cleartomark_token;
 
1128
    int i;
 
1129
    static const char zeros[65] =
 
1130
        "0000000000000000000000000000000000000000000000000000000000000000\n";
 
1131
 
 
1132
 
 
1133
    for (i = 0; i < 8; i++)
 
1134
        _cairo_output_stream_write (font->output, zeros, sizeof zeros);
 
1135
 
 
1136
    cleartomark_token = find_token (font->type1_data, font->type1_end, "cleartomark");
 
1137
    if (cleartomark_token) {
 
1138
        /* Some fonts have conditional save/restore around the entire
 
1139
         * font dict, so we need to retain whatever postscript code
 
1140
         * that may come after 'cleartomark'. */
 
1141
 
 
1142
        _cairo_output_stream_write (font->output, cleartomark_token,
 
1143
                                    font->type1_end - cleartomark_token);
 
1144
    } else if (!font->eexec_segment_is_ascii) {
 
1145
        /* Fonts embedded in PDF may omit the fixed-content portion
 
1146
         * that includes the 'cleartomark' operator. Type 1 in PDF is
 
1147
         * always binary. */
 
1148
 
 
1149
        _cairo_output_stream_printf (font->output, "cleartomark");
 
1150
    } else {
 
1151
        return CAIRO_INT_STATUS_UNSUPPORTED;
 
1152
    }
 
1153
 
 
1154
    /* some fonts do not have a newline at the end of the last line */
 
1155
    _cairo_output_stream_printf (font->output, "\n");
 
1156
 
 
1157
    return CAIRO_STATUS_SUCCESS;
 
1158
}
 
1159
 
 
1160
static cairo_status_t
 
1161
type1_font_write (void *closure, const unsigned char *data, unsigned int length)
 
1162
{
 
1163
    cairo_type1_font_subset_t *font = closure;
 
1164
 
 
1165
    return _cairo_array_append_multiple (&font->contents, data, length);
 
1166
}
 
1167
 
 
1168
static cairo_status_t
 
1169
cairo_type1_font_subset_write (cairo_type1_font_subset_t *font,
 
1170
                               const char *name)
 
1171
{
 
1172
    cairo_status_t status;
 
1173
 
 
1174
    status = cairo_type1_font_subset_find_segments (font);
 
1175
    if (unlikely (status))
 
1176
        return status;
 
1177
 
 
1178
    status = cairo_type1_font_subset_decrypt_eexec_segment (font);
 
1179
    if (unlikely (status))
 
1180
        return status;
 
1181
 
 
1182
    /* Determine which glyph definition delimiters to use. */
 
1183
    if (find_token (font->cleartext, font->cleartext_end, "/-|") != NULL) {
 
1184
        font->rd = "-|";
 
1185
        font->nd = "|-";
 
1186
    } else if (find_token (font->cleartext, font->cleartext_end, "/RD") != NULL) {
 
1187
        font->rd = "RD";
 
1188
        font->nd = "ND";
 
1189
    } else {
 
1190
        /* Don't know *what* kind of font this is... */
 
1191
        return CAIRO_INT_STATUS_UNSUPPORTED;
 
1192
    }
 
1193
 
 
1194
    font->eexec_key = CAIRO_TYPE1_PRIVATE_DICT_KEY;
 
1195
    font->hex_column = 0;
 
1196
 
 
1197
    status = cairo_type1_font_subset_write_private_dict (font, name);
 
1198
    if (unlikely (status))
 
1199
        return status;
 
1200
 
 
1201
    font->base.data_size = _cairo_output_stream_get_position (font->output) -
 
1202
        font->base.header_size;
 
1203
 
 
1204
    status = cairo_type1_font_subset_write_trailer (font);
 
1205
    if (unlikely (status))
 
1206
        return status;
 
1207
 
 
1208
    font->base.trailer_size =
 
1209
        _cairo_output_stream_get_position (font->output) -
 
1210
        font->base.header_size - font->base.data_size;
 
1211
 
 
1212
    return CAIRO_STATUS_SUCCESS;
 
1213
}
 
1214
 
 
1215
static cairo_status_t
 
1216
cairo_type1_font_subset_generate (void       *abstract_font,
 
1217
                                  const char *name)
 
1218
 
 
1219
{
 
1220
    cairo_type1_font_subset_t *font = abstract_font;
 
1221
    cairo_ft_unscaled_font_t *ft_unscaled_font;
 
1222
    unsigned long ret;
 
1223
    cairo_status_t status;
 
1224
 
 
1225
    ft_unscaled_font = (cairo_ft_unscaled_font_t *) font->base.unscaled_font;
 
1226
    font->face = _cairo_ft_unscaled_font_lock_face (ft_unscaled_font);
 
1227
    if (unlikely (font->face == NULL))
 
1228
        return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
1229
 
 
1230
    font->type1_length = font->face->stream->size;
 
1231
    font->type1_data = malloc (font->type1_length);
 
1232
    if (unlikely (font->type1_data == NULL)) {
 
1233
        status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
1234
        goto fail;
 
1235
    }
 
1236
 
 
1237
    if (font->face->stream->read != NULL) {
 
1238
        /* Note that read() may be implemented as a macro, thanks POSIX!, so we
 
1239
         * need to wrap the following usage in parentheses in order to
 
1240
         * disambiguate it for the pre-processor - using the verbose function
 
1241
         * pointer dereference for clarity.
 
1242
         */
 
1243
        ret = (* font->face->stream->read) (font->face->stream, 0,
 
1244
                                            (unsigned char *) font->type1_data,
 
1245
                                            font->type1_length);
 
1246
        if (ret != font->type1_length) {
 
1247
            status = _cairo_error (CAIRO_STATUS_READ_ERROR);
 
1248
            goto fail;
 
1249
        }
 
1250
    } else {
 
1251
        memcpy (font->type1_data,
 
1252
                font->face->stream->base, font->type1_length);
 
1253
    }
 
1254
 
 
1255
    status = _cairo_array_grow_by (&font->contents, 4096);
 
1256
    if (unlikely (status))
 
1257
        goto fail;
 
1258
 
 
1259
    font->output = _cairo_output_stream_create (type1_font_write, NULL, font);
 
1260
    if (unlikely ((status = font->output->status)))
 
1261
        goto fail;
 
1262
 
 
1263
    status = cairo_type1_font_subset_write (font, name);
 
1264
    if (unlikely (status))
 
1265
        goto fail;
 
1266
 
 
1267
    font->base.data = _cairo_array_index (&font->contents, 0);
 
1268
 
 
1269
 fail:
 
1270
    _cairo_ft_unscaled_font_unlock_face (ft_unscaled_font);
 
1271
 
 
1272
    return status;
 
1273
}
 
1274
 
 
1275
static cairo_status_t
 
1276
_cairo_type1_font_subset_fini (cairo_type1_font_subset_t *font)
 
1277
{
 
1278
    cairo_status_t status = CAIRO_STATUS_SUCCESS;
 
1279
    unsigned int i;
 
1280
 
 
1281
    /* If the subset generation failed, some of the pointers below may
 
1282
     * be NULL depending on at which point the error occurred. */
 
1283
 
 
1284
    _cairo_array_fini (&font->contents);
 
1285
 
 
1286
    free (font->type1_data);
 
1287
    if (font->glyphs != NULL) {
 
1288
        for (i = 0; i < font->base.num_glyphs; i++)
 
1289
            free (font->glyphs[i].name);
 
1290
    }
 
1291
 
 
1292
    _cairo_unscaled_font_destroy (font->base.unscaled_font);
 
1293
 
 
1294
    if (font->output != NULL)
 
1295
        status = _cairo_output_stream_destroy (font->output);
 
1296
 
 
1297
    if (font->base.base_font)
 
1298
        free (font->base.base_font);
 
1299
    free (font->glyphs);
 
1300
 
 
1301
    return status;
 
1302
}
 
1303
 
 
1304
cairo_status_t
 
1305
_cairo_type1_subset_init (cairo_type1_subset_t          *type1_subset,
 
1306
                          const char                    *name,
 
1307
                          cairo_scaled_font_subset_t    *scaled_font_subset,
 
1308
                          cairo_bool_t                   hex_encode)
 
1309
{
 
1310
    cairo_type1_font_subset_t font;
 
1311
    cairo_status_t status, status_ignored;
 
1312
    unsigned long parent_glyph, length;
 
1313
    unsigned int i;
 
1314
    cairo_unscaled_font_t *unscaled_font;
 
1315
    char buf[30];
 
1316
 
 
1317
    /* XXX: Need to fix this to work with a general cairo_unscaled_font_t. */
 
1318
    if (!_cairo_scaled_font_is_ft (scaled_font_subset->scaled_font))
 
1319
        return CAIRO_INT_STATUS_UNSUPPORTED;
 
1320
 
 
1321
    if (_cairo_ft_scaled_font_is_vertical (scaled_font_subset->scaled_font))
 
1322
        return CAIRO_INT_STATUS_UNSUPPORTED;
 
1323
 
 
1324
    unscaled_font = _cairo_ft_scaled_font_get_unscaled_font (scaled_font_subset->scaled_font);
 
1325
 
 
1326
    status = _cairo_type1_font_subset_init (&font, unscaled_font, hex_encode);
 
1327
    if (unlikely (status))
 
1328
        return status;
 
1329
 
 
1330
    for (i = 0; i < scaled_font_subset->num_glyphs; i++) {
 
1331
        parent_glyph = scaled_font_subset->glyphs[i];
 
1332
        cairo_type1_font_subset_use_glyph (&font, parent_glyph);
 
1333
    }
 
1334
 
 
1335
    status = cairo_type1_font_subset_generate (&font, name);
 
1336
    if (unlikely (status))
 
1337
        goto fail1;
 
1338
 
 
1339
    if (font.base.base_font) {
 
1340
        type1_subset->base_font = strdup (font.base.base_font);
 
1341
    } else {
 
1342
        snprintf(buf, sizeof (buf), "CairoFont-%u-%u",
 
1343
                 scaled_font_subset->font_id, scaled_font_subset->subset_id);
 
1344
        type1_subset->base_font = strdup (buf);
 
1345
    }
 
1346
    if (unlikely (type1_subset->base_font == NULL))
 
1347
        goto fail1;
 
1348
 
 
1349
    type1_subset->widths = calloc (sizeof (double), font.num_glyphs);
 
1350
    if (unlikely (type1_subset->widths == NULL))
 
1351
        goto fail2;
 
1352
    for (i = 0; i < font.base.num_glyphs; i++) {
 
1353
        if (font.glyphs[i].subset_index < 0)
 
1354
            continue;
 
1355
        type1_subset->widths[font.glyphs[i].subset_index] =
 
1356
            font.glyphs[i].width;
 
1357
    }
 
1358
 
 
1359
    type1_subset->x_min = font.base.x_min;
 
1360
    type1_subset->y_min = font.base.y_min;
 
1361
    type1_subset->x_max = font.base.x_max;
 
1362
    type1_subset->y_max = font.base.y_max;
 
1363
    type1_subset->ascent = font.base.ascent;
 
1364
    type1_subset->descent = font.base.descent;
 
1365
 
 
1366
    length = font.base.header_size +
 
1367
             font.base.data_size +
 
1368
             font.base.trailer_size;
 
1369
    type1_subset->data = malloc (length);
 
1370
    if (unlikely (type1_subset->data == NULL))
 
1371
        goto fail3;
 
1372
 
 
1373
    memcpy (type1_subset->data,
 
1374
            _cairo_array_index (&font.contents, 0), length);
 
1375
 
 
1376
    type1_subset->header_length = font.base.header_size;
 
1377
    type1_subset->data_length = font.base.data_size;
 
1378
    type1_subset->trailer_length = font.base.trailer_size;
 
1379
 
 
1380
    return _cairo_type1_font_subset_fini (&font);
 
1381
 
 
1382
 fail3:
 
1383
    free (type1_subset->widths);
 
1384
 fail2:
 
1385
    free (type1_subset->base_font);
 
1386
 fail1:
 
1387
    status_ignored = _cairo_type1_font_subset_fini (&font);
 
1388
 
 
1389
    return status;
 
1390
}
 
1391
 
 
1392
void
 
1393
_cairo_type1_subset_fini (cairo_type1_subset_t *subset)
 
1394
{
 
1395
    free (subset->base_font);
 
1396
    free (subset->widths);
 
1397
    free (subset->data);
 
1398
}
 
1399
 
 
1400
cairo_bool_t
 
1401
_cairo_type1_scaled_font_is_type1 (cairo_scaled_font_t *scaled_font)
 
1402
{
 
1403
    cairo_ft_unscaled_font_t *unscaled;
 
1404
    FT_Face face;
 
1405
    PS_FontInfoRec font_info;
 
1406
    cairo_bool_t is_type1 = FALSE;
 
1407
 
 
1408
    if (!_cairo_scaled_font_is_ft (scaled_font))
 
1409
       return FALSE;
 
1410
    unscaled = (cairo_ft_unscaled_font_t *) _cairo_ft_scaled_font_get_unscaled_font (scaled_font);
 
1411
    face = _cairo_ft_unscaled_font_lock_face (unscaled);
 
1412
    if (!face)
 
1413
        return FALSE;
 
1414
 
 
1415
    if (FT_Get_PS_Font_Info(face, &font_info) == 0)
 
1416
        is_type1 = TRUE;
 
1417
 
 
1418
    /* OpenType/CFF fonts also have a PS_FontInfoRec */
 
1419
#if HAVE_FT_LOAD_SFNT_TABLE
 
1420
    if (FT_IS_SFNT (face))
 
1421
        is_type1 = FALSE;
 
1422
#endif
 
1423
 
 
1424
    _cairo_ft_unscaled_font_unlock_face (unscaled);
 
1425
 
 
1426
    return is_type1;
 
1427
}
 
1428
 
 
1429
#endif /* CAIRO_HAS_FT_FONT */
 
1430
 
 
1431
#endif /* CAIRO_HAS_FONT_SUBSET */