~ubuntu-branches/ubuntu/quantal/cairo/quantal-proposed

« back to all changes in this revision

Viewing changes to .pc/lp-#1030357.patch/src/cairo-cff-subset.c

  • Committer: Package Import Robot
  • Author(s): Stéphane Graber
  • Date: 2012-09-28 15:20:19 UTC
  • Revision ID: package-import@ubuntu.com-20120928152019-cobqis5072pxxfe4
Tags: 1.12.2-1ubuntu2
* Cherry-pick fixes from upstream (LP: #1030357)
  Thanks to Edward Donovan for the patch.
  - cff subsetting: widths can be floating point
  - cff: initialise variable to prevent valgrind warning
  - cff: use correct size for buffer
  - cff: convert '.' to locale specific decimal point before using sscanf
  - cff-subsetting: Ignore charset for non cid fonts

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 Adrian Johnson
 
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 Adrian Johnson.
 
31
 *
 
32
 * Contributor(s):
 
33
 *      Adrian Johnson <ajohnson@redneon.com>
 
34
 *      Eugeniy Meshcheryakov <eugen@debian.org>
 
35
 */
 
36
 
 
37
/*
 
38
 * Useful links:
 
39
 * http://www.adobe.com/content/dam/Adobe/en/devnet/font/pdfs/5176.CFF.pdf
 
40
 * http://www.adobe.com/content/dam/Adobe/en/devnet/font/pdfs/5177.Type2.pdf
 
41
 */
 
42
 
 
43
#define _BSD_SOURCE /* for snprintf(), strdup() */
 
44
#include "cairoint.h"
 
45
 
 
46
#include "cairo-array-private.h"
 
47
#include "cairo-error-private.h"
 
48
 
 
49
#if CAIRO_HAS_FONT_SUBSET
 
50
 
 
51
#include "cairo-scaled-font-subsets-private.h"
 
52
#include "cairo-truetype-subset-private.h"
 
53
#include <string.h>
 
54
 
 
55
/* CFF Dict Operators. If the high byte is 0 the command is encoded
 
56
 * with a single byte. */
 
57
#define BASEFONTNAME_OP  0x0c16
 
58
#define CIDCOUNT_OP      0x0c22
 
59
#define CHARSET_OP       0x000f
 
60
#define CHARSTRINGS_OP   0x0011
 
61
#define COPYRIGHT_OP     0x0c00
 
62
#define DEFAULTWIDTH_OP  0x0014
 
63
#define ENCODING_OP      0x0010
 
64
#define FAMILYNAME_OP    0x0003
 
65
#define FDARRAY_OP       0x0c24
 
66
#define FDSELECT_OP      0x0c25
 
67
#define FONTBBOX_OP      0x0005
 
68
#define FONTMATRIX_OP    0x0c07
 
69
#define FONTNAME_OP      0x0c26
 
70
#define FULLNAME_OP      0x0002
 
71
#define LOCAL_SUB_OP     0x0013
 
72
#define NOMINALWIDTH_OP  0x0015
 
73
#define NOTICE_OP        0x0001
 
74
#define POSTSCRIPT_OP    0x0c15
 
75
#define PRIVATE_OP       0x0012
 
76
#define ROS_OP           0x0c1e
 
77
#define UNIQUEID_OP      0x000d
 
78
#define VERSION_OP       0x0000
 
79
#define WEIGHT_OP        0x0004
 
80
#define XUID_OP          0x000e
 
81
 
 
82
#define NUM_STD_STRINGS 391
 
83
 
 
84
/* Type 2 Charstring operators */
 
85
#define TYPE2_hstem     0x0001
 
86
#define TYPE2_vstem     0x0003
 
87
#define TYPE2_callsubr  0x000a
 
88
 
 
89
#define TYPE2_return    0x000b
 
90
#define TYPE2_endchar   0x000e
 
91
 
 
92
#define TYPE2_hstemhm   0x0012
 
93
#define TYPE2_hintmask  0x0013
 
94
#define TYPE2_cntrmask  0x0014
 
95
#define TYPE2_vstemhm   0x0017
 
96
#define TYPE2_callgsubr 0x001d
 
97
 
 
98
#define TYPE2_rmoveto   0x0015
 
99
#define TYPE2_hmoveto   0x0016
 
100
#define TYPE2_vmoveto   0x0004
 
101
 
 
102
 
 
103
#define MAX_SUBROUTINE_NESTING 10 /* From Type2 Charstring spec */
 
104
 
 
105
 
 
106
typedef struct _cff_header {
 
107
    uint8_t major;
 
108
    uint8_t minor;
 
109
    uint8_t header_size;
 
110
    uint8_t offset_size;
 
111
} cff_header_t;
 
112
 
 
113
typedef struct _cff_index_element {
 
114
    cairo_bool_t   is_copy;
 
115
    unsigned char *data;
 
116
    int            length;
 
117
} cff_index_element_t;
 
118
 
 
119
typedef struct _cff_dict_operator {
 
120
    cairo_hash_entry_t base;
 
121
 
 
122
    unsigned short operator;
 
123
    unsigned char *operand;
 
124
    int            operand_length;
 
125
    int            operand_offset;
 
126
} cff_dict_operator_t;
 
127
 
 
128
typedef struct _cairo_cff_font {
 
129
 
 
130
    cairo_scaled_font_subset_t *scaled_font_subset;
 
131
    const cairo_scaled_font_backend_t *backend;
 
132
 
 
133
    /* Font Data */
 
134
    unsigned char       *data;
 
135
    unsigned long        data_length;
 
136
    unsigned char       *current_ptr;
 
137
    unsigned char       *data_end;
 
138
    cff_header_t        *header;
 
139
    char                *font_name;
 
140
    char                *ps_name;
 
141
    cairo_hash_table_t  *top_dict;
 
142
    cairo_hash_table_t  *private_dict;
 
143
    cairo_array_t        strings_index;
 
144
    cairo_array_t        charstrings_index;
 
145
    cairo_array_t        global_sub_index;
 
146
    cairo_array_t        local_sub_index;
 
147
    unsigned char       *charset;
 
148
    int                  num_glyphs;
 
149
    cairo_bool_t         is_cid;
 
150
    cairo_bool_t         is_opentype;
 
151
    int                  units_per_em;
 
152
    int                  global_sub_bias;
 
153
    int                  local_sub_bias;
 
154
    int                  default_width;
 
155
    int                  nominal_width;
 
156
 
 
157
    /* CID Font Data */
 
158
    int                 *fdselect;
 
159
    unsigned int         num_fontdicts;
 
160
    cairo_hash_table_t **fd_dict;
 
161
    cairo_hash_table_t **fd_private_dict;
 
162
    cairo_array_t       *fd_local_sub_index;
 
163
    int                 *fd_local_sub_bias;
 
164
    int                 *fd_default_width;
 
165
    int                 *fd_nominal_width;
 
166
 
 
167
    /* Subsetted Font Data */
 
168
    char                *subset_font_name;
 
169
    cairo_array_t        charstrings_subset_index;
 
170
    cairo_array_t        strings_subset_index;
 
171
    int                  euro_sid;
 
172
    int                 *fdselect_subset;
 
173
    unsigned int         num_subset_fontdicts;
 
174
    int                 *fd_subset_map;
 
175
    int                 *private_dict_offset;
 
176
    cairo_bool_t         subset_subroutines;
 
177
    cairo_bool_t        *global_subs_used;
 
178
    cairo_bool_t        *local_subs_used;
 
179
    cairo_bool_t       **fd_local_subs_used;
 
180
    cairo_array_t        output;
 
181
 
 
182
    /* Subset Metrics */
 
183
    int                 *widths;
 
184
    int                  x_min, y_min, x_max, y_max;
 
185
    int                  ascent, descent;
 
186
 
 
187
    /* Type 2 charstring data */
 
188
    int                  type2_stack_size;
 
189
    int                  type2_stack_top_value;
 
190
    cairo_bool_t         type2_stack_top_is_int;
 
191
    int                  type2_num_hints;
 
192
    int                  type2_hintmask_bytes;
 
193
    int                  type2_nesting_level;
 
194
    cairo_bool_t         type2_seen_first_int;
 
195
    cairo_bool_t         type2_find_width;
 
196
    cairo_bool_t         type2_found_width;
 
197
    int                  type2_width;
 
198
    cairo_bool_t         type2_has_path;
 
199
 
 
200
} cairo_cff_font_t;
 
201
 
 
202
/* Encoded integer using maximum sized encoding. This is required for
 
203
 * operands that are later modified after encoding. */
 
204
static unsigned char *
 
205
encode_integer_max (unsigned char *p, int i)
 
206
{
 
207
    *p++ = 29;
 
208
    *p++ = i >> 24;
 
209
    *p++ = (i >> 16) & 0xff;
 
210
    *p++ = (i >> 8)  & 0xff;
 
211
    *p++ = i & 0xff;
 
212
    return p;
 
213
}
 
214
 
 
215
static unsigned char *
 
216
encode_integer (unsigned char *p, int i)
 
217
{
 
218
    if (i >= -107 && i <= 107) {
 
219
        *p++ = i + 139;
 
220
    } else if (i >= 108 && i <= 1131) {
 
221
        i -= 108;
 
222
        *p++ = (i >> 8)+ 247;
 
223
        *p++ = i & 0xff;
 
224
    } else if (i >= -1131 && i <= -108) {
 
225
        i = -i - 108;
 
226
        *p++ = (i >> 8)+ 251;
 
227
        *p++ = i & 0xff;
 
228
    } else if (i >= -32768 && i <= 32767) {
 
229
        *p++ = 28;
 
230
        *p++ = (i >> 8)  & 0xff;
 
231
        *p++ = i & 0xff;
 
232
    } else {
 
233
        p = encode_integer_max (p, i);
 
234
    }
 
235
    return p;
 
236
}
 
237
 
 
238
static unsigned char *
 
239
decode_integer (unsigned char *p, int *integer)
 
240
{
 
241
    if (*p == 28) {
 
242
        *integer = (int)(p[1]<<8 | p[2]);
 
243
        p += 3;
 
244
    } else if (*p == 29) {
 
245
        *integer = (int)((p[1] << 24) | (p[2] << 16) | (p[3] << 8) | p[4]);
 
246
        p += 5;
 
247
    } else if (*p >= 32 && *p <= 246) {
 
248
        *integer = *p++ - 139;
 
249
    } else if (*p <= 250) {
 
250
        *integer = (p[0] - 247) * 256 + p[1] + 108;
 
251
        p += 2;
 
252
    } else if (*p <= 254) {
 
253
        *integer = -(p[0] - 251) * 256 - p[1] - 108;
 
254
        p += 2;
 
255
    } else {
 
256
        *integer = 0;
 
257
        p += 1;
 
258
    }
 
259
    return p;
 
260
}
 
261
 
 
262
static char *
 
263
decode_nibble (int n, char *buf)
 
264
{
 
265
    switch (n)
 
266
    {
 
267
    case 0xa:
 
268
        *buf++ = '.';
 
269
        break;
 
270
    case 0xb:
 
271
        *buf++ = 'E';
 
272
        break;
 
273
    case 0xc:
 
274
        *buf++ = 'E';
 
275
        *buf++ = '-';
 
276
        break;
 
277
    case 0xd:
 
278
        *buf++ = '-';
 
279
        break;
 
280
    case 0xe:
 
281
        *buf++ = '-';
 
282
        break;
 
283
    case 0xf:
 
284
        break;
 
285
    default:
 
286
        *buf++ = '0' + n;
 
287
        break;
 
288
    }
 
289
 
 
290
    return buf;
 
291
}
 
292
 
 
293
static unsigned char *
 
294
decode_real (unsigned char *p, double *real)
 
295
{
 
296
    int n;
 
297
    char buffer[100];
 
298
    char *buf = buffer;
 
299
    char *buf_end = buffer + sizeof (buf);
 
300
 
 
301
    p++;
 
302
    while (buf + 2 < buf_end) {
 
303
        n = *p >> 4;
 
304
        buf = decode_nibble (n, buf);
 
305
        n = *p & 0x0f;
 
306
        buf = decode_nibble (n, buf);
 
307
        if ((*p & 0x0f) == 0x0f) {
 
308
            p++;
 
309
            break;
 
310
        }
 
311
        p++;
 
312
    };
 
313
    *buf = 0;
 
314
 
 
315
    if (sscanf(buffer, "%lf", real) != 1)
 
316
        *real = 0.0;
 
317
 
 
318
    return p;
 
319
}
 
320
 
 
321
static unsigned char *
 
322
decode_number (unsigned char *p, double *number)
 
323
{
 
324
    if (*p == 30) {
 
325
        p = decode_real (p, number);
 
326
    } else {
 
327
        int i;
 
328
        p = decode_integer (p, &i);
 
329
        *number = i;
 
330
    }
 
331
    return p;
 
332
}
 
333
 
 
334
static unsigned char *
 
335
decode_operator (unsigned char *p, unsigned short *operator)
 
336
{
 
337
    unsigned short op = 0;
 
338
 
 
339
    op = *p++;
 
340
    if (op == 12) {
 
341
        op <<= 8;
 
342
        op |= *p++;
 
343
    }
 
344
    *operator = op;
 
345
    return p;
 
346
}
 
347
 
 
348
/* return 0 if not an operand */
 
349
static int
 
350
operand_length (unsigned char *p)
 
351
{
 
352
    unsigned char *begin = p;
 
353
 
 
354
    if (*p == 28)
 
355
        return 3;
 
356
 
 
357
    if (*p == 29)
 
358
        return 5;
 
359
 
 
360
    if (*p >= 32 && *p <= 246)
 
361
        return 1;
 
362
 
 
363
    if (*p >= 247 && *p <= 254)
 
364
        return 2;
 
365
 
 
366
    if (*p == 30) {
 
367
        while ((*p & 0x0f) != 0x0f)
 
368
            p++;
 
369
        return p - begin + 1;
 
370
    }
 
371
 
 
372
    return 0;
 
373
}
 
374
 
 
375
static unsigned char *
 
376
encode_index_offset (unsigned char *p, int offset_size, unsigned long offset)
 
377
{
 
378
    while (--offset_size >= 0) {
 
379
        p[offset_size] = (unsigned char) (offset & 0xff);
 
380
        offset >>= 8;
 
381
    }
 
382
    return p + offset_size;
 
383
}
 
384
 
 
385
static unsigned long
 
386
decode_index_offset(unsigned char *p, int off_size)
 
387
{
 
388
    unsigned long offset = 0;
 
389
 
 
390
    while (off_size-- > 0)
 
391
        offset = offset*256 + *p++;
 
392
    return offset;
 
393
}
 
394
 
 
395
static void
 
396
cff_index_init (cairo_array_t *index)
 
397
{
 
398
    _cairo_array_init (index, sizeof (cff_index_element_t));
 
399
}
 
400
 
 
401
static cairo_int_status_t
 
402
cff_index_read (cairo_array_t *index, unsigned char **ptr, unsigned char *end_ptr)
 
403
{
 
404
    cff_index_element_t element;
 
405
    unsigned char *data, *p;
 
406
    cairo_status_t status;
 
407
    int offset_size, count, start, i;
 
408
    int end = 0;
 
409
 
 
410
    p = *ptr;
 
411
    if (p + 2 > end_ptr)
 
412
        return CAIRO_INT_STATUS_UNSUPPORTED;
 
413
    count = be16_to_cpu( *((uint16_t *)p) );
 
414
    p += 2;
 
415
    if (count > 0) {
 
416
        offset_size = *p++;
 
417
        if (p + (count + 1)*offset_size > end_ptr)
 
418
            return CAIRO_INT_STATUS_UNSUPPORTED;
 
419
        data = p + offset_size*(count + 1) - 1;
 
420
        start = decode_index_offset (p, offset_size);
 
421
        p += offset_size;
 
422
        for (i = 0; i < count; i++) {
 
423
            end = decode_index_offset (p, offset_size);
 
424
            p += offset_size;
 
425
            if (p > end_ptr)
 
426
                return CAIRO_INT_STATUS_UNSUPPORTED;
 
427
            element.length = end - start;
 
428
            element.is_copy = FALSE;
 
429
            element.data = data + start;
 
430
            status = _cairo_array_append (index, &element);
 
431
            if (unlikely (status))
 
432
                return status;
 
433
            start = end;
 
434
        }
 
435
        p = data + end;
 
436
    }
 
437
    *ptr = p;
 
438
 
 
439
    return CAIRO_STATUS_SUCCESS;
 
440
}
 
441
 
 
442
static cairo_status_t
 
443
cff_index_write (cairo_array_t *index, cairo_array_t *output)
 
444
{
 
445
    int offset_size;
 
446
    int offset;
 
447
    int num_elem;
 
448
    int i;
 
449
    cff_index_element_t *element;
 
450
    uint16_t count;
 
451
    unsigned char buf[5];
 
452
    cairo_status_t status;
 
453
 
 
454
    num_elem = _cairo_array_num_elements (index);
 
455
    count = cpu_to_be16 ((uint16_t) num_elem);
 
456
    status = _cairo_array_append_multiple (output, &count, 2);
 
457
    if (unlikely (status))
 
458
        return status;
 
459
 
 
460
    if (num_elem == 0)
 
461
        return CAIRO_STATUS_SUCCESS;
 
462
 
 
463
    /* Find maximum offset to determine offset size */
 
464
    offset = 1;
 
465
    for (i = 0; i < num_elem; i++) {
 
466
        element = _cairo_array_index (index, i);
 
467
        offset += element->length;
 
468
    }
 
469
    if (offset < 0x100)
 
470
        offset_size = 1;
 
471
    else if (offset < 0x10000)
 
472
        offset_size = 2;
 
473
    else if (offset < 0x1000000)
 
474
        offset_size = 3;
 
475
    else
 
476
        offset_size = 4;
 
477
 
 
478
    buf[0] = (unsigned char) offset_size;
 
479
    status = _cairo_array_append (output, buf);
 
480
    if (unlikely (status))
 
481
        return status;
 
482
 
 
483
    offset = 1;
 
484
    encode_index_offset (buf, offset_size, offset);
 
485
    status = _cairo_array_append_multiple (output, buf, offset_size);
 
486
    if (unlikely (status))
 
487
        return status;
 
488
 
 
489
    for (i = 0; i < num_elem; i++) {
 
490
        element = _cairo_array_index (index, i);
 
491
        offset += element->length;
 
492
        encode_index_offset (buf, offset_size, offset);
 
493
        status = _cairo_array_append_multiple (output, buf, offset_size);
 
494
        if (unlikely (status))
 
495
            return status;
 
496
    }
 
497
 
 
498
    for (i = 0; i < num_elem; i++) {
 
499
        element = _cairo_array_index (index, i);
 
500
        if (element->length > 0) {
 
501
            status = _cairo_array_append_multiple (output,
 
502
                                                   element->data,
 
503
                                                   element->length);
 
504
        }
 
505
        if (unlikely (status))
 
506
            return status;
 
507
    }
 
508
    return CAIRO_STATUS_SUCCESS;
 
509
}
 
510
 
 
511
static void
 
512
cff_index_set_object (cairo_array_t *index, int obj_index,
 
513
                      unsigned char *object , int length)
 
514
{
 
515
    cff_index_element_t *element;
 
516
 
 
517
    element = _cairo_array_index (index, obj_index);
 
518
    if (element->is_copy)
 
519
        free (element->data);
 
520
 
 
521
    element->data = object;
 
522
    element->length = length;
 
523
    element->is_copy = FALSE;
 
524
}
 
525
 
 
526
static cairo_status_t
 
527
cff_index_append (cairo_array_t *index, unsigned char *object , int length)
 
528
{
 
529
    cff_index_element_t element;
 
530
 
 
531
    element.length = length;
 
532
    element.is_copy = FALSE;
 
533
    element.data = object;
 
534
 
 
535
    return _cairo_array_append (index, &element);
 
536
}
 
537
 
 
538
static cairo_status_t
 
539
cff_index_append_copy (cairo_array_t *index,
 
540
                       const unsigned char *object,
 
541
                       unsigned int length)
 
542
{
 
543
    cff_index_element_t element;
 
544
    cairo_status_t status;
 
545
 
 
546
    element.length = length;
 
547
    element.is_copy = TRUE;
 
548
    element.data = malloc (element.length);
 
549
    if (unlikely (element.data == NULL))
 
550
        return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
551
 
 
552
    memcpy (element.data, object, element.length);
 
553
 
 
554
    status = _cairo_array_append (index, &element);
 
555
    if (unlikely (status)) {
 
556
        free (element.data);
 
557
        return status;
 
558
    }
 
559
 
 
560
    return CAIRO_STATUS_SUCCESS;
 
561
}
 
562
 
 
563
static void
 
564
cff_index_fini (cairo_array_t *index)
 
565
{
 
566
    cff_index_element_t *element;
 
567
    unsigned int i;
 
568
 
 
569
    for (i = 0; i < _cairo_array_num_elements (index); i++) {
 
570
        element = _cairo_array_index (index, i);
 
571
        if (element->is_copy && element->data)
 
572
            free (element->data);
 
573
    }
 
574
    _cairo_array_fini (index);
 
575
}
 
576
 
 
577
static cairo_bool_t
 
578
_cairo_cff_dict_equal (const void *key_a, const void *key_b)
 
579
{
 
580
    const cff_dict_operator_t *op_a = key_a;
 
581
    const cff_dict_operator_t *op_b = key_b;
 
582
 
 
583
    return op_a->operator == op_b->operator;
 
584
}
 
585
 
 
586
static cairo_status_t
 
587
cff_dict_init (cairo_hash_table_t **dict)
 
588
{
 
589
    *dict = _cairo_hash_table_create (_cairo_cff_dict_equal);
 
590
    if (unlikely (*dict == NULL))
 
591
        return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
592
 
 
593
    return CAIRO_STATUS_SUCCESS;
 
594
}
 
595
 
 
596
static void
 
597
_cairo_dict_init_key (cff_dict_operator_t *key, int operator)
 
598
{
 
599
    key->base.hash = (unsigned long) operator;
 
600
    key->operator = operator;
 
601
}
 
602
 
 
603
static cairo_status_t
 
604
cff_dict_create_operator (int            operator,
 
605
                          unsigned char *operand,
 
606
                          int            size,
 
607
                          cff_dict_operator_t **out)
 
608
{
 
609
    cff_dict_operator_t *op;
 
610
 
 
611
    op = malloc (sizeof (cff_dict_operator_t));
 
612
    if (unlikely (op == NULL))
 
613
        return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
614
 
 
615
    _cairo_dict_init_key (op, operator);
 
616
    op->operand = malloc (size);
 
617
    if (unlikely (op->operand == NULL)) {
 
618
        free (op);
 
619
        return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
620
    }
 
621
 
 
622
    memcpy (op->operand, operand, size);
 
623
    op->operand_length = size;
 
624
    op->operand_offset = -1;
 
625
 
 
626
    *out = op;
 
627
    return CAIRO_STATUS_SUCCESS;
 
628
}
 
629
 
 
630
static cairo_status_t
 
631
cff_dict_read (cairo_hash_table_t *dict, unsigned char *p, int dict_size)
 
632
{
 
633
    unsigned char *end;
 
634
    cairo_array_t operands;
 
635
    cff_dict_operator_t *op;
 
636
    unsigned short operator;
 
637
    cairo_status_t status = CAIRO_STATUS_SUCCESS;
 
638
    int size;
 
639
 
 
640
    end = p + dict_size;
 
641
    _cairo_array_init (&operands, 1);
 
642
    while (p < end) {
 
643
        size = operand_length (p);
 
644
        if (size != 0) {
 
645
            status = _cairo_array_append_multiple (&operands, p, size);
 
646
            if (unlikely (status))
 
647
                goto fail;
 
648
 
 
649
            p += size;
 
650
        } else {
 
651
            p = decode_operator (p, &operator);
 
652
            status = cff_dict_create_operator (operator,
 
653
                                          _cairo_array_index (&operands, 0),
 
654
                                          _cairo_array_num_elements (&operands),
 
655
                                          &op);
 
656
            if (unlikely (status))
 
657
                goto fail;
 
658
 
 
659
            status = _cairo_hash_table_insert (dict, &op->base);
 
660
            if (unlikely (status))
 
661
                goto fail;
 
662
 
 
663
            _cairo_array_truncate (&operands, 0);
 
664
        }
 
665
    }
 
666
 
 
667
fail:
 
668
    _cairo_array_fini (&operands);
 
669
 
 
670
    return status;
 
671
}
 
672
 
 
673
static void
 
674
cff_dict_remove (cairo_hash_table_t *dict, unsigned short operator)
 
675
{
 
676
    cff_dict_operator_t key, *op;
 
677
 
 
678
    _cairo_dict_init_key (&key, operator);
 
679
    op = _cairo_hash_table_lookup (dict, &key.base);
 
680
    if (op != NULL) {
 
681
        free (op->operand);
 
682
        _cairo_hash_table_remove (dict, (cairo_hash_entry_t *) op);
 
683
        free (op);
 
684
    }
 
685
}
 
686
 
 
687
static unsigned char *
 
688
cff_dict_get_operands (cairo_hash_table_t *dict,
 
689
                       unsigned short      operator,
 
690
                       int                *size)
 
691
{
 
692
    cff_dict_operator_t key, *op;
 
693
 
 
694
    _cairo_dict_init_key (&key, operator);
 
695
    op = _cairo_hash_table_lookup (dict, &key.base);
 
696
    if (op != NULL) {
 
697
        *size = op->operand_length;
 
698
        return op->operand;
 
699
    }
 
700
 
 
701
    return NULL;
 
702
}
 
703
 
 
704
static cairo_status_t
 
705
cff_dict_set_operands (cairo_hash_table_t *dict,
 
706
                       unsigned short      operator,
 
707
                       unsigned char      *operand,
 
708
                       int                 size)
 
709
{
 
710
    cff_dict_operator_t key, *op;
 
711
    cairo_status_t status;
 
712
 
 
713
    _cairo_dict_init_key (&key, operator);
 
714
    op = _cairo_hash_table_lookup (dict, &key.base);
 
715
    if (op != NULL) {
 
716
        free (op->operand);
 
717
        op->operand = malloc (size);
 
718
        if (unlikely (op->operand == NULL))
 
719
            return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
720
 
 
721
        memcpy (op->operand, operand, size);
 
722
        op->operand_length = size;
 
723
    }
 
724
    else
 
725
    {
 
726
        status = cff_dict_create_operator (operator, operand, size, &op);
 
727
        if (unlikely (status))
 
728
            return status;
 
729
 
 
730
        status = _cairo_hash_table_insert (dict, &op->base);
 
731
        if (unlikely (status))
 
732
            return status;
 
733
    }
 
734
 
 
735
    return CAIRO_STATUS_SUCCESS;
 
736
}
 
737
 
 
738
static int
 
739
cff_dict_get_location (cairo_hash_table_t *dict,
 
740
                       unsigned short      operator,
 
741
                       int                *size)
 
742
{
 
743
    cff_dict_operator_t key, *op;
 
744
 
 
745
    _cairo_dict_init_key (&key, operator);
 
746
    op = _cairo_hash_table_lookup (dict, &key.base);
 
747
    if (op != NULL) {
 
748
        *size = op->operand_length;
 
749
        return op->operand_offset;
 
750
    }
 
751
 
 
752
    return -1;
 
753
}
 
754
 
 
755
typedef struct _dict_write_info {
 
756
    cairo_array_t *output;
 
757
    cairo_status_t status;
 
758
} dict_write_info_t;
 
759
 
 
760
static void
 
761
cairo_dict_write_operator (cff_dict_operator_t *op, dict_write_info_t *write_info)
 
762
{
 
763
    unsigned char data;
 
764
 
 
765
    op->operand_offset = _cairo_array_num_elements (write_info->output);
 
766
    write_info->status = _cairo_array_append_multiple (write_info->output, op->operand, op->operand_length);
 
767
    if (write_info->status)
 
768
        return;
 
769
 
 
770
    if (op->operator & 0xff00) {
 
771
        data = op->operator >> 8;
 
772
        write_info->status = _cairo_array_append (write_info->output, &data);
 
773
        if (write_info->status)
 
774
            return;
 
775
    }
 
776
    data = op->operator & 0xff;
 
777
    write_info->status = _cairo_array_append (write_info->output, &data);
 
778
}
 
779
 
 
780
static void
 
781
_cairo_dict_collect (void *entry, void *closure)
 
782
{
 
783
    dict_write_info_t   *write_info = closure;
 
784
    cff_dict_operator_t *op = entry;
 
785
 
 
786
    if (write_info->status)
 
787
        return;
 
788
 
 
789
    /* The ROS operator is handled separately in cff_dict_write() */
 
790
    if (op->operator != ROS_OP)
 
791
        cairo_dict_write_operator (op, write_info);
 
792
}
 
793
 
 
794
static cairo_status_t
 
795
cff_dict_write (cairo_hash_table_t *dict, cairo_array_t *output)
 
796
{
 
797
    dict_write_info_t write_info;
 
798
    cff_dict_operator_t key, *op;
 
799
 
 
800
    write_info.output = output;
 
801
    write_info.status = CAIRO_STATUS_SUCCESS;
 
802
 
 
803
    /* The CFF specification requires that the Top Dict of CID fonts
 
804
     * begin with the ROS operator. */
 
805
    _cairo_dict_init_key (&key, ROS_OP);
 
806
    op = _cairo_hash_table_lookup (dict, &key.base);
 
807
    if (op != NULL)
 
808
        cairo_dict_write_operator (op, &write_info);
 
809
 
 
810
    _cairo_hash_table_foreach (dict, _cairo_dict_collect, &write_info);
 
811
 
 
812
    return write_info.status;
 
813
}
 
814
 
 
815
static void
 
816
_cff_dict_entry_pluck (void *_entry, void *dict)
 
817
{
 
818
    cff_dict_operator_t *entry = _entry;
 
819
 
 
820
    _cairo_hash_table_remove (dict, &entry->base);
 
821
    free (entry->operand);
 
822
    free (entry);
 
823
}
 
824
 
 
825
static void
 
826
cff_dict_fini (cairo_hash_table_t *dict)
 
827
{
 
828
    _cairo_hash_table_foreach (dict, _cff_dict_entry_pluck, dict);
 
829
    _cairo_hash_table_destroy (dict);
 
830
}
 
831
 
 
832
static cairo_int_status_t
 
833
cairo_cff_font_read_header (cairo_cff_font_t *font)
 
834
{
 
835
    if (font->data_length < sizeof (cff_header_t))
 
836
        return CAIRO_INT_STATUS_UNSUPPORTED;
 
837
 
 
838
 
 
839
    font->header = (cff_header_t *) font->data;
 
840
    font->current_ptr = font->data + font->header->header_size;
 
841
 
 
842
    return CAIRO_STATUS_SUCCESS;
 
843
}
 
844
 
 
845
static cairo_int_status_t
 
846
cairo_cff_font_read_name (cairo_cff_font_t *font)
 
847
{
 
848
    cairo_array_t index;
 
849
    cairo_int_status_t status;
 
850
    cff_index_element_t *element;
 
851
    unsigned char *p;
 
852
    int i, len;
 
853
 
 
854
    cff_index_init (&index);
 
855
    status = cff_index_read (&index, &font->current_ptr, font->data_end);
 
856
    if (!font->is_opentype) {
 
857
        element = _cairo_array_index (&index, 0);
 
858
        p = element->data;
 
859
        len = element->length;
 
860
 
 
861
        /* If font name is prefixed with a subset tag, strip it off. */
 
862
        if (len > 7 && p[6] == '+') {
 
863
            for (i = 0; i < 6; i++)
 
864
                if (p[i] < 'A' || p[i] > 'Z')
 
865
                    break;
 
866
            if (i == 6) {
 
867
                p += 7;
 
868
                len -= 7;
 
869
            }
 
870
        }
 
871
        font->ps_name = malloc (len + 1);
 
872
        if (unlikely (font->ps_name == NULL))
 
873
            return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
874
 
 
875
        memcpy (font->ps_name, p, len);
 
876
        font->ps_name[len] = 0;
 
877
    }
 
878
    cff_index_fini (&index);
 
879
 
 
880
    return status;
 
881
}
 
882
 
 
883
static cairo_int_status_t
 
884
cairo_cff_font_read_private_dict (cairo_cff_font_t   *font,
 
885
                                  cairo_hash_table_t *private_dict,
 
886
                                  cairo_array_t      *local_sub_index,
 
887
                                  int                *local_sub_bias,
 
888
                                  cairo_bool_t      **local_subs_used,
 
889
                                  int                *default_width,
 
890
                                  int                *nominal_width,
 
891
                                  unsigned char      *ptr,
 
892
                                  int                 size)
 
893
{
 
894
    cairo_int_status_t status;
 
895
    unsigned char buf[10];
 
896
    unsigned char *end_buf;
 
897
    int offset;
 
898
    int i;
 
899
    unsigned char *operand;
 
900
    unsigned char *p;
 
901
    int num_subs;
 
902
 
 
903
    status = cff_dict_read (private_dict, ptr, size);
 
904
    if (unlikely (status))
 
905
        return status;
 
906
 
 
907
    operand = cff_dict_get_operands (private_dict, LOCAL_SUB_OP, &i);
 
908
    if (operand) {
 
909
        decode_integer (operand, &offset);
 
910
        p = ptr + offset;
 
911
        status = cff_index_read (local_sub_index, &p, font->data_end);
 
912
        if (unlikely (status))
 
913
            return status;
 
914
 
 
915
        /* Use maximum sized encoding to reserve space for later modification. */
 
916
        end_buf = encode_integer_max (buf, 0);
 
917
        status = cff_dict_set_operands (private_dict, LOCAL_SUB_OP, buf, end_buf - buf);
 
918
        if (unlikely (status))
 
919
            return status;
 
920
    }
 
921
 
 
922
    *default_width = 0;
 
923
    operand = cff_dict_get_operands (private_dict, DEFAULTWIDTH_OP, &i);
 
924
    if (operand)
 
925
        decode_integer (operand, default_width);
 
926
 
 
927
    *nominal_width = 0;
 
928
    operand = cff_dict_get_operands (private_dict, NOMINALWIDTH_OP, &i);
 
929
    if (operand)
 
930
        decode_integer (operand, nominal_width);
 
931
 
 
932
    num_subs = _cairo_array_num_elements (local_sub_index);
 
933
    *local_subs_used = calloc (num_subs, sizeof (cairo_bool_t));
 
934
    if (unlikely (*local_subs_used == NULL))
 
935
        return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
936
 
 
937
    if (num_subs < 1240)
 
938
        *local_sub_bias = 107;
 
939
    else if (num_subs < 33900)
 
940
        *local_sub_bias = 1131;
 
941
    else
 
942
        *local_sub_bias = 32768;
 
943
 
 
944
    return CAIRO_STATUS_SUCCESS;
 
945
}
 
946
 
 
947
static cairo_int_status_t
 
948
cairo_cff_font_read_fdselect (cairo_cff_font_t *font, unsigned char *p)
 
949
{
 
950
    int type, num_ranges, first, last, fd, i, j;
 
951
 
 
952
    font->fdselect = calloc (font->num_glyphs, sizeof (int));
 
953
    if (unlikely (font->fdselect == NULL))
 
954
        return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
955
 
 
956
    type = *p++;
 
957
    if (type == 0)
 
958
    {
 
959
        for (i = 0; i < font->num_glyphs; i++)
 
960
            font->fdselect[i] = *p++;
 
961
    } else if (type == 3) {
 
962
        num_ranges = be16_to_cpu( *((uint16_t *)p) );
 
963
        p += 2;
 
964
        for  (i = 0; i < num_ranges; i++)
 
965
        {
 
966
            first = be16_to_cpu( *((uint16_t *)p) );
 
967
            p += 2;
 
968
            fd = *p++;
 
969
            last = be16_to_cpu( *((uint16_t *)p) );
 
970
            for (j = first; j < last; j++)
 
971
                font->fdselect[j] = fd;
 
972
        }
 
973
    } else {
 
974
        return CAIRO_INT_STATUS_UNSUPPORTED;
 
975
    }
 
976
 
 
977
    return CAIRO_STATUS_SUCCESS;
 
978
}
 
979
 
 
980
static cairo_int_status_t
 
981
cairo_cff_font_read_cid_fontdict (cairo_cff_font_t *font, unsigned char *ptr)
 
982
{
 
983
    cairo_array_t index;
 
984
    cff_index_element_t *element;
 
985
    unsigned int i;
 
986
    int size;
 
987
    unsigned char *operand;
 
988
    int offset;
 
989
    cairo_int_status_t status;
 
990
    unsigned char buf[100];
 
991
    unsigned char *end_buf;
 
992
 
 
993
    cff_index_init (&index);
 
994
    status = cff_index_read (&index, &ptr, font->data_end);
 
995
    if (unlikely (status))
 
996
        goto fail;
 
997
 
 
998
    font->num_fontdicts = _cairo_array_num_elements (&index);
 
999
 
 
1000
    font->fd_dict = calloc (sizeof (cairo_hash_table_t *), font->num_fontdicts);
 
1001
    if (unlikely (font->fd_dict == NULL)) {
 
1002
        status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
1003
        goto fail;
 
1004
    }
 
1005
 
 
1006
    font->fd_private_dict = calloc (sizeof (cairo_hash_table_t *), font->num_fontdicts);
 
1007
    if (unlikely (font->fd_private_dict == NULL)) {
 
1008
        status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
1009
        goto fail;
 
1010
    }
 
1011
 
 
1012
    font->fd_local_sub_index = calloc (sizeof (cairo_array_t), font->num_fontdicts);
 
1013
    if (unlikely (font->fd_local_sub_index == NULL)) {
 
1014
        status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
1015
        goto fail;
 
1016
    }
 
1017
 
 
1018
    font->fd_local_sub_bias = calloc (sizeof (int), font->num_fontdicts);
 
1019
    if (unlikely (font->fd_local_sub_bias == NULL)) {
 
1020
        status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
1021
        goto fail;
 
1022
    }
 
1023
 
 
1024
    font->fd_local_subs_used = calloc (sizeof (cairo_bool_t *), font->num_fontdicts);
 
1025
    if (unlikely (font->fd_local_subs_used == NULL)) {
 
1026
        status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
1027
        goto fail;
 
1028
    }
 
1029
 
 
1030
    font->fd_default_width = calloc (sizeof (int), font->num_fontdicts);
 
1031
    if (unlikely (font->fd_default_width == NULL)) {
 
1032
        status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
1033
        goto fail;
 
1034
    }
 
1035
 
 
1036
    font->fd_nominal_width = calloc (sizeof (int), font->num_fontdicts);
 
1037
    if (unlikely (font->fd_nominal_width == NULL)) {
 
1038
        status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
1039
        goto fail;
 
1040
    }
 
1041
 
 
1042
    for (i = 0; i < font->num_fontdicts; i++) {
 
1043
        status = cff_dict_init (&font->fd_dict[i]);
 
1044
        if (unlikely (status))
 
1045
            goto fail;
 
1046
 
 
1047
        element = _cairo_array_index (&index, i);
 
1048
        status = cff_dict_read (font->fd_dict[i], element->data, element->length);
 
1049
        if (unlikely (status))
 
1050
            goto fail;
 
1051
 
 
1052
        operand = cff_dict_get_operands (font->fd_dict[i], PRIVATE_OP, &size);
 
1053
        if (operand == NULL) {
 
1054
            status = CAIRO_INT_STATUS_UNSUPPORTED;
 
1055
            goto fail;
 
1056
        }
 
1057
        operand = decode_integer (operand, &size);
 
1058
        decode_integer (operand, &offset);
 
1059
        status = cff_dict_init (&font->fd_private_dict[i]);
 
1060
        if (unlikely (status))
 
1061
            goto fail;
 
1062
 
 
1063
        cff_index_init (&font->fd_local_sub_index[i]);
 
1064
        status = cairo_cff_font_read_private_dict (font,
 
1065
                                                   font->fd_private_dict[i],
 
1066
                                                   &font->fd_local_sub_index[i],
 
1067
                                                   &font->fd_local_sub_bias[i],
 
1068
                                                   &font->fd_local_subs_used[i],
 
1069
                                                   &font->fd_default_width[i],
 
1070
                                                   &font->fd_nominal_width[i],
 
1071
                                                   font->data + offset,
 
1072
                                                   size);
 
1073
        if (unlikely (status))
 
1074
            goto fail;
 
1075
 
 
1076
        /* Set integer operand to max value to use max size encoding to reserve
 
1077
         * space for any value later */
 
1078
        end_buf = encode_integer_max (buf, 0);
 
1079
        end_buf = encode_integer_max (end_buf, 0);
 
1080
        status = cff_dict_set_operands (font->fd_dict[i], PRIVATE_OP, buf, end_buf - buf);
 
1081
        if (unlikely (status))
 
1082
            goto fail;
 
1083
    }
 
1084
 
 
1085
    return CAIRO_STATUS_SUCCESS;
 
1086
 
 
1087
fail:
 
1088
    cff_index_fini (&index);
 
1089
 
 
1090
    return status;
 
1091
}
 
1092
 
 
1093
static void
 
1094
cairo_cff_font_read_font_metrics (cairo_cff_font_t *font, cairo_hash_table_t  *top_dict)
 
1095
{
 
1096
    unsigned char *p;
 
1097
    unsigned char *end;
 
1098
    int size;
 
1099
    double x_min, y_min, x_max, y_max;
 
1100
    double xx, yx, xy, yy;
 
1101
 
 
1102
    x_min = 0.0;
 
1103
    y_min = 0.0;
 
1104
    x_max = 0.0;
 
1105
    y_max = 0.0;
 
1106
    p = cff_dict_get_operands (font->top_dict, FONTBBOX_OP, &size);
 
1107
    if (p) {
 
1108
        end = p + size;
 
1109
        if (p < end)
 
1110
            p = decode_number (p, &x_min);
 
1111
        if (p < end)
 
1112
            p = decode_number (p, &y_min);
 
1113
        if (p < end)
 
1114
            p = decode_number (p, &x_max);
 
1115
        if (p < end)
 
1116
            p = decode_number (p, &y_max);
 
1117
    }
 
1118
    font->x_min = floor (x_min);
 
1119
    font->y_min = floor (y_min);
 
1120
    font->x_max = floor (x_max);
 
1121
    font->y_max = floor (y_max);
 
1122
    font->ascent = font->y_max;
 
1123
    font->descent = font->y_min;
 
1124
 
 
1125
    xx = 0.001;
 
1126
    yx = 0.0;
 
1127
    xy = 0.0;
 
1128
    yy = 0.001;
 
1129
    p = cff_dict_get_operands (font->top_dict, FONTMATRIX_OP, &size);
 
1130
    if (p) {
 
1131
        end = p + size;
 
1132
        if (p < end)
 
1133
            p = decode_number (p, &xx);
 
1134
        if (p < end)
 
1135
            p = decode_number (p, &yx);
 
1136
        if (p < end)
 
1137
            p = decode_number (p, &xy);
 
1138
        if (p < end)
 
1139
            p = decode_number (p, &yy);
 
1140
    }
 
1141
    /* Freetype uses 1/yy to get units per EM */
 
1142
    font->units_per_em = _cairo_round(1.0/yy);
 
1143
}
 
1144
 
 
1145
static cairo_int_status_t
 
1146
cairo_cff_font_read_top_dict (cairo_cff_font_t *font)
 
1147
{
 
1148
    cairo_array_t index;
 
1149
    cff_index_element_t *element;
 
1150
    unsigned char buf[20];
 
1151
    unsigned char *end_buf;
 
1152
    unsigned char *operand;
 
1153
    cairo_int_status_t status;
 
1154
    unsigned char *p;
 
1155
    int size;
 
1156
    int offset;
 
1157
 
 
1158
    cff_index_init (&index);
 
1159
    status = cff_index_read (&index, &font->current_ptr, font->data_end);
 
1160
    if (unlikely (status))
 
1161
        goto fail;
 
1162
 
 
1163
    element = _cairo_array_index (&index, 0);
 
1164
    status = cff_dict_read (font->top_dict, element->data, element->length);
 
1165
    if (unlikely (status))
 
1166
        goto fail;
 
1167
 
 
1168
    if (cff_dict_get_operands (font->top_dict, ROS_OP, &size) != NULL)
 
1169
        font->is_cid = TRUE;
 
1170
    else
 
1171
        font->is_cid = FALSE;
 
1172
 
 
1173
    operand = cff_dict_get_operands (font->top_dict, CHARSTRINGS_OP, &size);
 
1174
    decode_integer (operand, &offset);
 
1175
    p = font->data + offset;
 
1176
    status = cff_index_read (&font->charstrings_index, &p, font->data_end);
 
1177
    if (unlikely (status))
 
1178
        goto fail;
 
1179
    font->num_glyphs = _cairo_array_num_elements (&font->charstrings_index);
 
1180
 
 
1181
    operand = cff_dict_get_operands (font->top_dict, CHARSET_OP, &size);
 
1182
    if (font->is_cid && !operand)
 
1183
        return CAIRO_INT_STATUS_UNSUPPORTED;
 
1184
 
 
1185
    decode_integer (operand, &offset);
 
1186
    font->charset = font->data + offset;
 
1187
    if (font->charset >= font->data_end)
 
1188
        return CAIRO_INT_STATUS_UNSUPPORTED;
 
1189
 
 
1190
    if (!font->is_opentype)
 
1191
        cairo_cff_font_read_font_metrics (font, font->top_dict);
 
1192
 
 
1193
    if (font->is_cid) {
 
1194
        operand = cff_dict_get_operands (font->top_dict, FDSELECT_OP, &size);
 
1195
        decode_integer (operand, &offset);
 
1196
        status = cairo_cff_font_read_fdselect (font, font->data + offset);
 
1197
        if (unlikely (status))
 
1198
            goto fail;
 
1199
 
 
1200
        operand = cff_dict_get_operands (font->top_dict, FDARRAY_OP, &size);
 
1201
        decode_integer (operand, &offset);
 
1202
        status = cairo_cff_font_read_cid_fontdict (font, font->data + offset);
 
1203
        if (unlikely (status))
 
1204
            goto fail;
 
1205
    } else {
 
1206
        operand = cff_dict_get_operands (font->top_dict, PRIVATE_OP, &size);
 
1207
        operand = decode_integer (operand, &size);
 
1208
        decode_integer (operand, &offset);
 
1209
        status = cairo_cff_font_read_private_dict (font,
 
1210
                                                   font->private_dict,
 
1211
                                                   &font->local_sub_index,
 
1212
                                                   &font->local_sub_bias,
 
1213
                                                   &font->local_subs_used,
 
1214
                                                   &font->default_width,
 
1215
                                                   &font->nominal_width,
 
1216
                                                   font->data + offset,
 
1217
                                                   size);
 
1218
        if (unlikely (status))
 
1219
            goto fail;
 
1220
    }
 
1221
 
 
1222
    /* Use maximum sized encoding to reserve space for later modification. */
 
1223
    end_buf = encode_integer_max (buf, 0);
 
1224
    status = cff_dict_set_operands (font->top_dict,
 
1225
                                    CHARSTRINGS_OP, buf, end_buf - buf);
 
1226
    if (unlikely (status))
 
1227
        goto fail;
 
1228
 
 
1229
    status = cff_dict_set_operands (font->top_dict,
 
1230
                                    CHARSET_OP, buf, end_buf - buf);
 
1231
    if (unlikely (status))
 
1232
        goto fail;
 
1233
 
 
1234
    if (font->scaled_font_subset->is_latin) {
 
1235
        status = cff_dict_set_operands (font->top_dict,
 
1236
                                        ENCODING_OP, buf, end_buf - buf);
 
1237
        if (unlikely (status))
 
1238
            goto fail;
 
1239
 
 
1240
        /* Private has two operands - size and offset */
 
1241
        end_buf = encode_integer_max (end_buf, 0);
 
1242
        cff_dict_set_operands (font->top_dict, PRIVATE_OP, buf, end_buf - buf);
 
1243
        if (unlikely (status))
 
1244
            goto fail;
 
1245
 
 
1246
    } else {
 
1247
        status = cff_dict_set_operands (font->top_dict,
 
1248
                                        FDSELECT_OP, buf, end_buf - buf);
 
1249
        if (unlikely (status))
 
1250
            goto fail;
 
1251
 
 
1252
        status = cff_dict_set_operands (font->top_dict,
 
1253
                                        FDARRAY_OP, buf, end_buf - buf);
 
1254
        if (unlikely (status))
 
1255
            goto fail;
 
1256
 
 
1257
        cff_dict_remove (font->top_dict, ENCODING_OP);
 
1258
        cff_dict_remove (font->top_dict, PRIVATE_OP);
 
1259
    }
 
1260
 
 
1261
    /* Remove the unique identifier operators as the subsetted font is
 
1262
     * not the same is the original font. */
 
1263
    cff_dict_remove (font->top_dict, UNIQUEID_OP);
 
1264
    cff_dict_remove (font->top_dict, XUID_OP);
 
1265
 
 
1266
fail:
 
1267
    cff_index_fini (&index);
 
1268
 
 
1269
    return status;
 
1270
}
 
1271
 
 
1272
static cairo_int_status_t
 
1273
cairo_cff_font_read_strings (cairo_cff_font_t *font)
 
1274
{
 
1275
    return cff_index_read (&font->strings_index, &font->current_ptr, font->data_end);
 
1276
}
 
1277
 
 
1278
static cairo_int_status_t
 
1279
cairo_cff_font_read_global_subroutines (cairo_cff_font_t *font)
 
1280
{
 
1281
    cairo_int_status_t status;
 
1282
    int num_subs;
 
1283
 
 
1284
    status = cff_index_read (&font->global_sub_index, &font->current_ptr, font->data_end);
 
1285
    if (unlikely (status))
 
1286
        return status;
 
1287
 
 
1288
    num_subs = _cairo_array_num_elements (&font->global_sub_index);
 
1289
    font->global_subs_used = calloc (num_subs, sizeof(cairo_bool_t));
 
1290
    if (unlikely (font->global_subs_used == NULL))
 
1291
        return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
1292
 
 
1293
    if (num_subs < 1240)
 
1294
        font->global_sub_bias = 107;
 
1295
    else if (num_subs < 33900)
 
1296
        font->global_sub_bias = 1131;
 
1297
    else
 
1298
        font->global_sub_bias = 32768;
 
1299
 
 
1300
    return CAIRO_STATUS_SUCCESS;
 
1301
}
 
1302
 
 
1303
typedef cairo_int_status_t
 
1304
(*font_read_t) (cairo_cff_font_t *font);
 
1305
 
 
1306
static const font_read_t font_read_funcs[] = {
 
1307
    cairo_cff_font_read_header,
 
1308
    cairo_cff_font_read_name,
 
1309
    cairo_cff_font_read_top_dict,
 
1310
    cairo_cff_font_read_strings,
 
1311
    cairo_cff_font_read_global_subroutines,
 
1312
};
 
1313
 
 
1314
static cairo_int_status_t
 
1315
cairo_cff_font_read_font (cairo_cff_font_t *font)
 
1316
{
 
1317
    cairo_int_status_t status;
 
1318
    unsigned int i;
 
1319
 
 
1320
    for (i = 0; i < ARRAY_LENGTH (font_read_funcs); i++) {
 
1321
        status = font_read_funcs[i] (font);
 
1322
        if (unlikely (status))
 
1323
            return status;
 
1324
    }
 
1325
 
 
1326
    return CAIRO_STATUS_SUCCESS;
 
1327
}
 
1328
 
 
1329
static cairo_status_t
 
1330
cairo_cff_font_set_ros_strings (cairo_cff_font_t *font)
 
1331
{
 
1332
    cairo_status_t status;
 
1333
    unsigned char buf[30];
 
1334
    unsigned char *p;
 
1335
    int sid1, sid2;
 
1336
    const char *registry = "Adobe";
 
1337
    const char *ordering = "Identity";
 
1338
 
 
1339
    sid1 = NUM_STD_STRINGS + _cairo_array_num_elements (&font->strings_subset_index);
 
1340
    status = cff_index_append_copy (&font->strings_subset_index,
 
1341
                                    (unsigned char *)registry,
 
1342
                                    strlen(registry));
 
1343
    if (unlikely (status))
 
1344
        return status;
 
1345
 
 
1346
    sid2 = NUM_STD_STRINGS + _cairo_array_num_elements (&font->strings_subset_index);
 
1347
    status = cff_index_append_copy (&font->strings_subset_index,
 
1348
                                    (unsigned char *)ordering,
 
1349
                                    strlen(ordering));
 
1350
    if (unlikely (status))
 
1351
        return status;
 
1352
 
 
1353
    p = encode_integer (buf, sid1);
 
1354
    p = encode_integer (p, sid2);
 
1355
    p = encode_integer (p, 0);
 
1356
    status = cff_dict_set_operands (font->top_dict, ROS_OP, buf, p - buf);
 
1357
    if (unlikely (status))
 
1358
        return status;
 
1359
 
 
1360
    p = encode_integer (buf, font->scaled_font_subset->num_glyphs);
 
1361
    status = cff_dict_set_operands (font->top_dict, CIDCOUNT_OP, buf, p - buf);
 
1362
    if (unlikely (status))
 
1363
        return status;
 
1364
 
 
1365
    return CAIRO_STATUS_SUCCESS;
 
1366
}
 
1367
 
 
1368
static cairo_status_t
 
1369
cairo_cff_font_subset_dict_string(cairo_cff_font_t   *font,
 
1370
                                  cairo_hash_table_t *dict,
 
1371
                                  int                 operator)
 
1372
{
 
1373
    int size;
 
1374
    unsigned char *p;
 
1375
    int sid;
 
1376
    unsigned char buf[100];
 
1377
    cff_index_element_t *element;
 
1378
    cairo_status_t status;
 
1379
 
 
1380
    p = cff_dict_get_operands (dict, operator, &size);
 
1381
    if (!p)
 
1382
        return CAIRO_STATUS_SUCCESS;
 
1383
 
 
1384
    decode_integer (p, &sid);
 
1385
    if (sid < NUM_STD_STRINGS)
 
1386
        return CAIRO_STATUS_SUCCESS;
 
1387
 
 
1388
    element = _cairo_array_index (&font->strings_index, sid - NUM_STD_STRINGS);
 
1389
    sid = NUM_STD_STRINGS + _cairo_array_num_elements (&font->strings_subset_index);
 
1390
    status = cff_index_append (&font->strings_subset_index, element->data, element->length);
 
1391
    if (unlikely (status))
 
1392
        return status;
 
1393
 
 
1394
    p = encode_integer (buf, sid);
 
1395
    status = cff_dict_set_operands (dict, operator, buf, p - buf);
 
1396
    if (unlikely (status))
 
1397
        return status;
 
1398
 
 
1399
    return CAIRO_STATUS_SUCCESS;
 
1400
}
 
1401
 
 
1402
static const int dict_strings[] = {
 
1403
    VERSION_OP,
 
1404
    NOTICE_OP,
 
1405
    COPYRIGHT_OP,
 
1406
    FULLNAME_OP,
 
1407
    FAMILYNAME_OP,
 
1408
    WEIGHT_OP,
 
1409
    POSTSCRIPT_OP,
 
1410
    BASEFONTNAME_OP,
 
1411
    FONTNAME_OP,
 
1412
};
 
1413
 
 
1414
static cairo_status_t
 
1415
cairo_cff_font_subset_dict_strings (cairo_cff_font_t   *font,
 
1416
                                    cairo_hash_table_t *dict)
 
1417
{
 
1418
    cairo_status_t status;
 
1419
    unsigned int i;
 
1420
 
 
1421
    for (i = 0; i < ARRAY_LENGTH (dict_strings); i++) {
 
1422
        status = cairo_cff_font_subset_dict_string (font, dict, dict_strings[i]);
 
1423
        if (unlikely (status))
 
1424
            return status;
 
1425
    }
 
1426
 
 
1427
    return CAIRO_STATUS_SUCCESS;
 
1428
}
 
1429
 
 
1430
static unsigned char *
 
1431
type2_decode_integer (unsigned char *p, int *integer)
 
1432
{
 
1433
    if (*p == 28) {
 
1434
        *integer = p[1] << 8 | p[2];
 
1435
        p += 3;
 
1436
    } else if (*p <= 246) {
 
1437
        *integer = *p++ - 139;
 
1438
    } else if (*p <= 250) {
 
1439
        *integer = (p[0] - 247) * 256 + p[1] + 108;
 
1440
        p += 2;
 
1441
    } else if (*p <= 254) {
 
1442
        *integer = -(p[0] - 251) * 256 - p[1] - 108;
 
1443
        p += 2;
 
1444
    } else { /* *p == 255 */
 
1445
    /* This actually a 16.16 fixed-point number however we are not interested in
 
1446
     * the value of fixed-point numbers. */
 
1447
        *integer = (p[1] << 24) | (p[2] << 16) | (p[3] << 8) | p[4];
 
1448
        p += 5;
 
1449
    }
 
1450
    return p;
 
1451
}
 
1452
 
 
1453
/* Type 2 charstring parser for finding calls to local or global
 
1454
 * subroutines. For non Opentype CFF fonts it also gets the glyph
 
1455
 * widths.
 
1456
 *
 
1457
 * When we find a subroutine operator, the subroutine is marked as in
 
1458
 * use and recursively followed. The subroutine number is the value on
 
1459
 * the top of the stack when the subroutine operator is executed. In
 
1460
 * most fonts the subroutine number is encoded in an integer
 
1461
 * immediately preceding the subroutine operator. However it is
 
1462
 * possible for the subroutine number on the stack to be the result of
 
1463
 * a computation (in which case there will be an operator preceding
 
1464
 * the subroutine operator). If this occurs, subroutine subsetting is
 
1465
 * disabled since we can't easily determine which subroutines are
 
1466
 * used.
 
1467
 *
 
1468
 * The width, if present, is the first integer in the charstring. The
 
1469
 * only way to confirm if the integer at the start of the charstring is
 
1470
 * the width is when the first stack clearing operator is parsed,
 
1471
 * check if there is an extra integer left over on the stack.
 
1472
 *
 
1473
 * When the first stack clearing operator is encountered
 
1474
 * type2_find_width is set to FALSE and type2_found_width is set to
 
1475
 * TRUE if an extra argument is found, otherwise FALSE.
 
1476
 */
 
1477
static cairo_status_t
 
1478
cairo_cff_parse_charstring (cairo_cff_font_t *font,
 
1479
                            unsigned char *charstring, int length,
 
1480
                            int glyph_id,
 
1481
                            cairo_bool_t need_width)
 
1482
{
 
1483
    unsigned char *p = charstring;
 
1484
    unsigned char *end = charstring + length;
 
1485
    int integer;
 
1486
    int hint_bytes;
 
1487
    int sub_num;
 
1488
    cff_index_element_t *element;
 
1489
    int fd;
 
1490
 
 
1491
    while (p < end) {
 
1492
        if (*p == 28 || *p >= 32) {
 
1493
            /* Integer value */
 
1494
            p = type2_decode_integer (p, &integer);
 
1495
            font->type2_stack_size++;
 
1496
            font->type2_stack_top_value = integer;
 
1497
            font->type2_stack_top_is_int = TRUE;
 
1498
            if (!font->type2_seen_first_int) {
 
1499
                font->type2_width = integer;
 
1500
                font->type2_seen_first_int = TRUE;
 
1501
            }
 
1502
        } else if (*p == TYPE2_hstem || *p == TYPE2_vstem ||
 
1503
                   *p == TYPE2_hstemhm || *p == TYPE2_vstemhm) {
 
1504
            /* Hint operator. The number of hints declared by the
 
1505
             * operator depends on the size of the stack. */
 
1506
            font->type2_stack_top_is_int = FALSE;
 
1507
            font->type2_num_hints += font->type2_stack_size/2;
 
1508
            if (font->type2_find_width && font->type2_stack_size % 2)
 
1509
                font->type2_found_width = TRUE;
 
1510
 
 
1511
            font->type2_stack_size = 0;
 
1512
            font->type2_find_width = FALSE;
 
1513
            p++;
 
1514
        } else if (*p == TYPE2_hintmask || *p == TYPE2_cntrmask) {
 
1515
            /* Hintmask operator. These operators are followed by a
 
1516
             * variable length mask where the length depends on the
 
1517
             * number of hints declared. The first time this is called
 
1518
             * it is also an implicit vstem if there are arguments on
 
1519
             * the stack. */
 
1520
            if (font->type2_hintmask_bytes == 0) {
 
1521
                font->type2_stack_top_is_int = FALSE;
 
1522
                font->type2_num_hints += font->type2_stack_size/2;
 
1523
                if (font->type2_find_width && font->type2_stack_size % 2)
 
1524
                    font->type2_found_width = TRUE;
 
1525
 
 
1526
                font->type2_stack_size = 0;
 
1527
                font->type2_find_width = FALSE;
 
1528
                font->type2_hintmask_bytes = (font->type2_num_hints+7)/8;
 
1529
            }
 
1530
 
 
1531
            hint_bytes = font->type2_hintmask_bytes;
 
1532
            p++;
 
1533
            p += hint_bytes;
 
1534
        } else if (*p == TYPE2_rmoveto) {
 
1535
            if (font->type2_find_width && font->type2_stack_size > 2)
 
1536
                font->type2_found_width = TRUE;
 
1537
 
 
1538
            font->type2_stack_size = 0;
 
1539
            font->type2_find_width = FALSE;
 
1540
            font->type2_has_path = TRUE;
 
1541
            p++;
 
1542
        } else if (*p == TYPE2_hmoveto || *p == TYPE2_vmoveto) {
 
1543
            if (font->type2_find_width && font->type2_stack_size > 1)
 
1544
                font->type2_found_width = TRUE;
 
1545
 
 
1546
            font->type2_stack_size = 0;
 
1547
            font->type2_find_width = FALSE;
 
1548
            font->type2_has_path = TRUE;
 
1549
            p++;
 
1550
        } else if (*p == TYPE2_endchar) {
 
1551
            if (!font->type2_has_path && font->type2_stack_size > 3)
 
1552
                return CAIRO_INT_STATUS_UNSUPPORTED; /* seac (Ref Appendix C of Type 2 Charstring Format */
 
1553
 
 
1554
            if (font->type2_find_width && font->type2_stack_size > 0)
 
1555
                font->type2_found_width = TRUE;
 
1556
 
 
1557
            return CAIRO_STATUS_SUCCESS;
 
1558
        } else if (*p == TYPE2_callsubr) {
 
1559
            /* call to local subroutine */
 
1560
            if (! font->type2_stack_top_is_int)
 
1561
                return CAIRO_INT_STATUS_UNSUPPORTED;
 
1562
 
 
1563
            if (++font->type2_nesting_level > MAX_SUBROUTINE_NESTING)
 
1564
                return CAIRO_INT_STATUS_UNSUPPORTED;
 
1565
 
 
1566
            p++;
 
1567
            font->type2_stack_top_is_int = FALSE;
 
1568
            font->type2_stack_size--;
 
1569
            if (font->type2_find_width && font->type2_stack_size == 0)
 
1570
                font->type2_seen_first_int = FALSE;
 
1571
 
 
1572
            if (font->is_cid) {
 
1573
                fd = font->fdselect[glyph_id];
 
1574
                sub_num = font->type2_stack_top_value + font->fd_local_sub_bias[fd];
 
1575
                element = _cairo_array_index (&font->fd_local_sub_index[fd], sub_num);
 
1576
                if (! font->fd_local_subs_used[fd][sub_num]) {
 
1577
                    font->fd_local_subs_used[fd][sub_num] = TRUE;
 
1578
                    cairo_cff_parse_charstring (font, element->data, element->length, glyph_id, need_width);
 
1579
                }
 
1580
            } else {
 
1581
                sub_num = font->type2_stack_top_value + font->local_sub_bias;
 
1582
                element = _cairo_array_index (&font->local_sub_index, sub_num);
 
1583
                if (! font->local_subs_used[sub_num] ||
 
1584
                    (need_width && !font->type2_found_width))
 
1585
                {
 
1586
                    font->local_subs_used[sub_num] = TRUE;
 
1587
                    cairo_cff_parse_charstring (font, element->data, element->length, glyph_id, need_width);
 
1588
                }
 
1589
            }
 
1590
            font->type2_nesting_level--;
 
1591
        } else if (*p == TYPE2_callgsubr) {
 
1592
            /* call to global subroutine */
 
1593
            if (! font->type2_stack_top_is_int)
 
1594
                return CAIRO_INT_STATUS_UNSUPPORTED;
 
1595
 
 
1596
            if (++font->type2_nesting_level > MAX_SUBROUTINE_NESTING)
 
1597
                return CAIRO_INT_STATUS_UNSUPPORTED;
 
1598
 
 
1599
            p++;
 
1600
            font->type2_stack_size--;
 
1601
            font->type2_stack_top_is_int = FALSE;
 
1602
            if (font->type2_find_width && font->type2_stack_size == 0)
 
1603
                font->type2_seen_first_int = FALSE;
 
1604
 
 
1605
            sub_num = font->type2_stack_top_value + font->global_sub_bias;
 
1606
            element = _cairo_array_index (&font->global_sub_index, sub_num);
 
1607
            if (! font->global_subs_used[sub_num] ||
 
1608
                (need_width && !font->type2_found_width))
 
1609
            {
 
1610
                font->global_subs_used[sub_num] = TRUE;
 
1611
                cairo_cff_parse_charstring (font, element->data, element->length, glyph_id, need_width);
 
1612
            }
 
1613
            font->type2_nesting_level--;
 
1614
        } else if (*p == 12) {
 
1615
            /* 2 byte instruction */
 
1616
 
 
1617
            /* All the 2 byte operators are either not valid before a
 
1618
             * stack clearing operator or they are one of the
 
1619
             * arithmetic, storage, or conditional operators. */
 
1620
            if (need_width && font->type2_find_width)
 
1621
                return CAIRO_INT_STATUS_UNSUPPORTED;
 
1622
 
 
1623
            p += 2;
 
1624
            font->type2_stack_top_is_int = FALSE;
 
1625
        } else {
 
1626
            /* 1 byte instruction */
 
1627
            p++;
 
1628
            font->type2_stack_top_is_int = FALSE;
 
1629
        }
 
1630
    }
 
1631
 
 
1632
    return CAIRO_STATUS_SUCCESS;
 
1633
}
 
1634
 
 
1635
static cairo_status_t
 
1636
cairo_cff_find_width_and_subroutines_used (cairo_cff_font_t  *font,
 
1637
                                           unsigned char *charstring, int length,
 
1638
                                           int glyph_id, int subset_id)
 
1639
{
 
1640
    cairo_status_t status;
 
1641
    int width;
 
1642
    int fd;
 
1643
 
 
1644
    font->type2_stack_size = 0;
 
1645
    font->type2_stack_top_value = 0;;
 
1646
    font->type2_stack_top_is_int = FALSE;
 
1647
    font->type2_num_hints = 0;
 
1648
    font->type2_hintmask_bytes = 0;
 
1649
    font->type2_nesting_level = 0;
 
1650
    font->type2_seen_first_int = FALSE;
 
1651
    font->type2_find_width = TRUE;
 
1652
    font->type2_found_width = FALSE;
 
1653
    font->type2_width = 0;
 
1654
    font->type2_has_path = FALSE;
 
1655
 
 
1656
    status = cairo_cff_parse_charstring (font, charstring, length, glyph_id, TRUE);
 
1657
    if (status)
 
1658
        return status;
 
1659
 
 
1660
    if (!font->is_opentype) {
 
1661
        if (font->is_cid) {
 
1662
            fd = font->fdselect[glyph_id];
 
1663
            if (font->type2_found_width)
 
1664
                width = font->fd_nominal_width[fd] + font->type2_width;
 
1665
            else
 
1666
                width = font->fd_default_width[fd];
 
1667
        } else {
 
1668
            if (font->type2_found_width)
 
1669
                width = font->nominal_width + font->type2_width;
 
1670
            else
 
1671
                width = font->default_width;
 
1672
        }
 
1673
        font->widths[subset_id] = width;
 
1674
    }
 
1675
 
 
1676
    return CAIRO_STATUS_SUCCESS;
 
1677
}
 
1678
 
 
1679
static cairo_int_status_t
 
1680
cairo_cff_font_get_gid_for_cid (cairo_cff_font_t  *font, unsigned long cid, unsigned long *gid)
 
1681
{
 
1682
    unsigned char *p;
 
1683
    unsigned long first_gid;
 
1684
    unsigned long first_cid;
 
1685
    int num_left;
 
1686
    unsigned long c, g;
 
1687
 
 
1688
    if (cid == 0) {
 
1689
        *gid = 0;
 
1690
        return CAIRO_STATUS_SUCCESS;
 
1691
    }
 
1692
 
 
1693
    switch (font->charset[0]) {
 
1694
        /* Format 0 */
 
1695
        case 0:
 
1696
            p = font->charset + 1;
 
1697
            g = 1;
 
1698
            while (g <= (unsigned)font->num_glyphs && p < font->data_end) {
 
1699
                c = be16_to_cpu( *((uint16_t *)p) );
 
1700
                if (c == cid) {
 
1701
                    *gid = g;
 
1702
                    return CAIRO_STATUS_SUCCESS;
 
1703
                }
 
1704
                g++;
 
1705
                p += 2;
 
1706
            }
 
1707
            break;
 
1708
 
 
1709
        /* Format 1 */
 
1710
        case 1:
 
1711
            first_gid = 1;
 
1712
            p = font->charset + 1;
 
1713
            while (first_gid <= (unsigned)font->num_glyphs && p + 2 < font->data_end) {
 
1714
                first_cid = be16_to_cpu( *((uint16_t *)p) );
 
1715
                num_left = p[2];
 
1716
                if (cid >= first_cid && cid <= first_cid + num_left) {
 
1717
                    *gid = first_gid + cid - first_cid;
 
1718
                    return CAIRO_STATUS_SUCCESS;
 
1719
                }
 
1720
                first_gid += num_left + 1;
 
1721
                p += 3;
 
1722
            }
 
1723
            break;
 
1724
 
 
1725
        /* Format 2 */
 
1726
        case 2:
 
1727
            first_gid = 1;
 
1728
            p = font->charset + 1;
 
1729
            while (first_gid <= (unsigned)font->num_glyphs && p + 3 < font->data_end) {
 
1730
                first_cid = be16_to_cpu( *((uint16_t *)p) );
 
1731
                num_left = be16_to_cpu( *((uint16_t *)(p+2)) );
 
1732
                if (cid >= first_cid && cid <= first_cid + num_left) {
 
1733
                    *gid = first_gid + cid - first_cid;
 
1734
                    return CAIRO_STATUS_SUCCESS;
 
1735
                }
 
1736
                first_gid += num_left + 1;
 
1737
                p += 4;
 
1738
            }
 
1739
            break;
 
1740
 
 
1741
        default:
 
1742
            break;
 
1743
    }
 
1744
    return CAIRO_INT_STATUS_UNSUPPORTED;
 
1745
}
 
1746
 
 
1747
static cairo_int_status_t
 
1748
cairo_cff_font_subset_charstrings_and_subroutines (cairo_cff_font_t  *font)
 
1749
{
 
1750
    cff_index_element_t *element;
 
1751
    unsigned int i;
 
1752
    cairo_int_status_t status;
 
1753
    unsigned long glyph, cid;
 
1754
 
 
1755
    font->subset_subroutines = TRUE;
 
1756
    for (i = 0; i < font->scaled_font_subset->num_glyphs; i++) {
 
1757
        if (font->is_cid) {
 
1758
            cid = font->scaled_font_subset->glyphs[i];
 
1759
            status = cairo_cff_font_get_gid_for_cid (font, cid, &glyph);
 
1760
            if (unlikely (status))
 
1761
                return status;
 
1762
        } else {
 
1763
            glyph = font->scaled_font_subset->glyphs[i];
 
1764
        }
 
1765
        element = _cairo_array_index (&font->charstrings_index, glyph);
 
1766
        status = cff_index_append (&font->charstrings_subset_index,
 
1767
                                   element->data,
 
1768
                                   element->length);
 
1769
        if (unlikely (status))
 
1770
            return status;
 
1771
 
 
1772
        if (font->subset_subroutines) {
 
1773
            status = cairo_cff_find_width_and_subroutines_used (font,
 
1774
                                                                element->data, element->length,
 
1775
                                                                glyph, i);
 
1776
            if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
 
1777
                /* If parsing the charstrings fails we embed all the
 
1778
                 * subroutines. But if the font is not opentype we
 
1779
                 * need to successfully parse all charstrings to get
 
1780
                 * the widths. */
 
1781
                font->subset_subroutines = FALSE;
 
1782
                if (!font->is_opentype)
 
1783
                    return status;
 
1784
            } else if (unlikely (status)) {
 
1785
                return status;
 
1786
            }
 
1787
        }
 
1788
    }
 
1789
 
 
1790
    return CAIRO_STATUS_SUCCESS;
 
1791
}
 
