Coverage Report

Created: 2025-11-16 09:57

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