Coverage Report

Created: 2025-07-12 07:23

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