1792
 
 
1793
static cairo_status_t
 
1794
cairo_cff_font_subset_fontdict (cairo_cff_font_t  *font)
 
1795
{
 
1796
    unsigned int i;
 
1797
    int fd;
 
1798
    int *reverse_map;
 
1799
    unsigned long cid, gid;
 
1800
    cairo_int_status_t status;
 
1801
 
 
1802
    font->fdselect_subset = calloc (font->scaled_font_subset->num_glyphs,
 
1803
                                     sizeof (int));
 
1804
    if (unlikely (font->fdselect_subset == NULL))
 
1805
        return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
1806
 
 
1807
    font->fd_subset_map = calloc (font->num_fontdicts, sizeof (int));
 
1808
    if (unlikely (font->fd_subset_map == NULL))
 
1809
        return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
1810
 
 
1811
    font->private_dict_offset = calloc (font->num_fontdicts, sizeof (int));
 
1812
    if (unlikely (font->private_dict_offset == NULL))
 
1813
        return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
1814
 
 
1815
    reverse_map = calloc (font->num_fontdicts, sizeof (int));
 
1816
    if (unlikely (reverse_map == NULL))
 
1817
        return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
1818
 
 
1819
    for (i = 0; i < font->num_fontdicts; i++)
 
1820
        reverse_map[i] = -1;
 
1821
 
 
1822
    font->num_subset_fontdicts = 0;
 
1823
    for (i = 0; i < font->scaled_font_subset->num_glyphs; i++) {
 
1824
        cid = font->scaled_font_subset->glyphs[i];
 
1825
        status = cairo_cff_font_get_gid_for_cid (font, cid, &gid);
 
1826
        if (unlikely (status))
 
1827
            return status;
 
1828
 
 
1829
        fd = font->fdselect[gid];
 
1830
        if (reverse_map[fd] < 0) {
 
1831
            font->fd_subset_map[font->num_subset_fontdicts] = fd;
 
1832
            reverse_map[fd] = font->num_subset_fontdicts++;
 
1833
        }
 
1834
        font->fdselect_subset[i] = reverse_map[fd];
 
1835
    }
 
1836
 
 
1837
    free (reverse_map);
 
1838
 
 
1839
    return CAIRO_STATUS_SUCCESS;
 
1840
}
 
