Coverage Report

Created: 2026-09-28 10:59

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