1841
 
 
1842
static cairo_status_t
 
1843
cairo_cff_font_create_cid_fontdict (cairo_cff_font_t *font)
 
1844
{
 
1845
    unsigned char buf[100];
 
1846
    unsigned char *end_buf;
 
1847
    cairo_status_t status;
 
1848
 
 
1849
    font->num_fontdicts = 1;
 
1850
    font->fd_dict = malloc (sizeof (cairo_hash_table_t *));
 
1851
    if (unlikely (font->fd_dict == NULL))
 
1852
        return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
1853
 
 
1854
    if (cff_dict_init (&font->fd_dict[0])) {
 
1855
        free (font->fd_dict);
 
1856
        font->fd_dict = NULL;
 
1857
        font->num_fontdicts = 0;
 
1858
        return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
1859
    }
 
1860
 
 
1861
    font->fd_subset_map = malloc (sizeof (int));
 
1862
    if (unlikely (font->fd_subset_map == NULL))
 
1863
        return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
1864
 
 
1865
    font->private_dict_offset = malloc (sizeof (int));
 
1866
    if (unlikely (font->private_dict_offset == NULL))
 
1867
        return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
1868
 
 
1869
    font->fd_subset_map[0] = 0;
 
1870
    font->num_subset_fontdicts = 1;
 
1871
 
 
1872
    /* Set integer operand to max value to use max size encoding to reserve
 
1873
     * space for any value later */
 
1874
    end_buf = encode_integer_max (buf, 0);
 
1875
    end_buf = encode_integer_max (end_buf, 0);
 
1876
    status = cff_dict_set_operands (font->fd_dict[0], PRIVATE_OP, buf, end_buf - buf);
 
1877
    if (unlikely (status))
 
1878
        return status;
 
1879
 
 
1880
    return CAIRO_STATUS_SUCCESS;
 
1881
}
 
1882
 
 
1883
static cairo_status_t
 
1884
cairo_cff_font_subset_strings (cairo_cff_font_t *font)
 
1885
{
 
1886
    cairo_status_t status;
 
1887
    unsigned int i;
 
1888
 
 
1889
    status = cairo_cff_font_subset_dict_strings (font, font->top_dict);
 
1890
    if (unlikely (status))
 
1891
        return status;
 
1892
 
 
1893
    if (font->is_cid) {
 
1894
        for (i = 0; i < font->num_subset_fontdicts; i++) {
 
1895
            status = cairo_cff_font_subset_dict_strings (font, font->fd_dict[font->fd_subset_map[i]]);
 
1896
            if (unlikely (status))
 
1897
                return status;
 
1898
 
 
1899
            status = cairo_cff_font_subset_dict_strings (font, font->fd_private_dict[font->fd_subset_map[i]]);
 
1900
            if (unlikely (status))
 
1901
                return status;
 
1902
        }
 
1903
    } else {
 
1904
        status = cairo_cff_font_subset_dict_strings (font, font->private_dict);
 
1905
    }
 
1906
 
 
1907
    return status;
 
1908
}
 
1909
 
 
1910
/* The Euro is the only the only character in the winansi encoding
 
1911
 * with a glyph name that is not a CFF standard string. As the strings
 
1912
 * are written before the charset, we need to check during the
 
1913
 * subsetting phase if the Euro glyph is required and add the
 
1914
 * glyphname to the list of strings to write out.
 
1915
 */
 
1916
static cairo_status_t
 
1917
cairo_cff_font_add_euro_charset_string (cairo_cff_font_t *font)
 
1918
{
 
1919
    cairo_status_t status;
 
1920
    unsigned int i;
 
1921
    int ch;
 
1922
    const char *euro = "Euro";
 
1923
 
 
1924
    for (i = 1; i < font->scaled_font_subset->num_glyphs; i++) {
 
1925
        ch = font->scaled_font_subset->to_latin_char[i];
 
1926
        if (ch == 128) {
 
1927
            font->euro_sid = NUM_STD_STRINGS + _cairo_array_num_elements (&font->strings_subset_index);
 
1928
            status = cff_index_append_copy (&font->strings_subset_index,
 
1929
                                            (unsigned char *)euro, strlen(euro));
 
1930
            return status;
 
1931
        }
 
1932
    }
 
1933
 
 
1934
    return CAIRO_STATUS_SUCCESS;
 
1935
}
 
1936
 
 
1937
static cairo_status_t
 
1938
cairo_cff_font_subset_font (cairo_cff_font_t  *font)
 
1939
{
 
1940
    cairo_status_t status;
 
1941
 
 
1942
    if (!font->scaled_font_subset->is_latin) {
 
1943
        status = cairo_cff_font_set_ros_strings (font);
 
1944
        if (unlikely (status))
 
1945
            return status;
 
1946
    }
 
1947
 
 
1948
    status = cairo_cff_font_subset_charstrings_and_subroutines (font);
 
1949
    if (unlikely (status))
 
1950
        return status;
 
1951
 
 
1952
    if (!font->scaled_font_subset->is_latin) {
 
1953
        if (font->is_cid)
 
1954
            status = cairo_cff_font_subset_fontdict (font);
 
1955
        else
 
1956
            status = cairo_cff_font_create_cid_fontdict (font);
 
1957
        if (unlikely (status))
 
1958
            return status;
 
1959
    }  else {
 
1960
        font->private_dict_offset = malloc (sizeof (int));
 
1961
        if (unlikely (font->private_dict_offset == NULL))
 
1962
            return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
1963
    }
 
1964
 
 
1965
    status = cairo_cff_font_subset_strings (font);
 
1966
    if (unlikely (status))
 
1967
        return status;
 
1968
 
 
1969
    if (font->scaled_font_subset->is_latin)
 
1970
        status = cairo_cff_font_add_euro_charset_string (font);
 
1971
 
 
1972
    return status;
 
1973
}
 
1974
 
 
1975
/* Set the operand of the specified operator in the (already written)
 
1976
 * top dict to point to the current position in the output
 
1977
 * array. Operands updated with this function must have previously
 
1978
 * been encoded with the 5-byte (max) integer encoding. */
 
1979
static void
 
1980
cairo_cff_font_set_topdict_operator_to_cur_pos (cairo_cff_font_t  *font,
 
1981
                                                int                operator)
 
1982
{
 
1983
    int cur_pos;
 
1984
    int offset;
 
1985
    int size;
 
1986
    unsigned char buf[10];
 
1987
    unsigned char *buf_end;
 
1988
    unsigned char *op_ptr;
 
1989
 
 
1990
    cur_pos = _cairo_array_num_elements (&font->output);
 
1991
    buf_end = encode_integer_max (buf, cur_pos);
 
1992
    offset = cff_dict_get_location (font->top_dict, operator, &size);
 
1993
    assert (offset > 0);
 
1994
    op_ptr = _cairo_array_index (&font->output, offset);
 
1995
    memcpy (op_ptr, buf, buf_end - buf);
 
1996
}
 
1997
 
 
1998
static cairo_status_t
 
1999
cairo_cff_font_write_header (cairo_cff_font_t *font)
 
2000
{
 
2001
    return _cairo_array_append_multiple (&font->output,
 
2002
                                         font->header,
 
2003
                                         font->header->header_size);
 
2004
}
 
2005
 
 
2006
static cairo_status_t
 
2007
cairo_cff_font_write_name (cairo_cff_font_t *font)
 
2008
{
 
2009
    cairo_status_t status = CAIRO_STATUS_SUCCESS;
 
2010
    cairo_array_t index;
 
2011
 
 
2012
    cff_index_init (&index);
 
2013
 
 
2014
    status = cff_index_append_copy (&index,
 
2015
                                    (unsigned char *) font->ps_name,
 
2016
                                    strlen(font->ps_name));
 
2017
    if (unlikely (status))
 
2018
        goto FAIL;
 
2019
 
 
2020
    status = cff_index_write (&index, &font->output);
 
2021
    if (unlikely (status))
 
2022
        goto FAIL;
 
2023
 
 
2024
FAIL:
 
2025
    cff_index_fini (&index);
 
2026
 
 
2027
    return status;
 
2028
}
 
2029
 
 
2030
static cairo_status_t
 
2031
cairo_cff_font_write_top_dict (cairo_cff_font_t *font)
 
2032
{
 
2033
    uint16_t count;
 
2034
    unsigned char buf[10];
 
2035
    unsigned char *p;
 
2036
    int offset_index;
 
2037
    int dict_start, dict_size;
 
2038
    int offset_size = 4;
 
2039
    cairo_status_t status;
 
2040
 
 
2041
    /* Write an index containing the top dict */
 
2042
 
 
2043
    count = cpu_to_be16 (1);
 
2044
    status = _cairo_array_append_multiple (&font->output, &count, 2);
 
2045
    if (unlikely (status))
 
2046
        return status;
 
2047
    buf[0] = offset_size;
 
2048
    status = _cairo_array_append (&font->output, buf);
 
2049
    if (unlikely (status))
 
2050
        return status;
 
2051
    encode_index_offset (buf, offset_size, 1);
 
2052
    status = _cairo_array_append_multiple (&font->output, buf, offset_size);
 
2053
    if (unlikely (status))
 
2054
        return status;
 
2055
 
 
2056
    /* Reserve space for last element of offset array and update after
 
2057
     * dict is written */
 
2058
    offset_index = _cairo_array_num_elements (&font->output);
 
2059
    status = _cairo_array_append_multiple (&font->output, buf, offset_size);
 
2060
    if (unlikely (status))
 
2061
        return status;
 
2062
 
 
2063
    dict_start = _cairo_array_num_elements (&font->output);
 
2064
    status = cff_dict_write (font->top_dict, &font->output);
 
2065
    if (unlikely (status))
 
2066
        return status;
 
2067
    dict_size = _cairo_array_num_elements (&font->output) - dict_start;
 
2068
 
 
2069
    encode_index_offset (buf, offset_size, dict_size + 1);
 
2070
    p = _cairo_array_index (&font->output, offset_index);
 
2071
    memcpy (p, buf, offset_size);
 
2072
 
 
2073
    return CAIRO_STATUS_SUCCESS;
 
2074
}
 
2075
 
 
2076
static cairo_status_t
 
2077
cairo_cff_font_write_strings (cairo_cff_font_t  *font)
 
2078
{
 
2079
    return cff_index_write (&font->strings_subset_index, &font->output);
 
2080
}
 
2081
 
 
2082
static cairo_status_t
 
2083
cairo_cff_font_write_global_subrs (cairo_cff_font_t  *font)
 
2084
{
 
2085
    unsigned int i;
 
2086
    unsigned char return_op = TYPE2_return;
 
2087
 
 
2088
    /* poppler and fontforge don't like zero length subroutines so we
 
2089
     * replace unused subroutines with a 'return' instruction. */
 
2090
    if (font->subset_subroutines) {
 
2091
        for (i = 0; i < _cairo_array_num_elements (&font->global_sub_index); i++) {
 
2092
            if (! font->global_subs_used[i])
 
2093
                cff_index_set_object (&font->global_sub_index, i, &return_op, 1);
 
2094
        }
 
2095
    }
 
2096
 
 
2097
    return cff_index_write (&font->global_sub_index, &font->output);
 
2098
}
 
2099
 
 
2100
static cairo_status_t
 
2101
cairo_cff_font_write_encoding (cairo_cff_font_t  *font)
 
2102
{
 
2103
    unsigned char buf[2];
 
2104
    cairo_status_t status;
 
2105
    unsigned int i;
 
2106
 
 
2107
    cairo_cff_font_set_topdict_operator_to_cur_pos (font, ENCODING_OP);
 
2108
    buf[0] = 0; /* Format 0 */
 
2109
    buf[1] = font->scaled_font_subset->num_glyphs - 1;
 
2110
    status = _cairo_array_append_multiple (&font->output, buf, 2);
 
2111
    if (unlikely (status))
 
2112
        return status;
 
2113
 
 
2114
    for (i = 1; i < font->scaled_font_subset->num_glyphs; i++) {
 
2115
        unsigned char ch = font->scaled_font_subset->to_latin_char[i];
 
2116
        status = _cairo_array_append (&font->output, &ch);
 
2117
        if (unlikely (status))
 
2118
            return status;
 
2119
    }
 
2120
 
 
2121
    return CAIRO_STATUS_SUCCESS;
 
2122
}
 
2123
 
 
2124
static cairo_status_t
 
2125
cairo_cff_font_write_fdselect (cairo_cff_font_t  *font)
 
2126
{
 
2127
    unsigned char data;
 
2128
    unsigned int i;
 
2129
    cairo_int_status_t status;
 
2130
 
 
2131
    cairo_cff_font_set_topdict_operator_to_cur_pos (font, FDSELECT_OP);
 
2132
 
 
2133
    if (font->is_cid) {
 
2134
        data = 0;
 
2135
        status = _cairo_array_append (&font->output, &data);
 
2136
        if (unlikely (status))
 
2137
            return status;
 
2138
 
 
2139
        for (i = 0; i < font->scaled_font_subset->num_glyphs; i++) {
 
2140
            data = font->fdselect_subset[i];
 
2141
            status = _cairo_array_append (&font->output, &data);
 
2142
            if (unlikely (status))
 
2143
                return status;
 
2144
        }
 
2145
    } else {
 
2146
        unsigned char byte;
 
2147
        uint16_t word;
 
2148
 
 
2149
        status = _cairo_array_grow_by (&font->output, 9);
 
2150
        if (unlikely (status))
 
2151
            return status;
 
2152
 
 
2153
        byte = 3;
 
2154
        status = _cairo_array_append (&font->output, &byte);
 
2155
        assert (status == CAIRO_INT_STATUS_SUCCESS);
 
2156
 
 
2157
        word = cpu_to_be16 (1);
 
2158
        status = _cairo_array_append_multiple (&font->output, &word, 2);
 
2159
        assert (status == CAIRO_INT_STATUS_SUCCESS);
 
2160
 
 
2161
        word = cpu_to_be16 (0);
 
2162
        status = _cairo_array_append_multiple (&font->output, &word, 2);
 
2163
        assert (status == CAIRO_INT_STATUS_SUCCESS);
 
2164
 
 
2165
        byte = 0;
 
2166
        status = _cairo_array_append (&font->output, &byte);
 
2167
        assert (status == CAIRO_INT_STATUS_SUCCESS);
 
2168
 
 
2169
        word = cpu_to_be16 (font->scaled_font_subset->num_glyphs);
 
2170
        status = _cairo_array_append_multiple (&font->output, &word, 2);
 
2171
        assert (status == CAIRO_INT_STATUS_SUCCESS);
 
2172
    }
 
2173
 
 
2174
    return CAIRO_STATUS_SUCCESS;
 
2175
}
 
2176
 
 
2177
/* Winansi to CFF standard strings mapping for characters 128 to 255 */
 
2178
static const int winansi_to_cff_std_string[] = {
 
2179
        /* 128 */
 
2180
      0,   0, 117, 101, 118, 121, 112, 113,
 
2181
    126, 122, 192, 107, 142,   0, 199,   0,
 
2182
        /* 144 */
 
2183
      0,  65,   8, 105, 119, 116, 111, 137,
 
2184
    127, 153, 221, 108, 148,   0, 228, 198,
 
2185
        /* 160 */
 
2186
      0,  96,  97,  98, 103, 100, 160, 102,
 
2187
    131, 170, 139, 106, 151,   0, 165, 128,
 
2188
        /* 176 */
 
2189
    161, 156, 164, 169, 125, 152, 115, 114,
 
2190
    133, 150, 143, 120, 158, 155, 163, 123,
 
2191
        /* 192 */
 
2192
    174, 171, 172, 176, 173, 175, 138, 177,
 
2193
    181, 178, 179, 180, 185, 182, 183, 184,
 
2194
        /* 208 */
 
2195
    154, 186, 190, 187, 188, 191, 189, 168,
 
2196
    141, 196, 193, 194, 195, 197, 157, 149,
 
2197
        /* 224 */
 
2198
    203, 200, 201, 205, 202, 204, 144, 206,
 
2199
    210, 207, 208, 209, 214, 211, 212, 213,
 
2200
        /* 240 */
 
2201
    167, 215, 219, 216, 217, 220, 218, 159,
 
2202
    147, 225, 222, 223, 224, 226, 162, 227,
 
2203
};
 
2204
 
 
2205
static int
 
2206
cairo_cff_font_get_sid_for_winansi_char (cairo_cff_font_t  *font, int ch)
 
2207
{
 
2208
    int sid;
 
2209
 
 
2210
    if (ch == 39) {
 
2211
        sid = 104;
 
2212
 
 
2213
    } else if (ch == 96) {
 
2214
        sid = 124;
 
2215
 
 
2216
    } else if (ch >= 32 && ch <= 126) {
 
2217
        sid = ch - 31;
 
2218
 
 
2219
    } else if (ch == 128) {
 
2220
        assert (font->euro_sid >= NUM_STD_STRINGS);
 
2221
        sid = font->euro_sid;
 
2222
 
 
2223
    } else if (ch >= 128 && ch <= 255) {
 
2224
        sid = winansi_to_cff_std_string[ch - 128];
 
2225
 
 
2226
    } else {
 
2227
        sid = 0;
 
2228
    }
 
2229
 
 
2230
    return sid;
 
2231
}
 
2232
 
 
2233
static cairo_status_t
 
2234
cairo_cff_font_write_type1_charset (cairo_cff_font_t  *font)
 
2235
{
 
2236
    unsigned char format = 0;
 
2237
    unsigned int i;
 
2238
    int ch, sid;
 
2239
    cairo_status_t status;
 
2240
    uint16_t sid_be16;
 
2241
 
 
2242
    cairo_cff_font_set_topdict_operator_to_cur_pos (font, CHARSET_OP);
 
2243
    status = _cairo_array_append (&font->output, &format);
 
2244
    if (unlikely (status))
 
2245
        return status;
 
2246
 
 
2247
    for (i = 1; i < font->scaled_font_subset->num_glyphs; i++) {
 
2248
        ch = font->scaled_font_subset->to_latin_char[i];
 
2249
        sid = cairo_cff_font_get_sid_for_winansi_char (font, ch);
 
2250
        if (unlikely (status))
 
2251
            return status;
 
2252
 
 
2253
        sid_be16 = cpu_to_be16(sid);
 
2254
        status = _cairo_array_append_multiple (&font->output, &sid_be16, sizeof(sid_be16));
 
2255
        if (unlikely (status))
 
2256
            return status;
 
2257
    }
 
2258
 
 
2259
    return CAIRO_STATUS_SUCCESS;
 
2260
}
 
2261
 
 
2262
static cairo_status_t
 
2263
cairo_cff_font_write_cid_charset (cairo_cff_font_t  *font)
 
2264
{
 
2265
    unsigned char byte;
 
2266
    uint16_t word;
 
2267
    cairo_status_t status;
 
2268
 
 
2269
    cairo_cff_font_set_topdict_operator_to_cur_pos (font, CHARSET_OP);
 
2270
    status = _cairo_array_grow_by (&font->output, 5);
 
2271
    if (unlikely (status))
 
2272
        return status;
 
2273
 
 
2274
    byte = 2;
 
2275
    status = _cairo_array_append (&font->output, &byte);
 
2276
    assert (status == CAIRO_STATUS_SUCCESS);
 
2277
 
 
2278
    word = cpu_to_be16 (1);
 
2279
    status = _cairo_array_append_multiple (&font->output, &word, 2);
 
2280
    assert (status == CAIRO_STATUS_SUCCESS);
 
2281
 
 
2282
    word = cpu_to_be16 (font->scaled_font_subset->num_glyphs - 2);
 
2283
    status = _cairo_array_append_multiple (&font->output, &word, 2);
 
2284
    assert (status == CAIRO_STATUS_SUCCESS);
 
2285
 
 
2286
    return CAIRO_STATUS_SUCCESS;
 
2287
}
 
2288
 
 
2289
static cairo_status_t
 
2290
cairo_cff_font_write_charstrings (cairo_cff_font_t  *font)
 
2291
{
 
2292
    cairo_cff_font_set_topdict_operator_to_cur_pos (font, CHARSTRINGS_OP);
 
2293
 
 
2294
    return cff_index_write (&font->charstrings_subset_index, &font->output);
 
2295
}
 
2296
 
 
2297
static cairo_status_t
 
2298
cairo_cff_font_write_cid_fontdict (cairo_cff_font_t *font)
 
2299
{
 
2300
    unsigned int i;
 
2301
    cairo_int_status_t status;
 
2302
    unsigned int offset_array;
 
2303
    uint32_t *offset_array_ptr;
 
2304
    int offset_base;
 
2305
    uint16_t count;
 
2306
    uint8_t offset_size = 4;
 
2307
 
 
2308
    cairo_cff_font_set_topdict_operator_to_cur_pos (font, FDARRAY_OP);
 
2309
    count = cpu_to_be16 (font->num_subset_fontdicts);
 
2310
    status = _cairo_array_append_multiple (&font->output, &count, sizeof (uint16_t));
 
2311
    if (unlikely (status))
 
2312
        return status;
 
2313
    status = _cairo_array_append (&font->output, &offset_size);
 
2314
    if (unlikely (status))
 
2315
        return status;
 
2316
 
 
2317
    offset_array = _cairo_array_num_elements (&font->output);
 
2318
    status = _cairo_array_allocate (&font->output,
 
2319
                                    (font->num_subset_fontdicts + 1)*offset_size,
 
2320
                                    (void **) &offset_array_ptr);
 
2321
    if (unlikely (status))
 
2322
        return status;
 
2323
    offset_base = _cairo_array_num_elements (&font->output) - 1;
 
2324
    *offset_array_ptr = cpu_to_be32(1);
 
2325
    offset_array += sizeof(uint32_t);
 
2326
    for (i = 0; i < font->num_subset_fontdicts; i++) {
 
2327
        status = cff_dict_write (font->fd_dict[font->fd_subset_map[i]],
 
2328
                                 &font->output);
 
2329
        if (unlikely (status))
 
2330
            return status;
 
2331
 
 
2332
        offset_array_ptr = (uint32_t *) _cairo_array_index (&font->output, offset_array);
 
2333
        *offset_array_ptr = cpu_to_be32(_cairo_array_num_elements (&font->output) - offset_base);
 
2334
        offset_array += sizeof(uint32_t);
 
2335
    }
 
2336
 
 
2337
    return CAIRO_STATUS_SUCCESS;
 
2338
}
 
2339
 
 
2340
static cairo_status_t
 
2341
cairo_cff_font_write_private_dict (cairo_cff_font_t   *font,
 
2342
                                   int                 dict_num,
 
2343
                                   cairo_hash_table_t *parent_dict,
 
2344
                                   cairo_hash_table_t *private_dict)
 
2345
{
 
2346
    int offset;
 
2347
    int size;
 
2348
    unsigned char buf[10];
 
2349
    unsigned char *buf_end;
 
2350
    unsigned char *p;
 
2351
    cairo_status_t status;
 
2352
 
 
2353
    /* Write private dict and update offset and size in top dict */
 
2354
    font->private_dict_offset[dict_num] = _cairo_array_num_elements (&font->output);
 
2355
    status = cff_dict_write (private_dict, &font->output);
 
2356
    if (unlikely (status))
 
2357
        return status;
 
2358
 
 
2359
    size = _cairo_array_num_elements (&font->output) - font->private_dict_offset[dict_num];
 
2360
    /* private entry has two operands - size and offset */
 
2361
    buf_end = encode_integer_max (buf, size);
 
2362
    buf_end = encode_integer_max (buf_end, font->private_dict_offset[dict_num]);
 
2363
    offset = cff_dict_get_location (parent_dict, PRIVATE_OP, &size);
 
2364
    assert (offset > 0);
 
2365
    p = _cairo_array_index (&font->output, offset);
 
2366
    memcpy (p, buf, buf_end - buf);
 
2367
 
 
2368
    return CAIRO_STATUS_SUCCESS;
 
2369
}
 
2370
 
 
2371
static cairo_status_t
 
2372
cairo_cff_font_write_local_sub (cairo_cff_font_t   *font,
 
2373
                                int                 dict_num,
 
2374
                                cairo_hash_table_t *private_dict,
 
2375
                                cairo_array_t      *local_sub_index,
 
2376
                                cairo_bool_t       *local_subs_used)
 
2377
{
 
2378
    int offset;
 
2379
    int size;
 
2380
    unsigned char buf[10];
 
2381
    unsigned char *buf_end;
 
2382
    unsigned char *p;
 
2383
    cairo_status_t status;
 
2384
    unsigned int i;
 
2385
    unsigned char return_op = TYPE2_return;
 
2386
 
 
2387
    if (_cairo_array_num_elements (local_sub_index) > 0) {
 
2388
        /* Write local subroutines and update offset in private
 
2389
         * dict. Local subroutines offset is relative to start of
 
2390
         * private dict */
 
2391
        offset = _cairo_array_num_elements (&font->output) - font->private_dict_offset[dict_num];
 
2392
        buf_end = encode_integer_max (buf, offset);
 
2393
        offset = cff_dict_get_location (private_dict, LOCAL_SUB_OP, &size);
 
2394
        assert (offset > 0);
 
2395
        p = _cairo_array_index (&font->output, offset);
 
2396
        memcpy (p, buf, buf_end - buf);
 
2397
 
 
2398
        /* poppler and fontforge don't like zero length subroutines so
 
2399
         * we replace unused subroutines with a 'return' instruction.
 
2400
         */
 
2401
        if (font->subset_subroutines) {
 
2402
            for (i = 0; i < _cairo_array_num_elements (local_sub_index); i++) {
 
2403
                if (! local_subs_used[i])
 
2404
                    cff_index_set_object (local_sub_index, i, &return_op, 1);
 
2405
            }
 
2406
        }
 
2407
        status = cff_index_write (local_sub_index, &font->output);
 
2408
        if (unlikely (status))
 
2409
            return status;
 
2410
    }
 
2411
 
 
2412
    return CAIRO_STATUS_SUCCESS;
 
2413
}
 
2414
 
 
2415
 
 
2416
static cairo_status_t
 
2417
cairo_cff_font_write_cid_private_dict_and_local_sub (cairo_cff_font_t  *font)
 
2418
{
 
2419
    unsigned int i;
 
2420
    cairo_int_status_t status;
 
2421
 
 
2422
    if (font->is_cid) {
 
2423
        for (i = 0; i < font->num_subset_fontdicts; i++) {
 
2424
            status = cairo_cff_font_write_private_dict (
 
2425
                            font,
 
2426
                            i,
 
2427
                            font->fd_dict[font->fd_subset_map[i]],
 
2428
                            font->fd_private_dict[font->fd_subset_map[i]]);
 
2429
            if (unlikely (status))
 
2430
                return status;
 
2431
        }
 
2432
 
 
2433
        for (i = 0; i < font->num_subset_fontdicts; i++) {
 
2434
            status = cairo_cff_font_write_local_sub (
 
2435
                            font,
 
2436
                            i,
 
2437
                            font->fd_private_dict[font->fd_subset_map[i]],
 
2438
                            &font->fd_local_sub_index[font->fd_subset_map[i]],
 
2439
                            font->fd_local_subs_used[font->fd_subset_map[i]]);
 
2440
            if (unlikely (status))
 
2441
                return status;
 
2442
        }
 
2443
    } else {
 
2444
        status = cairo_cff_font_write_private_dict (font,
 
2445
                                                    0,
 
2446
                                                    font->fd_dict[0],
 
2447
                                                    font->private_dict);
 
2448
        if (unlikely (status))
 
2449
            return status;
 
2450
 
 
2451
        status = cairo_cff_font_write_local_sub (font,
 
2452
                                                 0,
 
2453
                                                 font->private_dict,
 
2454
                                                 &font->local_sub_index,
 
2455
                                                 font->local_subs_used);
 
2456
        if (unlikely (status))
 
2457
            return status;
 
2458
    }
 
2459
 
 
2460
    return CAIRO_STATUS_SUCCESS;
 
2461
}
 
2462
 
 
2463
static cairo_status_t
 
2464
cairo_cff_font_write_type1_private_dict_and_local_sub (cairo_cff_font_t  *font)
 
2465
{
 
2466
    cairo_int_status_t status;
 
2467
 
 
2468
    status = cairo_cff_font_write_private_dict (font,
 
2469
                                                0,
 
2470
                                                font->top_dict,
 
2471
                                                font->private_dict);
 
2472
    if (unlikely (status))
 
2473
        return status;
 
2474
 
 
2475
    status = cairo_cff_font_write_local_sub (font,
 
2476
                                             0,
 
2477
                                             font->private_dict,
 
2478
                                             &font->local_sub_index,
 
2479
                                             font->local_subs_used);
 
2480
    if (unlikely (status))
 
2481
        return status;
 
2482
 
 
2483
    return CAIRO_STATUS_SUCCESS;
 
2484
}
 
2485
 
 
2486
 
 
2487
typedef cairo_status_t
 
2488
(*font_write_t) (cairo_cff_font_t *font);
 
2489
 
 
2490
static const font_write_t font_write_cid_funcs[] = {
 
2491
    cairo_cff_font_write_header,
 
2492
    cairo_cff_font_write_name,
 
2493
    cairo_cff_font_write_top_dict,
 
2494
    cairo_cff_font_write_strings,
 
2495
    cairo_cff_font_write_global_subrs,
 
2496
    cairo_cff_font_write_cid_charset,
 
2497
    cairo_cff_font_write_fdselect,
 
2498
    cairo_cff_font_write_charstrings,
 
2499
    cairo_cff_font_write_cid_fontdict,
 
2500
    cairo_cff_font_write_cid_private_dict_and_local_sub,
 
2501
};
 
2502
 
 
2503
static const font_write_t font_write_type1_funcs[] = {
 
2504
    cairo_cff_font_write_header,
 
2505
    cairo_cff_font_write_name,
 
2506
    cairo_cff_font_write_top_dict,
 
2507
    cairo_cff_font_write_strings,
 
2508
    cairo_cff_font_write_global_subrs,
 
2509
    cairo_cff_font_write_encoding,
 
2510
    cairo_cff_font_write_type1_charset,
 
2511
    cairo_cff_font_write_charstrings,
 
2512
    cairo_cff_font_write_type1_private_dict_and_local_sub,
 
2513
};
 
2514
 
 
2515
static cairo_status_t
 
2516
cairo_cff_font_write_subset (cairo_cff_font_t *font)
 
2517
{
 
2518
    cairo_int_status_t status;
 
2519
    unsigned int i;
 
2520
 
 
2521
    if (font->scaled_font_subset->is_latin) {
 
2522
        for (i = 0; i < ARRAY_LENGTH (font_write_type1_funcs); i++) {
 
2523
            status = font_write_type1_funcs[i] (font);
 
2524
            if (unlikely (status))
 
2525
                return status;
 
2526
        }
 
2527
    } else {
 
2528
        for (i = 0; i < ARRAY_LENGTH (font_write_cid_funcs); i++) {
 
2529
            status = font_write_cid_funcs[i] (font);
 
2530
            if (unlikely (status))
 
2531
                return status;
 
2532
        }
 
2533
    }
 
2534
 
 
2535
    return CAIRO_STATUS_SUCCESS;
 
2536
}
 
2537
 
 
2538
static cairo_int_status_t
 
2539
cairo_cff_font_generate (cairo_cff_font_t  *font,
 
2540
                         const char       **data,
 
2541
                         unsigned long     *length)
 
2542
{
 
2543
    cairo_int_status_t status;
 
2544
 
 
2545
    status = cairo_cff_font_read_font (font);
 
2546
    if (unlikely (status))
 
2547
        return status;
 
2548
 
 
2549
    /* If the PS name is not found, create a CairoFont-x-y name. */
 
2550
    if (font->ps_name == NULL) {
 
2551
        font->ps_name = malloc (30);
 
2552
        if (unlikely (font->ps_name == NULL))
 
2553
            return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
2554
 
 
2555
        snprintf(font->ps_name, 30, "CairoFont-%u-%u",
 
2556
                 font->scaled_font_subset->font_id,
 
2557
                 font->scaled_font_subset->subset_id);
 
2558
    }
 
2559
 
 
2560
    status = cairo_cff_font_subset_font (font);
 
2561
    if (unlikely (status))
 
2562
        return status;
 
2563
 
 
2564
    status = cairo_cff_font_write_subset (font);
 
2565
    if (unlikely (status))
 
2566
        return status;
 
2567
 
 
2568
 
 
2569
    *data = _cairo_array_index (&font->output, 0);
 
2570
    *length = _cairo_array_num_elements (&font->output);
 
2571
 
 
2572
    return CAIRO_STATUS_SUCCESS;
 
2573
}
 
2574
 
 
2575
static cairo_int_status_t
 
2576
cairo_cff_font_create_set_widths (cairo_cff_font_t *font)
 
2577
{
 
2578
    unsigned long size;
 
2579
    unsigned long long_entry_size;
 
2580
    unsigned long short_entry_size;
 
2581
    unsigned int i;
 
2582
    tt_hhea_t hhea;
 
2583
    int num_hmetrics;
 
2584
    unsigned char buf[10];
 
2585
    int glyph_index;
 
2586
    cairo_int_status_t status;
 
2587
 
 
2588
    size = sizeof (tt_hhea_t);
 
2589
    status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
 
2590
                                                 TT_TAG_hhea, 0,
 
2591
                                                 (unsigned char*) &hhea, &size);
 
2592
    if (unlikely (status))
 
2593
        return status;
 
2594
    num_hmetrics = be16_to_cpu (hhea.num_hmetrics);
 
2595
 
 
2596
    for (i = 0; i < font->scaled_font_subset->num_glyphs; i++) {
 
2597
        glyph_index = font->scaled_font_subset->glyphs[i];
 
2598
        long_entry_size = 2 * sizeof (int16_t);
 
2599
        short_entry_size = sizeof (int16_t);
 
2600
        if (glyph_index < num_hmetrics) {
 
2601
            status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
 
2602
                                                         TT_TAG_hmtx,
 
2603
                                                         glyph_index * long_entry_size,
 
2604
                                                         buf, &short_entry_size);
 
2605
            if (unlikely (status))
 
2606
                return status;
 
2607
        }
 
2608
        else
 
2609
        {
 
2610
            status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
 
2611
                                                         TT_TAG_hmtx,
 
2612
                                                         (num_hmetrics - 1) * long_entry_size,
 
2613
                                                         buf, &short_entry_size);
 
2614
            if (unlikely (status))
 
2615
                return status;
 
2616
        }
 
2617
        font->widths[i] = be16_to_cpu (*((int16_t*)buf));
 
2618
    }
 
2619
 
 
2620
    return CAIRO_STATUS_SUCCESS;
 
2621
}
 
2622
 
 
2623
static cairo_bool_t
 
2624
check_fontdata_is_cff (const unsigned char *data, long length)
 
2625
{
 
2626
    cff_header_t *header;
 
2627
 
 
2628
    if (length < (long)sizeof (cff_header_t))
 
2629
        return FALSE;
 
2630
 
 
2631
    header = (cff_header_t *) data;
 
2632
    if (header->major == 1 &&
 
2633
        header->minor == 0 &&
 
2634
        header->header_size == 4)
 
2635
    {
 
2636
        return TRUE;
 
2637
    }
 
2638
 
 
2639
    return FALSE;
 
2640
}
 
2641
 
 
2642
static cairo_int_status_t
 
2643
_cairo_cff_font_load_opentype_cff (cairo_cff_font_t  *font)
 
2644
{
 
2645
    const cairo_scaled_font_backend_t *backend = font->backend;
 
2646
    cairo_status_t status;
 
2647
    tt_head_t head;
 
2648
    tt_hhea_t hhea;
 
2649
    unsigned long size, data_length;
 
2650
 
 
2651
    if (!backend->load_truetype_table)
 
2652
        return CAIRO_INT_STATUS_UNSUPPORTED;
 
2653
 
 
2654
    data_length = 0;
 
2655
    status = backend->load_truetype_table (font->scaled_font_subset->scaled_font,
 
2656
                                           TT_TAG_CFF, 0, NULL, &data_length);
 
2657
    if (status)
 
2658
        return status;
 
2659
 
 
2660
    size = sizeof (tt_head_t);
 
2661
    status = backend->load_truetype_table (font->scaled_font_subset->scaled_font,
 
2662
                                           TT_TAG_head, 0,
 
2663
                                           (unsigned char *) &head, &size);
 
2664
    if (unlikely (status))
 
2665
        return status;
 
2666
 
 
2667
    size = sizeof (tt_hhea_t);
 
2668
    status = backend->load_truetype_table (font->scaled_font_subset->scaled_font,
 
2669
                                           TT_TAG_hhea, 0,
 
2670
                                           (unsigned char *) &hhea, &size);
 
2671
    if (unlikely (status))
 
2672
        return status;
 
2673
 
 
2674
    size = 0;
 
2675
    status = backend->load_truetype_table (font->scaled_font_subset->scaled_font,
 
2676
                                           TT_TAG_hmtx, 0, NULL, &size);
 
2677
    if (unlikely (status))
 
2678
        return status;
 
2679
 
 
2680
    font->x_min = (int16_t) be16_to_cpu (head.x_min);
 
2681
    font->y_min = (int16_t) be16_to_cpu (head.y_min);
 
2682
    font->x_max = (int16_t) be16_to_cpu (head.x_max);
 
2683
    font->y_max = (int16_t) be16_to_cpu (head.y_max);
 
2684
    font->ascent = (int16_t) be16_to_cpu (hhea.ascender);
 
2685
    font->descent = (int16_t) be16_to_cpu (hhea.descender);
 
2686
    font->units_per_em = (int16_t) be16_to_cpu (head.units_per_em);
 
2687
    if (font->units_per_em == 0)
 
2688
        font->units_per_em = 1000;
 
2689
 
 
2690
    font->font_name = NULL;
 
2691
    status = _cairo_truetype_read_font_name (font->scaled_font_subset->scaled_font,
 
2692
                                             &font->ps_name,
 
2693
                                             &font->font_name);
 
2694
    if (_cairo_status_is_error (status))
 
2695
        return status;
 
2696
 
 
2697
    font->is_opentype = TRUE;
 
2698
    font->data_length = data_length;
 
2699
    font->data = malloc (data_length);
 
2700
    if (unlikely (font->data == NULL))
 
2701
        return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
2702
 
 
2703
    status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
 
2704
                                                 TT_TAG_CFF, 0, font->data,
 
2705
                                                 &font->data_length);
 
2706
    if (unlikely (status))
 
2707
        return status;
 
2708
 
 
2709
    if (!check_fontdata_is_cff (font->data, data_length))
 
2710
        return CAIRO_INT_STATUS_UNSUPPORTED;
 
2711
 
 
2712
    return CAIRO_STATUS_SUCCESS;
 
2713
}
 
2714
 
 
2715
static cairo_int_status_t
 
2716
_cairo_cff_font_load_cff (cairo_cff_font_t  *font)
 
2717
{
 
2718
    const cairo_scaled_font_backend_t *backend = font->backend;
 
2719
    cairo_status_t status;
 
2720
    unsigned long data_length;
 
2721
 
 
2722
    if (!backend->load_type1_data)
 
2723
        return CAIRO_INT_STATUS_UNSUPPORTED;
 
2724
 
 
2725
    data_length = 0;
 
2726
    status = backend->load_type1_data (font->scaled_font_subset->scaled_font,
 
2727
                                      0, NULL, &data_length);
 
2728
    if (unlikely (status))
 
2729
        return status;
 
2730
 
 
2731
    font->font_name = NULL;
 
2732
    font->is_opentype = FALSE;
 
2733
    font->data_length = data_length;
 
2734
    font->data = malloc (data_length);
 
2735
    if (unlikely (font->data == NULL))
 
2736
        return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
2737
 
 
2738
    status = font->backend->load_type1_data (font->scaled_font_subset->scaled_font,
 
2739
                                             0, font->data, &font->data_length);
 
2740
    if (unlikely (status))
 
2741
        return status;
 
2742
 
 
2743
    if (!check_fontdata_is_cff (font->data, data_length))
 
2744
        return CAIRO_INT_STATUS_UNSUPPORTED;
 
2745
 
 
2746
    return CAIRO_STATUS_SUCCESS;
 
2747
}
 
2748
 
 
2749
static cairo_int_status_t
 
2750
_cairo_cff_font_create (cairo_scaled_font_subset_t  *scaled_font_subset,
 
2751
                        cairo_cff_font_t           **font_return,
 
2752
                        const char                  *subset_name)
 
2753
{
 
2754
    const cairo_scaled_font_backend_t *backend;
 
2755
    cairo_int_status_t status;
 
2756
    cairo_cff_font_t *font;
 
2757
 
 
2758
    backend = scaled_font_subset->scaled_font->backend;
 
2759
 
 
2760
    /* We need to use a fallback font generated from the synthesized outlines. */
 
2761
    if (backend->is_synthetic && backend->is_synthetic (scaled_font_subset->scaled_font))
 
2762
        return CAIRO_INT_STATUS_UNSUPPORTED;
 
2763
 
 
2764
    font = malloc (sizeof (cairo_cff_font_t));
 
2765
    if (unlikely (font == NULL))
 
2766
        return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
2767
 
 
2768
    font->backend = backend;
 
2769
    font->scaled_font_subset = scaled_font_subset;
 
2770
 
 
2771
    status = _cairo_cff_font_load_opentype_cff (font);
 
2772
    if (status == CAIRO_INT_STATUS_UNSUPPORTED)
 
2773
        status = _cairo_cff_font_load_cff (font);
 
2774
    if (status)
 
2775
        goto fail1;
 
2776
 
 
2777
    font->data_end = font->data + font->data_length;
 
2778
    _cairo_array_init (&font->output, sizeof (char));
 
2779
    status = _cairo_array_grow_by (&font->output, 4096);
 
2780
    if (unlikely (status))
 
2781
        goto fail2;
 
2782
 
 
2783
    font->subset_font_name = strdup (subset_name);
 
2784
    if (unlikely (font->subset_font_name == NULL)) {
 
2785
        status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
2786
        goto fail2;
 
2787
    }
 
2788
 
 
2789
    font->widths = calloc (font->scaled_font_subset->num_glyphs, sizeof (int));
 
2790
    if (unlikely (font->widths == NULL)) {
 
2791
        status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
2792
        goto fail3;
 
2793
    }
 
2794
 
 
2795
    if (font->is_opentype) {
 
2796
        status = cairo_cff_font_create_set_widths (font);
 
2797
        if (unlikely (status))
 
2798
            goto fail4;
 
2799
    }
 
2800
 
 
2801
    status = cff_dict_init (&font->top_dict);
 
2802
    if (unlikely (status))
 
2803
        goto fail4;
 
2804
 
 
2805
    status = cff_dict_init (&font->private_dict);
 
2806
    if (unlikely (status))
 
2807
        goto fail5;
 
2808
 
 
2809
    cff_index_init (&font->strings_index);
 
2810
    cff_index_init (&font->charstrings_index);
 
2811
    cff_index_init (&font->global_sub_index);
 
2812
    cff_index_init (&font->local_sub_index);
 
2813
    cff_index_init (&font->charstrings_subset_index);
 
2814
    cff_index_init (&font->strings_subset_index);
 
2815
    font->euro_sid = 0;
 
2816
    font->fdselect = NULL;
 
2817
    font->fd_dict = NULL;
 
2818
    font->fd_private_dict = NULL;
 
2819
    font->fd_local_sub_index = NULL;
 
2820
    font->fd_local_sub_bias = NULL;
 
2821
    font->fdselect_subset = NULL;
 
2822
    font->fd_subset_map = NULL;
 
2823
    font->private_dict_offset = NULL;
 
2824
    font->global_subs_used = NULL;
 
2825
    font->local_subs_used = NULL;
 
2826
    font->fd_local_subs_used = NULL;
 
2827
 
 
2828
    *font_return = font;
 
2829
 
 
2830
    return CAIRO_STATUS_SUCCESS;
 
2831
 
 
2832
fail5:
 
2833
    _cairo_hash_table_destroy (font->top_dict);
 
2834
fail4:
 
2835
    free (font->widths);
 
2836
fail3:
 
2837
    free (font->subset_font_name);
 
2838
fail2:
 
2839
    free (font->data);
 
2840
    free (font->font_name);
 
2841
    free (font->ps_name);
 
2842
    _cairo_array_fini (&font->output);
 
2843
fail1:
 
2844
    free (font);
 
2845
 
 
2846
    return status;
 
2847
}
 
2848
 
 
2849
static void
 
2850
cairo_cff_font_destroy (cairo_cff_font_t *font)
 
2851
{
 
2852
    unsigned int i;
 
2853
 
 
2854
    free (font->widths);
 
2855
    free (font->font_name);
 
2856
    free (font->ps_name);
 
2857
    free (font->subset_font_name);
 
2858
    _cairo_array_fini (&font->output);
 
2859
    cff_dict_fini (font->top_dict);
 
2860
    cff_dict_fini (font->private_dict);
 
2861
    cff_index_fini (&font->strings_index);
 
2862
    cff_index_fini (&font->charstrings_index);
 
2863
    cff_index_fini (&font->global_sub_index);
 
2864
    cff_index_fini (&font->local_sub_index);
 
2865
    cff_index_fini (&font->charstrings_subset_index);
 
2866
    cff_index_fini (&font->strings_subset_index);
 
2867
 
 
2868
    /* If we bailed out early as a result of an error some of the
 
2869
     * following cairo_cff_font_t members may still be NULL */
 
2870
    if (font->fd_dict) {
 
2871
        for (i = 0; i < font->num_fontdicts; i++) {
 
2872
            if (font->fd_dict[i])
 
2873
                cff_dict_fini (font->fd_dict[i]);
 
2874
        }
 
2875
        free (font->fd_dict);
 
2876
    }
 
2877
    free (font->global_subs_used);
 
2878
    free (font->local_subs_used);
 
2879
    free (font->fd_subset_map);
 
2880
    free (font->private_dict_offset);
 
2881
 
 
2882
    if (font->is_cid) {
 
2883
        free (font->fdselect);
 
2884
        free (font->fdselect_subset);
 
2885
        if (font->fd_private_dict) {
 
2886
            for (i = 0; i < font->num_fontdicts; i++) {
 
2887
                if (font->fd_private_dict[i])
 
2888
                    cff_dict_fini (font->fd_private_dict[i]);
 
2889
            }
 
2890
            free (font->fd_private_dict);
 
2891
        }
 
2892
        if (font->fd_local_sub_index) {
 
2893
            for (i = 0; i < font->num_fontdicts; i++)
 
2894
                cff_index_fini (&font->fd_local_sub_index[i]);
 
2895
            free (font->fd_local_sub_index);
 
2896
        }
 
2897
        free (font->fd_local_sub_bias);
 
2898
        if (font->fd_local_subs_used) {
 
2899
            for (i = 0; i < font->num_fontdicts; i++) {
 
2900
                free (font->fd_local_subs_used[i]);
 
2901
            }
 
2902
            free (font->fd_local_subs_used);
 
2903
        }
 
2904
        free (font->fd_default_width);
 
2905
        free (font->fd_nominal_width);
 
2906
    }
 
2907
 
 
2908
    free (font->data);
 
2909
 
 
2910
    free (font);
 
2911
}
 
2912
 
 
2913
cairo_status_t
 
2914
_cairo_cff_subset_init (cairo_cff_subset_t          *cff_subset,
 
2915
                        const char                  *subset_name,
 
2916
                        cairo_scaled_font_subset_t  *font_subset)
 
2917
{
 
2918
    cairo_cff_font_t *font = NULL; /* squelch bogus compiler warning */
 
2919
    cairo_status_t status;
 
2920
    const char *data = NULL; /* squelch bogus compiler warning */
 
2921
    unsigned long length = 0; /* squelch bogus compiler warning */
 
2922
    unsigned int i;
 
2923
 
 
2924
    status = _cairo_cff_font_create (font_subset, &font, subset_name);
 
2925
    if (unlikely (status))
 
2926
        return status;
 
2927
 
 
2928
    status = cairo_cff_font_generate (font, &data, &length);
 
2929
    if (unlikely (status))
 
2930
        goto fail1;
 
2931
 
 
2932
    cff_subset->ps_name = strdup (font->ps_name);
 
2933
    if (unlikely (cff_subset->ps_name == NULL)) {
 
2934
        status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
2935
        goto fail1;
 
2936
    }
 
2937
 
 
2938
    if (font->font_name) {
 
2939
        cff_subset->family_name_utf8 = strdup (font->font_name);
 
2940
        if (cff_subset->family_name_utf8 == NULL) {
 
2941
            status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
2942
            goto fail2;
 
2943
        }
 
2944
    } else {
 
2945
        cff_subset->family_name_utf8 = NULL;
 
2946
    }
 
2947
 
 
2948
    cff_subset->widths = calloc (sizeof (double), font->scaled_font_subset->num_glyphs);
 
2949
    if (unlikely (cff_subset->widths == NULL)) {
 
2950
        status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
2951
        goto fail3;
 
2952
    }
 
2953
    for (i = 0; i < font->scaled_font_subset->num_glyphs; i++)
 
2954
        cff_subset->widths[i] = (double)font->widths[i]/font->units_per_em;
 
2955
 
 
2956
    cff_subset->x_min = (double)font->x_min/font->units_per_em;
 
2957
    cff_subset->y_min = (double)font->y_min/font->units_per_em;
 
2958
    cff_subset->x_max = (double)font->x_max/font->units_per_em;
 
2959
    cff_subset->y_max = (double)font->y_max/font->units_per_em;
 
2960
    cff_subset->ascent = (double)font->ascent/font->units_per_em;
 
2961
    cff_subset->descent = (double)font->descent/font->units_per_em;
 
2962
 
 
2963
    cff_subset->data = malloc (length);
 
2964
    if (unlikely (cff_subset->data == NULL)) {
 
2965
        status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
2966
        goto fail4;
 
2967
    }
 
2968
 
 
2969
    memcpy (cff_subset->data, data, length);
 
2970
    cff_subset->data_length = length;
 
2971
 
 
2972
    cairo_cff_font_destroy (font);
 
2973
 
 
2974
    return CAIRO_STATUS_SUCCESS;
 
2975
 
 
2976
 fail4:
 
2977
    free (cff_subset->widths);
 
2978
 fail3:
 
2979
    free (cff_subset->family_name_utf8);
 
2980
 fail2:
 
2981
    free (cff_subset->ps_name);
 
2982
 fail1:
 
2983
    cairo_cff_font_destroy (font);
 
2984
 
 
2985
    return status;
 
2986
}
 
2987
 
 
2988
void
 
2989
_cairo_cff_subset_fini (cairo_cff_subset_t *subset)
 
2990
{
 
2991
    free (subset->ps_name);
 
2992
    free (subset->family_name_utf8);
 
2993
    free (subset->widths);
 
2994
    free (subset->data);
 
2995
}
 
2996
 
 
2997
cairo_bool_t
 
2998
_cairo_cff_scaled_font_is_cid_cff (cairo_scaled_font_t *scaled_font)
 
2999
{
 
3000
    const cairo_scaled_font_backend_t *backend;
 
3001
    cairo_int_status_t status;
 
3002
    unsigned char *data;
 
3003
    unsigned long data_length;
 
3004
    unsigned char *current_ptr;
 
3005
    unsigned char *data_end;
 
3006
    cff_header_t  *header;
 
3007
    cff_index_element_t *element;
 
3008
    cairo_hash_table_t  *top_dict;
 
3009
    cairo_array_t index;
 
3010
    int size;
 
3011
    cairo_bool_t is_cid = FALSE;
 
3012
 
 
3013
    backend = scaled_font->backend;
 
3014
    data = NULL;
 
3015
    data_length = 0;
 
3016
    status = CAIRO_INT_STATUS_UNSUPPORTED;
 
3017
    /* Try to load an OpenType/CFF font */
 
3018
    if (backend->load_truetype_table &&
 
3019
        (status = backend->load_truetype_table (scaled_font, TT_TAG_CFF,
 
3020
                                                0, NULL, &data_length)) == CAIRO_INT_STATUS_SUCCESS)
 
3021
    {
 
3022
        data = malloc (data_length);
 
3023
        if (unlikely (data == NULL)) {
 
3024
            status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
3025
            return FALSE;
 
3026
        }
 
3027
 
 
3028
        status = backend->load_truetype_table (scaled_font, TT_TAG_CFF,
 
3029
                                           0, data, &data_length);
 
3030
        if (unlikely (status))
 
3031
            goto fail1;
 
3032
    }
 
3033
    /* Try to load a CFF font */
 
3034
    if (status == CAIRO_INT_STATUS_UNSUPPORTED &&
 
3035
        backend->load_type1_data &&
 
3036
        (status = backend->load_type1_data (scaled_font,
 
3037
                                            0, NULL, &data_length)) == CAIRO_INT_STATUS_SUCCESS)
 
3038
    {
 
3039
        data = malloc (data_length);
 
3040
        if (unlikely (data == NULL)) {
 
3041
            status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
3042
            return FALSE;
 
3043
        }
 
3044
 
 
3045
        status = backend->load_type1_data (scaled_font, 0, data, &data_length);
 
3046
        if (unlikely (status))
 
3047
            goto fail1;
 
3048
    }
 
3049
    if (status)
 
3050
        goto fail1;
 
3051
 
 
3052
    /* Check if it looks like a CFF font */
 
3053
    if (!check_fontdata_is_cff (data, data_length))
 
3054
        goto fail1;
 
3055
 
 
3056
    data_end = data + data_length;
 
3057
 
 
3058
    /* skip header */
 
3059
    if (data_length < sizeof (cff_header_t))
 
3060
        goto fail1;
 
3061
 
 
3062
    header = (cff_header_t *) data;
 
3063
    current_ptr = data + header->header_size;
 
3064
 
 
3065
    /* skip name */
 
3066
    cff_index_init (&index);
 
3067
    status = cff_index_read (&index, &current_ptr, data_end);
 
3068
    cff_index_fini (&index);
 
3069
 
 
3070
    if (status)
 
3071
        goto fail1;
 
3072
 
 
3073
    /* read top dict */
 
3074
    cff_index_init (&index);
 
3075
    status = cff_index_read (&index, &current_ptr, data_end);
 
3076
    if (unlikely (status))
 
3077
        goto fail2;
 
3078
 
 
3079
    status = cff_dict_init (&top_dict);
 
3080
    if (unlikely (status))
 
3081
        goto fail2;
 
3082
 
 
3083
    element = _cairo_array_index (&index, 0);
 
3084
    status = cff_dict_read (top_dict, element->data, element->length);
 
3085
    if (unlikely (status))
 
3086
        goto fail3;
 
3087
 
 
3088
    /* check for ROS operator indicating a CID font */
 
3089
    if (cff_dict_get_operands (top_dict, ROS_OP, &size) != NULL)
 
3090
        is_cid = TRUE;
 
3091
 
 
3092
fail3:
 
3093
    cff_dict_fini (top_dict);
 
3094
 
 
3095
fail2:
 
3096
    cff_index_fini (&index);
 
3097
 
 
3098
fail1:
 
3099
    free (data);
 
3100
 
 
3101
    return is_cid;
 
3102
}
 
3103
 
 
3104
static cairo_int_status_t
 
3105
_cairo_cff_font_fallback_create (cairo_scaled_font_subset_t  *scaled_font_subset,
 
3106
                                 cairo_cff_font_t           **font_return,
 
3107
                                 const char                  *subset_name)
 
3108
{
 
3109
    cairo_status_t status;
 
3110
    cairo_cff_font_t *font;
 
3111
 
 
3112
    font = malloc (sizeof (cairo_cff_font_t));
 
3113
    if (unlikely (font == NULL))
 
3114
        return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
3115
 
 
3116
    font->backend = NULL;
 
3117
    font->scaled_font_subset = scaled_font_subset;
 
3118
 
 
3119
    _cairo_array_init (&font->output, sizeof (char));
 
3120
    status = _cairo_array_grow_by (&font->output, 4096);
 
3121
    if (unlikely (status))
 
3122
        goto fail1;
 
3123
 
 
3124
    font->subset_font_name = strdup (subset_name);
 
3125
    if (unlikely (font->subset_font_name == NULL)) {
 
3126
        status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
3127
        goto fail1;
 
3128
    }
 
3129
 
 
3130
    font->ps_name = strdup (subset_name);
 
3131
    if (unlikely (font->ps_name == NULL)) {
 
3132
        status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
3133
        goto fail2;
 
3134
    }
 
3135
    font->font_name = NULL;
 
3136
 
 
3137
    font->x_min = 0;
 
3138
    font->y_min = 0;
 
3139
    font->x_max = 0;
 
3140
    font->y_max = 0;
 
3141
    font->ascent = 0;
 
3142
    font->descent = 0;
 
3143
 
 
3144
    font->widths = calloc (font->scaled_font_subset->num_glyphs, sizeof (int));
 
3145
    if (unlikely (font->widths == NULL)) {
 
3146
        status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
3147
        goto fail3;
 
3148
    }
 
3149
 
 
3150
    font->data_length = 0;
 
3151
    font->data = NULL;
 
3152
    font->data_end = NULL;
 
3153
 
 
3154
    status = cff_dict_init (&font->top_dict);
 
3155
    if (unlikely (status))
 
3156
        goto fail4;
 
3157
 
 
3158
    status = cff_dict_init (&font->private_dict);
 
3159
    if (unlikely (status))
 
3160
        goto fail5;
 
3161
 
 
3162
    cff_index_init (&font->strings_index);
 
3163
    cff_index_init (&font->charstrings_index);
 
3164
    cff_index_init (&font->global_sub_index);
 
3165
    cff_index_init (&font->local_sub_index);
 
3166
    cff_index_init (&font->charstrings_subset_index);
 
3167
    cff_index_init (&font->strings_subset_index);
 
3168
    font->global_subs_used = NULL;
 
3169
    font->local_subs_used = NULL;
 
3170
    font->fdselect = NULL;
 
3171
    font->fd_dict = NULL;
 
3172
    font->fd_private_dict = NULL;
 
3173
    font->fd_local_sub_index = NULL;
 
3174
    font->fdselect_subset = NULL;
 
3175
    font->fd_subset_map = NULL;
 
3176
    font->private_dict_offset = NULL;
 
3177
 
 
3178
    *font_return = font;
 
3179
 
 
3180
    return CAIRO_STATUS_SUCCESS;
 
3181
 
 
3182
fail5:
 
3183
    _cairo_hash_table_destroy (font->top_dict);
 
3184
fail4:
 
3185
    free (font->widths);
 
3186
fail3:
 
3187
    free (font->font_name);
 
3188
    free (font->ps_name);
 
3189
fail2:
 
3190
    free (font->subset_font_name);
 
3191
fail1:
 
3192
    _cairo_array_fini (&font->output);
 
3193
    free (font);
 
3194
    return status;
 
3195
}
 
3196
 
 
3197
static cairo_int_status_t
 
3198
cairo_cff_font_fallback_generate (cairo_cff_font_t           *font,
 
3199
                                  cairo_type2_charstrings_t  *type2_subset,
 
3200
                                  const char                **data,
 
3201
                                  unsigned long              *length)
 
3202
{
 
3203
    cairo_int_status_t status;
 
3204
    cff_header_t header;
 
3205
    cairo_array_t *charstring;
 
3206
    unsigned char buf[40];
 
3207
    unsigned char *end_buf, *end_buf2;
 
3208
    unsigned int i;
 
3209
    int sid;
 
3210
 
 
3211
    /* Create header */
 
3212
    header.major = 1;
 
3213
    header.minor = 0;
 
3214
    header.header_size = 4;
 
3215
    header.offset_size = 4;
 
3216
    font->header = &header;
 
3217
 
 
3218
    /* Create Top Dict */
 
3219
    font->is_cid = FALSE;
 
3220
 
 
3221
    snprintf((char*)buf, sizeof(buf), "CairoFont-%u-%u",
 
3222
             font->scaled_font_subset->font_id,
 
3223
             font->scaled_font_subset->subset_id);
 
3224
    sid = NUM_STD_STRINGS + _cairo_array_num_elements (&font->strings_subset_index);
 
3225
    status = cff_index_append_copy (&font->strings_subset_index,
 
3226
                                    (unsigned char *)buf,
 
3227
                                    strlen((char*)buf));
 
3228
    if (unlikely (status))
 
3229
        return status;
 
3230
 
 
3231
    end_buf = encode_integer (buf, sid);
 
3232
    status = cff_dict_set_operands (font->top_dict, FULLNAME_OP,
 
3233
                                    buf, end_buf - buf);
 
3234
    if (unlikely (status))
 
3235
        return status;
 
3236
 
 
3237
    status = cff_dict_set_operands (font->top_dict, FAMILYNAME_OP,
 
3238
                                    buf, end_buf - buf);
 
3239
    if (unlikely (status))
 
3240
        return status;
 
3241
 
 
3242
    end_buf = encode_integer (buf, type2_subset->x_min);
 
3243
    end_buf = encode_integer (end_buf, type2_subset->y_min);
 
3244
    end_buf = encode_integer (end_buf, type2_subset->x_max);
 
3245
    end_buf = encode_integer (end_buf, type2_subset->y_max);
 
3246
    status = cff_dict_set_operands (font->top_dict,
 
3247
                                    FONTBBOX_OP, buf, end_buf - buf);
 
3248
    if (unlikely (status))
 
3249
        return status;
 
3250
 
 
3251
    end_buf = encode_integer_max (buf, 0);
 
3252
    status = cff_dict_set_operands (font->top_dict,
 
3253
                                    CHARSTRINGS_OP, buf, end_buf - buf);
 
3254
    if (unlikely (status))
 
3255
        return status;
 
3256
 
 
3257
 
 
3258
    if (font->scaled_font_subset->is_latin) {
 
3259
        status = cff_dict_set_operands (font->top_dict,
 
3260
                                        ENCODING_OP, buf, end_buf - buf);
 
3261
        if (unlikely (status))
 
3262
            return status;
 
3263
 
 
3264
        /* Private has two operands - size and offset */
 
3265
        end_buf2 = encode_integer_max (end_buf, 0);
 
3266
        cff_dict_set_operands (font->top_dict, PRIVATE_OP, buf, end_buf2 - buf);
 
3267
        if (unlikely (status))
 
3268
            return status;
 
3269
 
 
3270
    } else {
 
3271
        status = cff_dict_set_operands (font->top_dict,
 
3272
                                        FDSELECT_OP, buf, end_buf - buf);
 
3273
        if (unlikely (status))
 
3274
            return status;
 
3275
 
 
3276
        status = cff_dict_set_operands (font->top_dict,
 
3277
                                        FDARRAY_OP, buf, end_buf - buf);
 
3278
        if (unlikely (status))
 
3279
            return status;
 
3280
    }
 
3281
 
 
3282
    status = cff_dict_set_operands (font->top_dict,
 
3283
                                    CHARSET_OP, buf, end_buf - buf);
 
3284
    if (unlikely (status))
 
3285
        return status;
 
3286
 
 
3287
    if (!font->scaled_font_subset->is_latin) {
 
3288
        status = cairo_cff_font_set_ros_strings (font);
 
3289
        if (unlikely (status))
 
3290
            return status;
 
3291
 
 
3292
        /* Create CID FD dictionary */
 
3293
        status = cairo_cff_font_create_cid_fontdict (font);
 
3294
        if (unlikely (status))
 
3295
            return status;
 
3296
    } else {
 
3297
        font->private_dict_offset = malloc (sizeof (int));
 
3298
        if (unlikely (font->private_dict_offset == NULL))
 
3299
            return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
3300
    }
 
3301
 
 
3302
    /* Create charstrings */
 
3303
    for (i = 0; i < font->scaled_font_subset->num_glyphs; i++) {
 
3304
        charstring = _cairo_array_index(&type2_subset->charstrings, i);
 
3305
 
 
3306
        status = cff_index_append (&font->charstrings_subset_index,
 
3307
                                   _cairo_array_index (charstring, 0),
 
3308
                                   _cairo_array_num_elements (charstring));
 
3309
 
 
3310
        if (unlikely (status))
 
3311
            return status;
 
3312
    }
 
3313
 
 
3314
    if (font->scaled_font_subset->is_latin)
 
3315
        status = cairo_cff_font_add_euro_charset_string (font);
 
3316
 
 
3317
    status = cairo_cff_font_write_subset (font);
 
3318
    if (unlikely (status))
 
3319
        return status;
 
3320
 
 
3321
    *data = _cairo_array_index (&font->output, 0);
 
3322
    *length = _cairo_array_num_elements (&font->output);
 
3323
 
 
3324
    return CAIRO_STATUS_SUCCESS;
 
3325
}
 
3326
 
 
3327
cairo_status_t
 
3328
_cairo_cff_fallback_init (cairo_cff_subset_t          *cff_subset,
 
3329
                          const char                  *subset_name,
 
3330
                          cairo_scaled_font_subset_t  *font_subset)
 
3331
{
 
3332
    cairo_cff_font_t *font = NULL; /* squelch bogus compiler warning */
 
3333
    cairo_status_t status;
 
3334
    const char *data = NULL; /* squelch bogus compiler warning */
 
3335
    unsigned long length = 0; /* squelch bogus compiler warning */
 
3336
    unsigned int i;
 
3337
    cairo_type2_charstrings_t type2_subset;
 
3338
 
 
3339
    status = _cairo_cff_font_fallback_create (font_subset, &font, subset_name);
 
3340
    if (unlikely (status))
 
3341
        return status;
 
3342
 
 
3343
    status = _cairo_type2_charstrings_init (&type2_subset, font_subset);
 
3344
    if (unlikely (status))
 
3345
        goto fail1;
 
3346
 
 
3347
    status = cairo_cff_font_fallback_generate (font, &type2_subset, &data, &length);
 
3348
    if (unlikely (status))
 
3349
        goto fail2;
 
3350
 
 
3351
    cff_subset->family_name_utf8 = NULL;
 
3352
    cff_subset->ps_name = strdup (font->ps_name);
 
3353
    if (unlikely (cff_subset->ps_name == NULL)) {
 
3354
        status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
3355
        goto fail2;
 
3356
    }
 
3357
 
 
3358
    cff_subset->widths = calloc (sizeof (double), font->scaled_font_subset->num_glyphs);
 
3359
    if (unlikely (cff_subset->widths == NULL)) {
 
3360
        status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
3361
        goto fail3;
 
3362
    }
 
3363
 
 
3364
    for (i = 0; i < font->scaled_font_subset->num_glyphs; i++)
 
3365
        cff_subset->widths[i] = (double)type2_subset.widths[i]/1000;
 
3366
 
 
3367
    cff_subset->x_min = (double)type2_subset.x_min/1000;
 
3368
    cff_subset->y_min = (double)type2_subset.y_min/1000;
 
3369
    cff_subset->x_max = (double)type2_subset.x_max/1000;
 
3370
    cff_subset->y_max = (double)type2_subset.y_max/1000;
 
3371
    cff_subset->ascent = (double)type2_subset.y_max/1000;
 
3372
    cff_subset->descent = (double)type2_subset.y_min/1000;
 
3373
 
 
3374
    cff_subset->data = malloc (length);
 
3375
    if (unlikely (cff_subset->data == NULL)) {
 
3376
        status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
3377
        goto fail4;
 
3378
    }
 
3379
 
 
3380
    memcpy (cff_subset->data, data, length);
 
3381
    cff_subset->data_length = length;
 
3382
 
 
3383
    _cairo_type2_charstrings_fini (&type2_subset);
 
3384
    cairo_cff_font_destroy (font);
 
3385
 
 
3386
    return CAIRO_STATUS_SUCCESS;
 
3387
 
 
3388
 fail4:
 
3389
    free (cff_subset->widths);
 
3390
 fail3:
 
3391
    free (cff_subset->ps_name);
 
3392
 fail2:
 
3393
    _cairo_type2_charstrings_fini (&type2_subset);
 
3394
 fail1:
 
3395
    cairo_cff_font_destroy (font);
 
3396
 
 
3397
    return status;
 
3398
}
 
3399
 
 
3400
void
 
3401
_cairo_cff_fallback_fini (cairo_cff_subset_t *subset)
 
3402
{
 
3403
    free (subset->ps_name);
 
3404
    free (subset->widths);
 
3405
    free (subset->data);
 
3406
}
 
3407
 
 
3408
#endif /* CAIRO_HAS_FONT_SUBSET */