Coverage Report

Created: 2025-07-07 10:01

/work/workdir/UnpackedTarball/cairo/src/cairo-cff-subset.c
Line
Count
Source (jump to first uncovered line)
1
/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
2
/* cairo - a vector graphics library with display and print output
3
 *
4
 * Copyright © 2006 Adrian Johnson
5
 *
6
 * This library is free software; you can redistribute it and/or
7
 * modify it either under the terms of the GNU Lesser General Public
8
 * License version 2.1 as published by the Free Software Foundation
9
 * (the "LGPL") or, at your option, under the terms of the Mozilla
10
 * Public License Version 1.1 (the "MPL"). If you do not alter this
11
 * notice, a recipient may use your version of this file under either
12
 * the MPL or the LGPL.
13
 *
14
 * You should have received a copy of the LGPL along with this library
15
 * in the file COPYING-LGPL-2.1; if not, write to the Free Software
16
 * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
17
 * You should have received a copy of the MPL along with this library
18
 * in the file COPYING-MPL-1.1
19
 *
20
 * The contents of this file are subject to the Mozilla Public License
21
 * Version 1.1 (the "License"); you may not use this file except in
22
 * compliance with the License. You may obtain a copy of the License at
23
 * http://www.mozilla.org/MPL/
24
 *
25
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
26
 * OF ANY KIND, either express or implied. See the LGPL or the MPL for
27
 * the specific language governing rights and limitations.
28
 *
29
 * The Original Code is the cairo graphics library.
30
 *
31
 * The Initial Developer of the Original Code is Adrian Johnson.
32
 *
33
 * Contributor(s):
34
 *  Adrian Johnson <ajohnson@redneon.com>
35
 *      Eugeniy Meshcheryakov <eugen@debian.org>
36
 */
37
38
/*
39
 * Useful links:
40
 * http://www.adobe.com/content/dam/Adobe/en/devnet/font/pdfs/5176.CFF.pdf
41
 * http://www.adobe.com/content/dam/Adobe/en/devnet/font/pdfs/5177.Type2.pdf
42
 */
43
44
#define _DEFAULT_SOURCE /* for snprintf(), strdup() */
45
#include "cairoint.h"
46
47
#include "cairo-array-private.h"
48
#include "cairo-error-private.h"
49
50
#if CAIRO_HAS_FONT_SUBSET
51
52
#include "cairo-scaled-font-subsets-private.h"
53
#include "cairo-truetype-subset-private.h"
54
#include <string.h>
55
#include <locale.h>
56
57
/* CFF Dict Operators. If the high byte is 0 the command is encoded
58
 * with a single byte. */
59
#define BASEFONTNAME_OP     0x0c16
60
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 unsigned long
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, start, i;
416
0
    int 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)
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)
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_malloc (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 (!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
0
        font->ps_name = _cairo_malloc (len + 1);
894
0
        if (unlikely (font->ps_name == NULL))
895
0
            return _cairo_error (CAIRO_STATUS_NO_MEMORY);
896
897
0
        memcpy (font->ps_name, p, len);
898
0
        font->ps_name[len] = 0;
899
900
0
        status = _cairo_escape_ps_name (&font->ps_name);
901
0
    }
902
0
    cff_index_fini (&index);
903
904
0
    return status;
905
0
}
906
907
static cairo_int_status_t
908
cairo_cff_font_read_private_dict (cairo_cff_font_t   *font,
909
                                  cairo_hash_table_t *private_dict,
910
                                  cairo_array_t      *local_sub_index,
911
                                  int                *local_sub_bias,
912
                                  cairo_bool_t      **local_subs_used,
913
                                  double             *default_width,
914
                                  double             *nominal_width,
915
                                  unsigned char      *ptr,
916
                                  int                 size)
917
0
{
918
0
    cairo_int_status_t status;
919
0
    unsigned char buf[10];
920
0
    unsigned char *end_buf;
921
0
    int offset;
922
0
    int i;
923
0
    unsigned char *operand;
924
0
    unsigned char *p;
925
0
    int num_subs;
926
927
0
    status = cff_dict_read (private_dict, ptr, size);
928
0
    if (unlikely (status))
929
0
  return status;
930
931
0
    operand = cff_dict_get_operands (private_dict, LOCAL_SUB_OP, &i);
932
0
    if (operand) {
933
0
        decode_integer (operand, &offset);
934
0
        p = ptr + offset;
935
0
        status = cff_index_read (local_sub_index, &p, font->data_end);
936
0
  if (unlikely (status))
937
0
      return status;
938
939
  /* Use maximum sized encoding to reserve space for later modification. */
940
0
  end_buf = encode_integer_max (buf, 0);
941
0
  status = cff_dict_set_operands (private_dict, LOCAL_SUB_OP, buf, end_buf - buf);
942
0
  if (unlikely (status))
943
0
      return status;
944
0
    }
945
946
0
    *default_width = 0;
947
0
    operand = cff_dict_get_operands (private_dict, DEFAULTWIDTH_OP, &i);
948
0
    if (operand)
949
0
        decode_number (operand, default_width);
950
951
0
    *nominal_width = 0;
952
0
    operand = cff_dict_get_operands (private_dict, NOMINALWIDTH_OP, &i);
953
0
    if (operand)
954
0
   decode_number (operand, nominal_width);
955
956
0
    num_subs = _cairo_array_num_elements (local_sub_index);
957
0
    *local_subs_used = calloc (num_subs, sizeof (cairo_bool_t));
958
0
    if (unlikely (*local_subs_used == NULL))
959
0
  return _cairo_error (CAIRO_STATUS_NO_MEMORY);
960
961
0
    if (num_subs < 1240)
962
0
  *local_sub_bias = 107;
963
0
    else if (num_subs < 33900)
964
0
  *local_sub_bias = 1131;
965
0
    else
966
0
  *local_sub_bias = 32768;
967
968
0
    return CAIRO_STATUS_SUCCESS;
969
0
}
970
971
static cairo_int_status_t
972
cairo_cff_font_read_fdselect (cairo_cff_font_t *font, unsigned char *p)
973
0
{
974
0
    int type, num_ranges, first, last, fd, i, j;
975
976
0
    font->fdselect = calloc (font->num_glyphs, sizeof (int));
977
0
    if (unlikely (font->fdselect == NULL))
978
0
  return _cairo_error (CAIRO_STATUS_NO_MEMORY);
979
980
0
    type = *p++;
981
0
    if (type == 0)
982
0
    {
983
0
        for (i = 0; i < font->num_glyphs; i++)
984
0
            font->fdselect[i] = *p++;
985
0
    } else if (type == 3) {
986
0
        num_ranges = get_unaligned_be16 (p);
987
0
        p += 2;
988
0
        for  (i = 0; i < num_ranges; i++)
989
0
        {
990
0
            first = get_unaligned_be16 (p);
991
0
            p += 2;
992
0
            fd = *p++;
993
0
            last = get_unaligned_be16 (p);
994
0
            if (last > font->num_glyphs)
995
0
                return CAIRO_INT_STATUS_UNSUPPORTED;
996
0
            for (j = first; j < last; j++)
997
0
                font->fdselect[j] = fd;
998
0
        }
999
0
    } else {
1000
0
        return CAIRO_INT_STATUS_UNSUPPORTED;
1001
0
    }
1002
1003
0
    return CAIRO_STATUS_SUCCESS;
1004
0
}
1005
1006
static cairo_int_status_t
1007
cairo_cff_font_read_cid_fontdict (cairo_cff_font_t *font, unsigned char *ptr)
1008
0
{
1009
0
    cairo_array_t index;
1010
0
    cff_index_element_t *element;
1011
0
    unsigned int i;
1012
0
    int size;
1013
0
    unsigned char *operand;
1014
0
    int offset;
1015
0
    cairo_int_status_t status;
1016
0
    unsigned char buf[100];
1017
0
    unsigned char *end_buf;
1018
1019
0
    cff_index_init (&index);
1020
0
    status = cff_index_read (&index, &ptr, font->data_end);
1021
0
    if (unlikely (status))
1022
0
        goto fail;
1023
1024
0
    font->num_fontdicts = _cairo_array_num_elements (&index);
1025
1026
0
    font->fd_dict = calloc (sizeof (cairo_hash_table_t *), font->num_fontdicts);
1027
0
    if (unlikely (font->fd_dict == NULL)) {
1028
0
        status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
1029
0
        goto fail;
1030
0
    }
1031
1032
0
    font->fd_private_dict = calloc (sizeof (cairo_hash_table_t *), font->num_fontdicts);
1033
0
    if (unlikely (font->fd_private_dict == NULL)) {
1034
0
        status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
1035
0
        goto fail;
1036
0
    }
1037
1038
0
    font->fd_local_sub_index = calloc (sizeof (cairo_array_t), font->num_fontdicts);
1039
0
    if (unlikely (font->fd_local_sub_index == NULL)) {
1040
0
        status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
1041
0
        goto fail;
1042
0
    }
1043
1044
0
    font->fd_local_sub_bias = calloc (sizeof (int), font->num_fontdicts);
1045
0
    if (unlikely (font->fd_local_sub_bias == NULL)) {
1046
0
        status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
1047
0
        goto fail;
1048
0
    }
1049
1050
0
    font->fd_local_subs_used = calloc (sizeof (cairo_bool_t *), font->num_fontdicts);
1051
0
    if (unlikely (font->fd_local_subs_used == NULL)) {
1052
0
        status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
1053
0
        goto fail;
1054
0
    }
1055
1056
0
    font->fd_default_width = calloc (font->num_fontdicts, sizeof (double));
1057
0
    if (unlikely (font->fd_default_width == NULL)) {
1058
0
        status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
1059
0
        goto fail;
1060
0
    }
1061
1062
0
    font->fd_nominal_width = calloc (font->num_fontdicts, sizeof (double));
1063
0
    if (unlikely (font->fd_nominal_width == NULL)) {
1064
0
        status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
1065
0
        goto fail;
1066
0
    }
1067
1068
0
    for (i = 0; i < font->num_fontdicts; i++) {
1069
0
        status = cff_dict_init (&font->fd_dict[i]);
1070
0
        if (unlikely (status))
1071
0
            goto fail;
1072
1073
0
        element = _cairo_array_index (&index, i);
1074
0
        status = cff_dict_read (font->fd_dict[i], element->data, element->length);
1075
0
        if (unlikely (status))
1076
0
            goto fail;
1077
1078
0
        operand = cff_dict_get_operands (font->fd_dict[i], PRIVATE_OP, &size);
1079
0
        if (operand == NULL) {
1080
0
            status = CAIRO_INT_STATUS_UNSUPPORTED;
1081
0
            goto fail;
1082
0
        }
1083
0
        operand = decode_integer (operand, &size);
1084
0
        decode_integer (operand, &offset);
1085
0
        status = cff_dict_init (&font->fd_private_dict[i]);
1086
0
  if (unlikely (status))
1087
0
            goto fail;
1088
1089
0
        cff_index_init (&font->fd_local_sub_index[i]);
1090
0
        status = cairo_cff_font_read_private_dict (font,
1091
0
                                                   font->fd_private_dict[i],
1092
0
                                                   &font->fd_local_sub_index[i],
1093
0
                                                   &font->fd_local_sub_bias[i],
1094
0
                                                   &font->fd_local_subs_used[i],
1095
0
                                                   &font->fd_default_width[i],
1096
0
                                                   &font->fd_nominal_width[i],
1097
0
                                                   font->data + offset,
1098
0
                                                   size);
1099
0
        if (unlikely (status))
1100
0
            goto fail;
1101
1102
  /* Set integer operand to max value to use max size encoding to reserve
1103
         * space for any value later */
1104
0
        end_buf = encode_integer_max (buf, 0);
1105
0
        end_buf = encode_integer_max (end_buf, 0);
1106
0
        status = cff_dict_set_operands (font->fd_dict[i], PRIVATE_OP, buf, end_buf - buf);
1107
0
        if (unlikely (status))
1108
0
            goto fail;
1109
0
    }
1110
1111
0
    status = CAIRO_STATUS_SUCCESS;
1112
1113
0
fail:
1114
0
    cff_index_fini (&index);
1115
1116
0
    return status;
1117
0
}
1118
1119
static void
1120
cairo_cff_font_read_font_metrics (cairo_cff_font_t *font, cairo_hash_table_t  *top_dict)
1121
0
{
1122
0
    unsigned char *p;
1123
0
    unsigned char *end;
1124
0
    int size;
1125
0
    double x_min, y_min, x_max, y_max;
1126
0
    double xx, yx, xy, yy;
1127
1128
0
    x_min = 0.0;
1129
0
    y_min = 0.0;
1130
0
    x_max = 0.0;
1131
0
    y_max = 0.0;
1132
0
    p = cff_dict_get_operands (font->top_dict, FONTBBOX_OP, &size);
1133
0
    if (p) {
1134
0
        end = p + size;
1135
0
        if (p < end)
1136
0
            p = decode_number (p, &x_min);
1137
0
        if (p < end)
1138
0
            p = decode_number (p, &y_min);
1139
0
        if (p < end)
1140
0
            p = decode_number (p, &x_max);
1141
0
        if (p < end)
1142
0
            p = decode_number (p, &y_max);
1143
0
    }
1144
0
    font->x_min = floor (x_min);
1145
0
    font->y_min = floor (y_min);
1146
0
    font->x_max = floor (x_max);
1147
0
    font->y_max = floor (y_max);
1148
0
    font->ascent = font->y_max;
1149
0
    font->descent = font->y_min;
1150
1151
0
    xx = 0.001;
1152
0
    yx = 0.0;
1153
0
    xy = 0.0;
1154
0
    yy = 0.001;
1155
0
    p = cff_dict_get_operands (font->top_dict, FONTMATRIX_OP, &size);
1156
0
    if (p) {
1157
0
        end = p + size;
1158
0
        if (p < end)
1159
0
            p = decode_number (p, &xx);
1160
0
        if (p < end)
1161
0
            p = decode_number (p, &yx);
1162
0
        if (p < end)
1163
0
            p = decode_number (p, &xy);
1164
0
        if (p < end)
1165
0
            p = decode_number (p, &yy);
1166
0
    }
1167
    /* Freetype uses 1/abs(yy) to get units per EM */
1168
0
    font->units_per_em = _cairo_round(1.0/fabs(yy));
1169
0
}
1170
1171
static cairo_int_status_t
1172
cairo_cff_font_read_top_dict (cairo_cff_font_t *font)
1173
0
{
1174
0
    cairo_array_t index;
1175
0
    cff_index_element_t *element;
1176
0
    unsigned char buf[20];
1177
0
    unsigned char *end_buf;
1178
0
    unsigned char *operand;
1179
0
    cairo_int_status_t status;
1180
0
    unsigned char *p;
1181
0
    int size;
1182
0
    int offset;
1183
1184
0
    cff_index_init (&index);
1185
0
    status = cff_index_read (&index, &font->current_ptr, font->data_end);
1186
0
    if (unlikely (status))
1187
0
        goto fail;
1188
1189
0
    element = _cairo_array_index (&index, 0);
1190
0
    status = cff_dict_read (font->top_dict, element->data, element->length);
1191
0
    if (unlikely (status))
1192
0
        goto fail;
1193
1194
0
    if (cff_dict_get_operands (font->top_dict, ROS_OP, &size) != NULL)
1195
0
        font->is_cid = TRUE;
1196
0
    else
1197
0
        font->is_cid = FALSE;
1198
1199
0
    operand = cff_dict_get_operands (font->top_dict, CHARSTRINGS_OP, &size);
1200
0
    decode_integer (operand, &offset);
1201
0
    p = font->data + offset;
1202
0
    status = cff_index_read (&font->charstrings_index, &p, font->data_end);
1203
0
    if (unlikely (status))
1204
0
        goto fail;
1205
0
    font->num_glyphs = _cairo_array_num_elements (&font->charstrings_index);
1206
1207
0
    if (font->is_cid) {
1208
0
   operand = cff_dict_get_operands (font->top_dict, CHARSET_OP, &size);
1209
0
   if (!operand)
1210
0
        return CAIRO_INT_STATUS_UNSUPPORTED;
1211
1212
0
   decode_integer (operand, &offset);
1213
0
   font->charset = font->data + offset;
1214
0
   if (font->charset >= font->data_end)
1215
0
        return CAIRO_INT_STATUS_UNSUPPORTED;
1216
0
    }
1217
1218
0
    if (!font->is_opentype)
1219
0
        cairo_cff_font_read_font_metrics (font, font->top_dict);
1220
1221
0
    if (font->is_cid) {
1222
0
        operand = cff_dict_get_operands (font->top_dict, FDSELECT_OP, &size);
1223
0
        decode_integer (operand, &offset);
1224
0
        status = cairo_cff_font_read_fdselect (font, font->data + offset);
1225
0
  if (unlikely (status))
1226
0
      goto fail;
1227
1228
0
        operand = cff_dict_get_operands (font->top_dict, FDARRAY_OP, &size);
1229
0
        decode_integer (operand, &offset);
1230
0
        status = cairo_cff_font_read_cid_fontdict (font, font->data + offset);
1231
0
  if (unlikely (status))
1232
0
      goto fail;
1233
0
    } else {
1234
0
        operand = cff_dict_get_operands (font->top_dict, PRIVATE_OP, &size);
1235
0
        operand = decode_integer (operand, &size);
1236
0
        decode_integer (operand, &offset);
1237
0
  status = cairo_cff_font_read_private_dict (font,
1238
0
                                                   font->private_dict,
1239
0
               &font->local_sub_index,
1240
0
               &font->local_sub_bias,
1241
0
               &font->local_subs_used,
1242
0
                                                   &font->default_width,
1243
0
                                                   &font->nominal_width,
1244
0
               font->data + offset,
1245
0
               size);
1246
0
  if (unlikely (status))
1247
0
      goto fail;
1248
0
    }
1249
1250
    /* Use maximum sized encoding to reserve space for later modification. */
1251
0
    end_buf = encode_integer_max (buf, 0);
1252
0
    status = cff_dict_set_operands (font->top_dict,
1253
0
                              CHARSTRINGS_OP, buf, end_buf - buf);
1254
0
    if (unlikely (status))
1255
0
  goto fail;
1256
1257
0
    status = cff_dict_set_operands (font->top_dict,
1258
0
                              CHARSET_OP, buf, end_buf - buf);
1259
0
    if (unlikely (status))
1260
0
  goto fail;
1261
1262
0
    if (font->scaled_font_subset->is_latin) {
1263
0
        status = cff_dict_set_operands (font->top_dict,
1264
0
                                        ENCODING_OP, buf, end_buf - buf);
1265
0
        if (unlikely (status))
1266
0
            goto fail;
1267
1268
  /* Private has two operands - size and offset */
1269
0
  end_buf = encode_integer_max (end_buf, 0);
1270
0
  cff_dict_set_operands (font->top_dict, PRIVATE_OP, buf, end_buf - buf);
1271
0
        if (unlikely (status))
1272
0
            goto fail;
1273
1274
0
    } else {
1275
0
        status = cff_dict_set_operands (font->top_dict,
1276
0
                                        FDSELECT_OP, buf, end_buf - buf);
1277
0
        if (unlikely (status))
1278
0
            goto fail;
1279
1280
0
        status = cff_dict_set_operands (font->top_dict,
1281
0
                                        FDARRAY_OP, buf, end_buf - buf);
1282
0
        if (unlikely (status))
1283
0
            goto fail;
1284
1285
0
        cff_dict_remove (font->top_dict, ENCODING_OP);
1286
0
        cff_dict_remove (font->top_dict, PRIVATE_OP);
1287
0
    }
1288
1289
    /* Remove the unique identifier operators as the subsetted font is
1290
     * not the same is the original font. */
1291
0
    cff_dict_remove (font->top_dict, UNIQUEID_OP);
1292
0
    cff_dict_remove (font->top_dict, XUID_OP);
1293
1294
0
fail:
1295
0
    cff_index_fini (&index);
1296
1297
0
    return status;
1298
0
}
1299
1300
static cairo_int_status_t
1301
cairo_cff_font_read_strings (cairo_cff_font_t *font)
1302
0
{
1303
0
    return cff_index_read (&font->strings_index, &font->current_ptr, font->data_end);
1304
0
}
1305
1306
static cairo_int_status_t
1307
cairo_cff_font_read_global_subroutines (cairo_cff_font_t *font)
1308
0
{
1309
0
    cairo_int_status_t status;
1310
0
    int num_subs;
1311
1312
0
    status = cff_index_read (&font->global_sub_index, &font->current_ptr, font->data_end);
1313
0
    if (unlikely (status))
1314
0
  return status;
1315
1316
0
    num_subs = _cairo_array_num_elements (&font->global_sub_index);
1317
0
    font->global_subs_used = calloc (num_subs, sizeof(cairo_bool_t));
1318
0
    if (unlikely (font->global_subs_used == NULL))
1319
0
  return _cairo_error (CAIRO_STATUS_NO_MEMORY);
1320
1321
0
    if (num_subs < 1240)
1322
0
        font->global_sub_bias = 107;
1323
0
    else if (num_subs < 33900)
1324
0
        font->global_sub_bias = 1131;
1325
0
    else
1326
0
        font->global_sub_bias = 32768;
1327
1328
0
    return CAIRO_STATUS_SUCCESS;
1329
0
}
1330
1331
typedef cairo_int_status_t
1332
(*font_read_t) (cairo_cff_font_t *font);
1333
1334
static const font_read_t font_read_funcs[] = {
1335
    cairo_cff_font_read_header,
1336
    cairo_cff_font_read_name,
1337
    cairo_cff_font_read_top_dict,
1338
    cairo_cff_font_read_strings,
1339
    cairo_cff_font_read_global_subroutines,
1340
};
1341
1342
static cairo_int_status_t
1343
cairo_cff_font_read_font (cairo_cff_font_t *font)
1344
0
{
1345
0
    cairo_int_status_t status;
1346
0
    unsigned int i;
1347
1348
0
    for (i = 0; i < ARRAY_LENGTH (font_read_funcs); i++) {
1349
0
        status = font_read_funcs[i] (font);
1350
0
        if (unlikely (status))
1351
0
            return status;
1352
0
    }
1353
1354
0
    return CAIRO_STATUS_SUCCESS;
1355
0
}
1356
1357
static cairo_status_t
1358
cairo_cff_font_set_ros_strings (cairo_cff_font_t *font)
1359
0
{
1360
0
    cairo_status_t status;
1361
0
    unsigned char buf[30];
1362
0
    unsigned char *p;
1363
0
    int sid1, sid2;
1364
0
    const char *registry = "Adobe";
1365
0
    const char *ordering = "Identity";
1366
1367
0
    sid1 = NUM_STD_STRINGS + _cairo_array_num_elements (&font->strings_subset_index);
1368
0
    status = cff_index_append_copy (&font->strings_subset_index,
1369
0
                                    (unsigned char *)registry,
1370
0
                                    strlen(registry));
1371
0
    if (unlikely (status))
1372
0
  return status;
1373
1374
0
    sid2 = NUM_STD_STRINGS + _cairo_array_num_elements (&font->strings_subset_index);
1375
0
    status = cff_index_append_copy (&font->strings_subset_index,
1376
0
                                    (unsigned char *)ordering,
1377
0
            strlen(ordering));
1378
0
    if (unlikely (status))
1379
0
  return status;
1380
1381
0
    p = encode_integer (buf, sid1);
1382
0
    p = encode_integer (p, sid2);
1383
0
    p = encode_integer (p, 0);
1384
0
    status = cff_dict_set_operands (font->top_dict, ROS_OP, buf, p - buf);
1385
0
    if (unlikely (status))
1386
0
  return status;
1387
1388
0
    p = encode_integer (buf, font->scaled_font_subset->num_glyphs);
1389
0
    status = cff_dict_set_operands (font->top_dict, CIDCOUNT_OP, buf, p - buf);
1390
0
    if (unlikely (status))
1391
0
  return status;
1392
1393
0
    return CAIRO_STATUS_SUCCESS;
1394
0
}
1395
1396
static cairo_status_t
1397
cairo_cff_font_subset_dict_string(cairo_cff_font_t   *font,
1398
                                  cairo_hash_table_t *dict,
1399
                                  int                 operator)
1400
0
{
1401
0
    int size;
1402
0
    unsigned char *p;
1403
0
    int sid;
1404
0
    unsigned char buf[100];
1405
0
    cff_index_element_t *element;
1406
0
    cairo_status_t status;
1407
1408
0
    p = cff_dict_get_operands (dict, operator, &size);
1409
0
    if (!p)
1410
0
        return CAIRO_STATUS_SUCCESS;
1411
1412
0
    decode_integer (p, &sid);
1413
0
    if (sid < NUM_STD_STRINGS)
1414
0
        return CAIRO_STATUS_SUCCESS;
1415
1416
0
    element = _cairo_array_index (&font->strings_index, sid - NUM_STD_STRINGS);
1417
0
    sid = NUM_STD_STRINGS + _cairo_array_num_elements (&font->strings_subset_index);
1418
0
    status = cff_index_append (&font->strings_subset_index, element->data, element->length);
1419
0
    if (unlikely (status))
1420
0
        return status;
1421
1422
0
    p = encode_integer (buf, sid);
1423
0
    status = cff_dict_set_operands (dict, operator, buf, p - buf);
1424
0
    if (unlikely (status))
1425
0
  return status;
1426
1427
0
    return CAIRO_STATUS_SUCCESS;
1428
0
}
1429
1430
static const int dict_strings[] = {
1431
    VERSION_OP,
1432
    NOTICE_OP,
1433
    COPYRIGHT_OP,
1434
    FULLNAME_OP,
1435
    FAMILYNAME_OP,
1436
    WEIGHT_OP,
1437
    POSTSCRIPT_OP,
1438
    BASEFONTNAME_OP,
1439
    FONTNAME_OP,
1440
};
1441
1442
static cairo_status_t
1443
cairo_cff_font_subset_dict_strings (cairo_cff_font_t   *font,
1444
                                    cairo_hash_table_t *dict)
1445
0
{
1446
0
    cairo_status_t status;
1447
0
    unsigned int i;
1448
1449
0
    for (i = 0; i < ARRAY_LENGTH (dict_strings); i++) {
1450
0
        status = cairo_cff_font_subset_dict_string (font, dict, dict_strings[i]);
1451
0
        if (unlikely (status))
1452
0
            return status;
1453
0
    }
1454
1455
0
    return CAIRO_STATUS_SUCCESS;
1456
0
}
1457
1458
static unsigned char *
1459
type2_decode_integer (unsigned char *p, int *integer)
1460
0
{
1461
0
    if (*p == 28) {
1462
0
  *integer = p[1] << 8 | p[2];
1463
0
  p += 3;
1464
0
    } else if (*p <= 246) {
1465
0
        *integer = *p++ - 139;
1466
0
    } else if (*p <= 250) {
1467
0
        *integer = (p[0] - 247) * 256 + p[1] + 108;
1468
0
        p += 2;
1469
0
    } else if (*p <= 254) {
1470
0
        *integer = -(p[0] - 251) * 256 - p[1] - 108;
1471
0
        p += 2;
1472
0
    } else { /* *p == 255 */
1473
   /* 16.16 fixed-point number. The fraction is ignored. */
1474
0
   *integer = (int16_t)((p[1] << 8) | p[2]);
1475
0
        p += 5;
1476
0
    }
1477
0
    return p;
1478
0
}
1479
1480
/* Type 2 charstring parser for finding calls to local or global
1481
 * subroutines. For non Opentype CFF fonts it also gets the glyph
1482
 * widths.
1483
 *
1484
 * When we find a subroutine operator, the subroutine is marked as in
1485
 * use and recursively followed. The subroutine number is the value on
1486
 * the top of the stack when the subroutine operator is executed. In
1487
 * most fonts the subroutine number is encoded in an integer
1488
 * immediately preceding the subroutine operator. However it is
1489
 * possible for the subroutine number on the stack to be the result of
1490
 * a computation (in which case there will be an operator preceding
1491
 * the subroutine operator). If this occurs, subroutine subsetting is
1492
 * disabled since we can't easily determine which subroutines are
1493
 * used.
1494
 *
1495
 * The width, if present, is the first integer in the charstring. The
1496
 * only way to confirm if the integer at the start of the charstring is
1497
 * the width is when the first stack clearing operator is parsed,
1498
 * check if there is an extra integer left over on the stack.
1499
 *
1500
 * When the first stack clearing operator is encountered
1501
 * type2_find_width is set to FALSE and type2_found_width is set to
1502
 * TRUE if an extra argument is found, otherwise FALSE.
1503
 */
1504
static cairo_status_t
1505
cairo_cff_parse_charstring (cairo_cff_font_t *font,
1506
                            unsigned char *charstring, int length,
1507
                            int glyph_id,
1508
          cairo_bool_t need_width)
1509
0
{
1510
0
    unsigned char *p = charstring;
1511
0
    unsigned char *end = charstring + length;
1512
0
    int integer;
1513
0
    int hint_bytes;
1514
0
    int sub_num;
1515
0
    cff_index_element_t *element;
1516
0
    int fd;
1517
1518
0
    while (p < end) {
1519
0
        if (*p == 28 || *p >= 32) {
1520
            /* Integer value */
1521
0
            p = type2_decode_integer (p, &integer);
1522
0
            font->type2_stack_size++;
1523
0
            font->type2_stack_top_value = integer;
1524
0
            font->type2_stack_top_is_int = TRUE;
1525
0
      if (!font->type2_seen_first_int) {
1526
0
    font->type2_width = integer;
1527
0
    font->type2_seen_first_int = TRUE;
1528
0
      }
1529
0
  } else if (*p == TYPE2_hstem || *p == TYPE2_vstem ||
1530
0
       *p == TYPE2_hstemhm || *p == TYPE2_vstemhm) {
1531
            /* Hint operator. The number of hints declared by the
1532
             * operator depends on the size of the stack. */
1533
0
      font->type2_stack_top_is_int = FALSE;
1534
0
      font->type2_num_hints += font->type2_stack_size/2;
1535
0
      if (font->type2_find_width && font->type2_stack_size % 2)
1536
0
    font->type2_found_width = TRUE;
1537
1538
0
      font->type2_stack_size = 0;
1539
0
      font->type2_find_width = FALSE;
1540
0
      p++;
1541
0
  } else if (*p == TYPE2_hintmask || *p == TYPE2_cntrmask) {
1542
      /* Hintmask operator. These operators are followed by a
1543
       * variable length mask where the length depends on the
1544
       * number of hints declared. The first time this is called
1545
       * it is also an implicit vstem if there are arguments on
1546
       * the stack. */
1547
0
      if (font->type2_hintmask_bytes == 0) {
1548
0
    font->type2_stack_top_is_int = FALSE;
1549
0
    font->type2_num_hints += font->type2_stack_size/2;
1550
0
    if (font->type2_find_width && font->type2_stack_size % 2)
1551
0
        font->type2_found_width = TRUE;
1552
1553
0
    font->type2_stack_size = 0;
1554
0
    font->type2_find_width = FALSE;
1555
0
    font->type2_hintmask_bytes = (font->type2_num_hints+7)/8;
1556
0
      }
1557
1558
0
      hint_bytes = font->type2_hintmask_bytes;
1559
0
      p++;
1560
0
      p += hint_bytes;
1561
0
  } else if (*p == TYPE2_rmoveto) {
1562
0
      if (font->type2_find_width && font->type2_stack_size > 2)
1563
0
    font->type2_found_width = TRUE;
1564
1565
0
      font->type2_stack_size = 0;
1566
0
      font->type2_find_width = FALSE;
1567
0
      font->type2_has_path = TRUE;
1568
0
      p++;
1569
0
  } else if (*p == TYPE2_hmoveto || *p == TYPE2_vmoveto) {
1570
0
      if (font->type2_find_width && font->type2_stack_size > 1)
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_endchar) {
1578
0
      if (!font->type2_has_path && font->type2_stack_size > 3)
1579
0
    return CAIRO_INT_STATUS_UNSUPPORTED; /* seac (Ref Appendix C of Type 2 Charstring Format */
1580
1581
0
      if (font->type2_find_width && font->type2_stack_size > 0)
1582
0
    font->type2_found_width = TRUE;
1583
1584
0
      return CAIRO_STATUS_SUCCESS;
1585
0
        } else if (*p == TYPE2_callsubr) {
1586
            /* call to local subroutine */
1587
0
      if (! font->type2_stack_top_is_int)
1588
0
    return CAIRO_INT_STATUS_UNSUPPORTED;
1589
1590
0
            if (++font->type2_nesting_level > MAX_SUBROUTINE_NESTING)
1591
0
    return CAIRO_INT_STATUS_UNSUPPORTED;
1592
1593
0
            p++;
1594
0
      font->type2_stack_top_is_int = FALSE;
1595
0
            font->type2_stack_size--;
1596
0
      if (font->type2_find_width && font->type2_stack_size == 0)
1597
0
    font->type2_seen_first_int = FALSE;
1598
1599
0
            if (font->is_cid) {
1600
0
                fd = font->fdselect[glyph_id];
1601
0
    sub_num = font->type2_stack_top_value + font->fd_local_sub_bias[fd];
1602
0
    if (sub_num >= (int)_cairo_array_num_elements(&font->fd_local_sub_index[fd]))
1603
0
        return CAIRO_INT_STATUS_UNSUPPORTED;
1604
0
                element = _cairo_array_index (&font->fd_local_sub_index[fd], sub_num);
1605
0
                if (! font->fd_local_subs_used[fd][sub_num]) {
1606
0
        font->fd_local_subs_used[fd][sub_num] = TRUE;
1607
0
        cairo_cff_parse_charstring (font, element->data, element->length, glyph_id, need_width);
1608
0
    }
1609
0
            } else {
1610
0
    sub_num = font->type2_stack_top_value + font->local_sub_bias;
1611
0
    if (sub_num >= (int)_cairo_array_num_elements(&font->local_sub_index))
1612
0
        return CAIRO_INT_STATUS_UNSUPPORTED;
1613
0
                element = _cairo_array_index (&font->local_sub_index, sub_num);
1614
0
                if (! font->local_subs_used[sub_num] ||
1615
0
        (need_width && !font->type2_found_width))
1616
0
    {
1617
0
        font->local_subs_used[sub_num] = TRUE;
1618
0
        cairo_cff_parse_charstring (font, element->data, element->length, glyph_id, need_width);
1619
0
    }
1620
0
            }
1621
0
            font->type2_nesting_level--;
1622
0
        } else if (*p == TYPE2_callgsubr) {
1623
            /* call to global subroutine */
1624
0
      if (! font->type2_stack_top_is_int)
1625
0
    return CAIRO_INT_STATUS_UNSUPPORTED;
1626
1627
0
            if (++font->type2_nesting_level > MAX_SUBROUTINE_NESTING)
1628
0
    return CAIRO_INT_STATUS_UNSUPPORTED;
1629
1630
0
            p++;
1631
0
            font->type2_stack_size--;
1632
0
      font->type2_stack_top_is_int = FALSE;
1633
0
      if (font->type2_find_width && font->type2_stack_size == 0)
1634
0
    font->type2_seen_first_int = FALSE;
1635
1636
0
      sub_num = font->type2_stack_top_value + font->global_sub_bias;
1637
0
      if (sub_num >= (int)_cairo_array_num_elements(&font->global_sub_index))
1638
0
    return CAIRO_INT_STATUS_UNSUPPORTED;
1639
0
      element = _cairo_array_index (&font->global_sub_index, sub_num);
1640
0
            if (! font->global_subs_used[sub_num] ||
1641
0
    (need_width && !font->type2_found_width))
1642
0
      {
1643
0
                font->global_subs_used[sub_num] = TRUE;
1644
0
                cairo_cff_parse_charstring (font, element->data, element->length, glyph_id, need_width);
1645
0
            }
1646
0
            font->type2_nesting_level--;
1647
0
        } else if (*p == 12) {
1648
            /* 2 byte instruction */
1649
1650
      /* All the 2 byte operators are either not valid before a
1651
       * stack clearing operator or they are one of the
1652
       * arithmetic, storage, or conditional operators. */
1653
0
      if (need_width && font->type2_find_width)
1654
0
    return CAIRO_INT_STATUS_UNSUPPORTED;
1655
1656
0
            p += 2;
1657
0
      font->type2_stack_top_is_int = FALSE;
1658
0
  } else {
1659
            /* 1 byte instruction */
1660
0
            p++;
1661
0
      font->type2_stack_top_is_int = FALSE;
1662
0
        }
1663
0
    }
1664
1665
0
    return CAIRO_STATUS_SUCCESS;
1666
0
}
1667
1668
static cairo_status_t
1669
cairo_cff_find_width_and_subroutines_used (cairo_cff_font_t  *font,
1670
             unsigned char *charstring, int length,
1671
             int glyph_id, int subset_id)
1672
0
{
1673
0
    cairo_status_t status;
1674
0
    int width;
1675
0
    int fd;
1676
1677
0
    font->type2_stack_size = 0;
1678
0
    font->type2_stack_top_value = 0;;
1679
0
    font->type2_stack_top_is_int = FALSE;
1680
0
    font->type2_num_hints = 0;
1681
0
    font->type2_hintmask_bytes = 0;
1682
0
    font->type2_nesting_level = 0;
1683
0
    font->type2_seen_first_int = FALSE;
1684
0
    font->type2_find_width = TRUE;
1685
0
    font->type2_found_width = FALSE;
1686
0
    font->type2_width = 0;
1687
0
    font->type2_has_path = FALSE;
1688
1689
0
    status = cairo_cff_parse_charstring (font, charstring, length, glyph_id, TRUE);
1690
0
    if (status)
1691
0
  return status;
1692
1693
0
    if (!font->is_opentype) {
1694
0
        if (font->is_cid) {
1695
0
            fd = font->fdselect[glyph_id];
1696
0
            if (font->type2_found_width)
1697
0
                width = font->fd_nominal_width[fd] + font->type2_width;
1698
0
            else
1699
0
                width = font->fd_default_width[fd];
1700
0
        } else {
1701
0
            if (font->type2_found_width)
1702
0
                width = font->nominal_width + font->type2_width;
1703
0
            else
1704
0
                width = font->default_width;
1705
0
        }
1706
0
        font->widths[subset_id] = width;
1707
0
    }
1708
1709
0
    return CAIRO_STATUS_SUCCESS;
1710
0
}
1711
1712
static cairo_int_status_t
1713
cairo_cff_font_get_gid_for_cid (cairo_cff_font_t  *font, unsigned long cid, unsigned long *gid)
1714
0
{
1715
0
    unsigned char *p;
1716
0
    unsigned long first_gid;
1717
0
    unsigned long first_cid;
1718
0
    int num_left;
1719
0
    unsigned long c, g;
1720
1721
0
    if (cid == 0) {
1722
0
  *gid = 0;
1723
0
  return CAIRO_STATUS_SUCCESS;
1724
0
    }
1725
1726
0
    switch (font->charset[0]) {
1727
  /* Format 0 */
1728
0
  case 0:
1729
0
      p = font->charset + 1;
1730
0
      g = 1;
1731
0
      while (g <= (unsigned)font->num_glyphs && p < font->data_end) {
1732
0
    c = get_unaligned_be16 (p);
1733
0
    if (c == cid) {
1734
0
        *gid = g;
1735
0
        return CAIRO_STATUS_SUCCESS;
1736
0
    }
1737
0
    g++;
1738
0
    p += 2;
1739
0
      }
1740
0
      break;
1741
1742
  /* Format 1 */
1743
0
  case 1:
1744
0
      first_gid = 1;
1745
0
      p = font->charset + 1;
1746
0
      while (first_gid <= (unsigned)font->num_glyphs && p + 2 < font->data_end) {
1747
0
    first_cid = get_unaligned_be16 (p);
1748
0
    num_left = p[2];
1749
0
    if (cid >= first_cid && cid <= first_cid + num_left) {
1750
0
        *gid = first_gid + cid - first_cid;
1751
0
        return CAIRO_STATUS_SUCCESS;
1752
0
    }
1753
0
    first_gid += num_left + 1;
1754
0
    p += 3;
1755
0
      }
1756
0
      break;
1757
1758
  /* Format 2 */
1759
0
  case 2:
1760
0
      first_gid = 1;
1761
0
      p = font->charset + 1;
1762
0
      while (first_gid <= (unsigned)font->num_glyphs && p + 3 < font->data_end) {
1763
0
    first_cid = get_unaligned_be16 (p);
1764
0
    num_left = get_unaligned_be16 (p+2);
1765
0
    if (cid >= first_cid && cid <= first_cid + num_left) {
1766
0
        *gid = first_gid + cid - first_cid;
1767
0
        return CAIRO_STATUS_SUCCESS;
1768
0
    }
1769
0
    first_gid += num_left + 1;
1770
0
    p += 4;
1771
0
      }
1772
0
      break;
1773
1774
0
  default:
1775
0
      break;
1776
0
    }
1777
0
    return CAIRO_INT_STATUS_UNSUPPORTED;
1778
0
}
1779
1780
static cairo_int_status_t
1781
cairo_cff_font_subset_charstrings_and_subroutines (cairo_cff_font_t  *font)
1782
0
{
1783
0
    cff_index_element_t *element;
1784
0
    unsigned int i;
1785
0
    cairo_int_status_t status;
1786
0
    unsigned long glyph, cid;
1787
1788
0
    font->subset_subroutines = TRUE;
1789
0
    for (i = 0; i < font->scaled_font_subset->num_glyphs; i++) {
1790
0
  if (font->is_cid && !font->is_opentype) {
1791
0
      cid = font->scaled_font_subset->glyphs[i];
1792
0
      status = cairo_cff_font_get_gid_for_cid (font, cid, &glyph);
1793
0
      if (unlikely (status))
1794
0
    return status;
1795
0
  } else {
1796
0
      glyph = font->scaled_font_subset->glyphs[i];
1797
0
  }
1798
0
        element = _cairo_array_index (&font->charstrings_index, glyph);
1799
0
        status = cff_index_append (&font->charstrings_subset_index,
1800
0
                                   element->data,
1801
0
                                   element->length);
1802
0
        if (unlikely (status))
1803
0
            return status;
1804
1805
0
  if (font->subset_subroutines) {
1806
0
      status = cairo_cff_find_width_and_subroutines_used (font,
1807
0
                element->data, element->length,
1808
0
                glyph, i);
1809
0
      if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
1810
    /* If parsing the charstrings fails we embed all the
1811
     * subroutines. But if the font is not opentype we
1812
     * need to successfully parse all charstrings to get
1813
     * the widths. */
1814
0
    font->subset_subroutines = FALSE;
1815
0
    if (!font->is_opentype)
1816
0
        return status;
1817
0
      } else if (unlikely (status)) {
1818
0
                return status;
1819
0
      }
1820
0
        }
1821
0
    }
1822
1823
0
    return CAIRO_STATUS_SUCCESS;
1824
0
}
1825
1826
static cairo_status_t
1827
cairo_cff_font_subset_fontdict (cairo_cff_font_t  *font)
1828
0
{
1829
0
    unsigned int i;
1830
0
    int fd;
1831
0
    int *reverse_map;
1832
0
    unsigned long cid, gid;
1833
0
    cairo_int_status_t status;
1834
1835
0
    font->fdselect_subset = calloc (font->scaled_font_subset->num_glyphs,
1836
0
                                     sizeof (int));
1837
0
    if (unlikely (font->fdselect_subset == NULL))
1838
0
  return _cairo_error (CAIRO_STATUS_NO_MEMORY);
1839
1840
0
    font->fd_subset_map = calloc (font->num_fontdicts, sizeof (int));
1841
0
    if (unlikely (font->fd_subset_map == NULL))
1842
0
  return _cairo_error (CAIRO_STATUS_NO_MEMORY);
1843
1844
0
    font->private_dict_offset = calloc (font->num_fontdicts, sizeof (int));
1845
0
    if (unlikely (font->private_dict_offset == NULL))
1846
0
  return _cairo_error (CAIRO_STATUS_NO_MEMORY);
1847
1848
0
    reverse_map = calloc (font->num_fontdicts, sizeof (int));
1849
0
    if (unlikely (reverse_map == NULL))
1850
0
  return _cairo_error (CAIRO_STATUS_NO_MEMORY);
1851
1852
0
    for (i = 0; i < font->num_fontdicts; i++)
1853
0
        reverse_map[i] = -1;
1854
1855
0
    font->num_subset_fontdicts = 0;
1856
0
    for (i = 0; i < font->scaled_font_subset->num_glyphs; i++) {
1857
0
  if (font->is_opentype) {
1858
0
      gid = font->scaled_font_subset->glyphs[i];
1859
0
  } else {
1860
0
      cid = font->scaled_font_subset->glyphs[i];
1861
0
      status = cairo_cff_font_get_gid_for_cid (font, cid, &gid);
1862
0
      if (unlikely (status)) {
1863
0
    free (reverse_map);
1864
0
    return status;
1865
0
      }
1866
0
  }
1867
1868
0
        fd = font->fdselect[gid];
1869
0
        if (reverse_map[fd] < 0) {
1870
0
            font->fd_subset_map[font->num_subset_fontdicts] = fd;
1871
0
            reverse_map[fd] = font->num_subset_fontdicts++;
1872
0
        }
1873
0
        font->fdselect_subset[i] = reverse_map[fd];
1874
0
    }
1875
1876
0
    free (reverse_map);
1877
1878
0
    return CAIRO_STATUS_SUCCESS;
1879
0
}
1880
1881
static cairo_status_t
1882
cairo_cff_font_create_cid_fontdict (cairo_cff_font_t *font)
1883
0
{
1884
0
    unsigned char buf[100];
1885
0
    unsigned char *end_buf;
1886
0
    cairo_status_t status;
1887
1888
0
    font->num_fontdicts = 1;
1889
0
    font->fd_dict = _cairo_malloc (sizeof (cairo_hash_table_t *));
1890
0
    if (unlikely (font->fd_dict == NULL))
1891
0
  return _cairo_error (CAIRO_STATUS_NO_MEMORY);
1892
1893
0
    if (cff_dict_init (&font->fd_dict[0])) {
1894
0
  free (font->fd_dict);
1895
0
  font->fd_dict = NULL;
1896
0
  font->num_fontdicts = 0;
1897
0
  return _cairo_error (CAIRO_STATUS_NO_MEMORY);
1898
0
    }
1899
1900
0
    font->fd_subset_map = _cairo_malloc (sizeof (int));
1901
0
    if (unlikely (font->fd_subset_map == NULL))
1902
0
  return _cairo_error (CAIRO_STATUS_NO_MEMORY);
1903
1904
0
    font->private_dict_offset = _cairo_malloc (sizeof (int));
1905
0
    if (unlikely (font->private_dict_offset == NULL))
1906
0
  return _cairo_error (CAIRO_STATUS_NO_MEMORY);
1907
1908
0
    font->fd_subset_map[0] = 0;
1909
0
    font->num_subset_fontdicts = 1;
1910
1911
    /* Set integer operand to max value to use max size encoding to reserve
1912
     * space for any value later */
1913
0
    end_buf = encode_integer_max (buf, 0);
1914
0
    end_buf = encode_integer_max (end_buf, 0);
1915
0
    status = cff_dict_set_operands (font->fd_dict[0], PRIVATE_OP, buf, end_buf - buf);
1916
0
    if (unlikely (status))
1917
0
  return status;
1918
1919
0
    return CAIRO_STATUS_SUCCESS;
1920
0
}
1921
1922
static cairo_status_t
1923
cairo_cff_font_subset_strings (cairo_cff_font_t *font)
1924
0
{
1925
0
    cairo_status_t status;
1926
0
    unsigned int i;
1927
1928
0
    status = cairo_cff_font_subset_dict_strings (font, font->top_dict);
1929
0
    if (unlikely (status))
1930
0
        return status;
1931
1932
0
    if (font->is_cid) {
1933
0
        for (i = 0; i < font->num_subset_fontdicts; i++) {
1934
0
            status = cairo_cff_font_subset_dict_strings (font, font->fd_dict[font->fd_subset_map[i]]);
1935
0
            if (unlikely (status))
1936
0
                return status;
1937
1938
0
            status = cairo_cff_font_subset_dict_strings (font, font->fd_private_dict[font->fd_subset_map[i]]);
1939
0
            if (unlikely (status))
1940
0
                return status;
1941
0
        }
1942
0
    } else {
1943
0
        status = cairo_cff_font_subset_dict_strings (font, font->private_dict);
1944
0
    }
1945
1946
0
    return status;
1947
0
}
1948
1949
/* The Euro is the only the only character in the winansi encoding
1950
 * with a glyph name that is not a CFF standard string. As the strings
1951
 * are written before the charset, we need to check during the
1952
 * subsetting phase if the Euro glyph is required and add the
1953
 * glyphname to the list of strings to write out.
1954
 */
1955
static cairo_status_t
1956
cairo_cff_font_add_euro_charset_string (cairo_cff_font_t *font)
1957
0
{
1958
0
    cairo_status_t status;
1959
0
    unsigned int i;
1960
0
    int ch;
1961
0
    const char *euro = "Euro";
1962
1963
0
    for (i = 1; i < font->scaled_font_subset->num_glyphs; i++) {
1964
0
  ch = font->scaled_font_subset->to_latin_char[i];
1965
0
  if (ch == 128) {
1966
0
      font->euro_sid = NUM_STD_STRINGS + _cairo_array_num_elements (&font->strings_subset_index);
1967
0
      status = cff_index_append_copy (&font->strings_subset_index,
1968
0
              (unsigned char *)euro, strlen(euro));
1969
0
      return status;
1970
0
  }
1971
0
    }
1972
1973
0
    return CAIRO_STATUS_SUCCESS;
1974
0
}
1975
1976
static cairo_status_t
1977
cairo_cff_font_subset_font (cairo_cff_font_t  *font)
1978
0
{
1979
0
    cairo_status_t status;
1980
1981
0
    if (!font->scaled_font_subset->is_latin) {
1982
0
  status = cairo_cff_font_set_ros_strings (font);
1983
0
  if (unlikely (status))
1984
0
      return status;
1985
0
    }
1986
1987
0
    status = cairo_cff_font_subset_charstrings_and_subroutines (font);
1988
0
    if (unlikely (status))
1989
0
        return status;
1990
1991
0
    if (!font->scaled_font_subset->is_latin) {
1992
0
  if (font->is_cid)
1993
0
      status = cairo_cff_font_subset_fontdict (font);
1994
0
  else
1995
0
      status = cairo_cff_font_create_cid_fontdict (font);
1996
0
  if (unlikely (status))
1997
0
      return status;
1998
0
    }  else {
1999
0
  font->private_dict_offset = _cairo_malloc (sizeof (int));
2000
0
  if (unlikely (font->private_dict_offset == NULL))
2001
0
      return _cairo_error (CAIRO_STATUS_NO_MEMORY);
2002
0
    }
2003
2004
0
    status = cairo_cff_font_subset_strings (font);
2005
0
    if (unlikely (status))
2006
0
        return status;
2007
2008
0
    if (font->scaled_font_subset->is_latin)
2009
0
  status = cairo_cff_font_add_euro_charset_string (font);
2010
2011
0
    return status;
2012
0
}
2013
2014
/* Set the operand of the specified operator in the (already written)
2015
 * top dict to point to the current position in the output
2016
 * array. Operands updated with this function must have previously
2017
 * been encoded with the 5-byte (max) integer encoding. */
2018
static void
2019
cairo_cff_font_set_topdict_operator_to_cur_pos (cairo_cff_font_t  *font,
2020
                                                int                operator)
2021
0
{
2022
0
    int cur_pos;
2023
0
    int offset;
2024
0
    int size;
2025
0
    unsigned char buf[10];
2026
0
    unsigned char *buf_end;
2027
0
    unsigned char *op_ptr;
2028
2029
0
    cur_pos = _cairo_array_num_elements (&font->output);
2030
0
    buf_end = encode_integer_max (buf, cur_pos);
2031
0
    offset = cff_dict_get_location (font->top_dict, operator, &size);
2032
0
    assert (offset > 0);
2033
0
    op_ptr = _cairo_array_index (&font->output, offset);
2034
0
    memcpy (op_ptr, buf, buf_end - buf);
2035
0
}
2036
2037
static cairo_status_t
2038
cairo_cff_font_write_header (cairo_cff_font_t *font)
2039
0
{
2040
0
    return _cairo_array_append_multiple (&font->output,
2041
0
                                         font->header,
2042
0
                                         font->header->header_size);
2043
0
}
2044
2045
static cairo_status_t
2046
cairo_cff_font_write_name (cairo_cff_font_t *font)
2047
0
{
2048
0
    cairo_status_t status = CAIRO_STATUS_SUCCESS;
2049
0
    cairo_array_t index;
2050
2051
0
    cff_index_init (&index);
2052
2053
0
    status = cff_index_append_copy (&index,
2054
0
                                    (unsigned char *) font->ps_name,
2055
0
                                    strlen(font->ps_name));
2056
0
    if (unlikely (status))
2057
0
  goto FAIL;
2058
2059
0
    status = cff_index_write (&index, &font->output);
2060
0
    if (unlikely (status))
2061
0
        goto FAIL;
2062
2063
0
FAIL:
2064
0
    cff_index_fini (&index);
2065
2066
0
    return status;
2067
0
}
2068
2069
static cairo_status_t
2070
cairo_cff_font_write_top_dict (cairo_cff_font_t *font)
2071
0
{
2072
0
    uint16_t count;
2073
0
    unsigned char buf[10];
2074
0
    unsigned char *p;
2075
0
    int offset_index;
2076
0
    int dict_start, dict_size;
2077
0
    int offset_size = 4;
2078
0
    cairo_status_t status;
2079
2080
    /* Write an index containing the top dict */
2081
2082
0
    count = cpu_to_be16 (1);
2083
0
    status = _cairo_array_append_multiple (&font->output, &count, 2);
2084
0
    if (unlikely (status))
2085
0
        return status;
2086
0
    buf[0] = offset_size;
2087
0
    status = _cairo_array_append (&font->output, buf);
2088
0
    if (unlikely (status))
2089
0
        return status;
2090
0
    encode_index_offset (buf, offset_size, 1);
2091
0
    status = _cairo_array_append_multiple (&font->output, buf, offset_size);
2092
0
    if (unlikely (status))
2093
0
        return status;
2094
2095
    /* Reserve space for last element of offset array and update after
2096
     * dict is written */
2097
0
    offset_index = _cairo_array_num_elements (&font->output);
2098
0
    status = _cairo_array_append_multiple (&font->output, buf, offset_size);
2099
0
    if (unlikely (status))
2100
0
        return status;
2101
2102
0
    dict_start = _cairo_array_num_elements (&font->output);
2103
0
    status = cff_dict_write (font->top_dict, &font->output);
2104
0
    if (unlikely (status))
2105
0
        return status;
2106
0
    dict_size = _cairo_array_num_elements (&font->output) - dict_start;
2107
2108
0
    encode_index_offset (buf, offset_size, dict_size + 1);
2109
0
    p = _cairo_array_index (&font->output, offset_index);
2110
0
    memcpy (p, buf, offset_size);
2111
2112
0
    return CAIRO_STATUS_SUCCESS;
2113
0
}
2114
2115
static cairo_status_t
2116
cairo_cff_font_write_strings (cairo_cff_font_t  *font)
2117
0
{
2118
0
    return cff_index_write (&font->strings_subset_index, &font->output);
2119
0
}
2120
2121
static cairo_status_t
2122
cairo_cff_font_write_global_subrs (cairo_cff_font_t  *font)
2123
0
{
2124
0
    unsigned int i;
2125
0
    unsigned char return_op = TYPE2_return;
2126
2127
    /* poppler and fontforge don't like zero length subroutines so we
2128
     * replace unused subroutines with a 'return' instruction. */
2129
0
    if (font->subset_subroutines) {
2130
0
        for (i = 0; i < _cairo_array_num_elements (&font->global_sub_index); i++) {
2131
0
            if (! font->global_subs_used[i])
2132
0
                cff_index_set_object (&font->global_sub_index, i, &return_op, 1);
2133
0
        }
2134
0
    }
2135
2136
0
    return cff_index_write (&font->global_sub_index, &font->output);
2137
0
}
2138
2139
static cairo_status_t
2140
cairo_cff_font_write_encoding (cairo_cff_font_t  *font)
2141
0
{
2142
0
    unsigned char buf[2];
2143
0
    cairo_status_t status;
2144
0
    unsigned int i;
2145
2146
0
    cairo_cff_font_set_topdict_operator_to_cur_pos (font, ENCODING_OP);
2147
0
    buf[0] = 0; /* Format 0 */
2148
0
    buf[1] = font->scaled_font_subset->num_glyphs - 1;
2149
0
    status = _cairo_array_append_multiple (&font->output, buf, 2);
2150
0
    if (unlikely (status))
2151
0
  return status;
2152
2153
0
    for (i = 1; i < font->scaled_font_subset->num_glyphs; i++) {
2154
0
  unsigned char ch = font->scaled_font_subset->to_latin_char[i];
2155
0
        status = _cairo_array_append (&font->output, &ch);
2156
0
        if (unlikely (status))
2157
0
            return status;
2158
0
    }
2159
2160
0
    return CAIRO_STATUS_SUCCESS;
2161
0
}
2162
2163
static cairo_status_t
2164
cairo_cff_font_write_fdselect (cairo_cff_font_t  *font)
2165
0
{
2166
0
    unsigned char data;
2167
0
    unsigned int i;
2168
0
    cairo_int_status_t status;
2169
2170
0
    cairo_cff_font_set_topdict_operator_to_cur_pos (font, FDSELECT_OP);
2171
2172
0
    if (font->is_cid) {
2173
0
        data = 0;
2174
0
        status = _cairo_array_append (&font->output, &data);
2175
0
        if (unlikely (status))
2176
0
            return status;
2177
2178
0
        for (i = 0; i < font->scaled_font_subset->num_glyphs; i++) {
2179
0
            data = font->fdselect_subset[i];
2180
0
            status = _cairo_array_append (&font->output, &data);
2181
0
            if (unlikely (status))
2182
0
                return status;
2183
0
        }
2184
0
    } else {
2185
0
        unsigned char byte;
2186
0
        uint16_t word;
2187
2188
0
        status = _cairo_array_grow_by (&font->output, 9);
2189
0
        if (unlikely (status))
2190
0
            return status;
2191
2192
0
        byte = 3;
2193
0
        status = _cairo_array_append (&font->output, &byte);
2194
0
        assert (status == CAIRO_INT_STATUS_SUCCESS);
2195
2196
0
        word = cpu_to_be16 (1);
2197
0
        status = _cairo_array_append_multiple (&font->output, &word, 2);
2198
0
        assert (status == CAIRO_INT_STATUS_SUCCESS);
2199
2200
0
        word = cpu_to_be16 (0);
2201
0
        status = _cairo_array_append_multiple (&font->output, &word, 2);
2202
0
        assert (status == CAIRO_INT_STATUS_SUCCESS);
2203
2204
0
        byte = 0;
2205
0
        status = _cairo_array_append (&font->output, &byte);
2206
0
        assert (status == CAIRO_INT_STATUS_SUCCESS);
2207
2208
0
        word = cpu_to_be16 (font->scaled_font_subset->num_glyphs);
2209
0
        status = _cairo_array_append_multiple (&font->output, &word, 2);
2210
0
        assert (status == CAIRO_INT_STATUS_SUCCESS);
2211
0
    }
2212
2213
0
    return CAIRO_STATUS_SUCCESS;
2214
0
}
2215
2216
/* Winansi to CFF standard strings mapping for characters 128 to 255 */
2217
static const int winansi_to_cff_std_string[] = {
2218
  /* 128 */
2219
      0,   0, 117, 101, 118, 121, 112, 113,
2220
    126, 122, 192, 107, 142,   0, 199,   0,
2221
  /* 144 */
2222
      0,  65,   8, 105, 119, 116, 111, 137,
2223
    127, 153, 221, 108, 148,   0, 228, 198,
2224
  /* 160 */
2225
      0,  96,  97,  98, 103, 100, 160, 102,
2226
    131, 170, 139, 106, 151,   0, 165, 128,
2227
  /* 176 */
2228
    161, 156, 164, 169, 125, 152, 115, 114,
2229
    133, 150, 143, 120, 158, 155, 163, 123,
2230
  /* 192 */
2231
    174, 171, 172, 176, 173, 175, 138, 177,
2232
    181, 178, 179, 180, 185, 182, 183, 184,
2233
  /* 208 */
2234
    154, 186, 190, 187, 188, 191, 189, 168,
2235
    141, 196, 193, 194, 195, 197, 157, 149,
2236
  /* 224 */
2237
    203, 200, 201, 205, 202, 204, 144, 206,
2238
    210, 207, 208, 209, 214, 211, 212, 213,
2239
  /* 240 */
2240
    167, 215, 219, 216, 217, 220, 218, 159,
2241
    147, 225, 222, 223, 224, 226, 162, 227,
2242
};
2243
2244
static int
2245
cairo_cff_font_get_sid_for_winansi_char (cairo_cff_font_t  *font, int ch)
2246
0
{
2247
0
    int sid;
2248
2249
0
    if (ch == 39) {
2250
0
  sid = 104;
2251
2252
0
    } else if (ch == 96) {
2253
0
  sid = 124;
2254
2255
0
    } else if (ch >= 32 && ch <= 126) {
2256
0
  sid = ch - 31;
2257
2258
0
    } else if (ch == 128) {
2259
0
  assert (font->euro_sid >= NUM_STD_STRINGS);
2260
0
  sid = font->euro_sid;
2261
2262
0
    } else if (ch >= 128 && ch <= 255) {
2263
0
  sid = winansi_to_cff_std_string[ch - 128];
2264
2265
0
    } else {
2266
0
  sid = 0;
2267
0
    }
2268
2269
0
    return sid;
2270
0
}
2271
2272
static cairo_status_t
2273
cairo_cff_font_write_type1_charset (cairo_cff_font_t  *font)
2274
0
{
2275
0
    unsigned char format = 0;
2276
0
    unsigned int i;
2277
0
    int ch, sid;
2278
0
    cairo_status_t status;
2279
0
    uint16_t sid_be16;
2280
2281
0
    cairo_cff_font_set_topdict_operator_to_cur_pos (font, CHARSET_OP);
2282
0
    status = _cairo_array_append (&font->output, &format);
2283
0
    if (unlikely (status))
2284
0
  return status;
2285
2286
0
    for (i = 1; i < font->scaled_font_subset->num_glyphs; i++) {
2287
0
  ch = font->scaled_font_subset->to_latin_char[i];
2288
0
  sid = cairo_cff_font_get_sid_for_winansi_char (font, ch);
2289
0
        if (unlikely (status))
2290
0
      return status;
2291
2292
0
  sid_be16 = cpu_to_be16(sid);
2293
0
  status = _cairo_array_append_multiple (&font->output, &sid_be16, sizeof(sid_be16));
2294
0
        if (unlikely (status))
2295
0
            return status;
2296
0
    }
2297
2298
0
    return CAIRO_STATUS_SUCCESS;
2299
0
}
2300
2301
static cairo_status_t
2302
cairo_cff_font_write_cid_charset (cairo_cff_font_t  *font)
2303
0
{
2304
0
    unsigned char byte;
2305
0
    uint16_t word;
2306
0
    cairo_status_t status;
2307
2308
0
    cairo_cff_font_set_topdict_operator_to_cur_pos (font, CHARSET_OP);
2309
0
    status = _cairo_array_grow_by (&font->output, 5);
2310
0
    if (unlikely (status))
2311
0
        return status;
2312
2313
0
    byte = 2;
2314
0
    status = _cairo_array_append (&font->output, &byte);
2315
0
    assert (status == CAIRO_STATUS_SUCCESS);
2316
2317
0
    word = cpu_to_be16 (1);
2318
0
    status = _cairo_array_append_multiple (&font->output, &word, 2);
2319
0
    assert (status == CAIRO_STATUS_SUCCESS);
2320
2321
0
    word = cpu_to_be16 (font->scaled_font_subset->num_glyphs - 2);
2322
0
    status = _cairo_array_append_multiple (&font->output, &word, 2);
2323
0
    assert (status == CAIRO_STATUS_SUCCESS);
2324
2325
0
    return CAIRO_STATUS_SUCCESS;
2326
0
}
2327
2328
static cairo_status_t
2329
cairo_cff_font_write_charstrings (cairo_cff_font_t  *font)
2330
0
{
2331
0
    cairo_cff_font_set_topdict_operator_to_cur_pos (font, CHARSTRINGS_OP);
2332
2333
0
    return cff_index_write (&font->charstrings_subset_index, &font->output);
2334
0
}
2335
2336
static cairo_status_t
2337
cairo_cff_font_write_cid_fontdict (cairo_cff_font_t *font)
2338
0
{
2339
0
    unsigned int i;
2340
0
    cairo_int_status_t status;
2341
0
    unsigned int offset_array;
2342
0
    unsigned char *offset_array_ptr;
2343
0
    int offset_base;
2344
0
    uint16_t count;
2345
0
    uint8_t offset_size = 4;
2346
2347
0
    cairo_cff_font_set_topdict_operator_to_cur_pos (font, FDARRAY_OP);
2348
0
    count = cpu_to_be16 (font->num_subset_fontdicts);
2349
0
    status = _cairo_array_append_multiple (&font->output, &count, sizeof (uint16_t));
2350
0
    if (unlikely (status))
2351
0
        return status;
2352
0
    status = _cairo_array_append (&font->output, &offset_size);
2353
0
    if (unlikely (status))
2354
0
        return status;
2355
2356
0
    offset_array = _cairo_array_num_elements (&font->output);
2357
0
    status = _cairo_array_allocate (&font->output,
2358
0
                                    (font->num_subset_fontdicts + 1)*offset_size,
2359
0
                                    (void **) &offset_array_ptr);
2360
0
    if (unlikely (status))
2361
0
        return status;
2362
0
    offset_base = _cairo_array_num_elements (&font->output) - 1;
2363
0
    put_unaligned_be32(1, offset_array_ptr);
2364
0
    offset_array += sizeof(uint32_t);
2365
0
    for (i = 0; i < font->num_subset_fontdicts; i++) {
2366
0
        status = cff_dict_write (font->fd_dict[font->fd_subset_map[i]],
2367
0
                                 &font->output);
2368
0
        if (unlikely (status))
2369
0
            return status;
2370
2371
0
  offset_array_ptr = _cairo_array_index (&font->output, offset_array);
2372
0
  put_unaligned_be32 (_cairo_array_num_elements (&font->output) - offset_base,
2373
0
          offset_array_ptr);
2374
0
  offset_array += sizeof(uint32_t);
2375
0
    }
2376
2377
0
    return CAIRO_STATUS_SUCCESS;
2378
0
}
2379
2380
static cairo_status_t
2381
cairo_cff_font_write_private_dict (cairo_cff_font_t   *font,
2382
           int                 dict_num,
2383
           cairo_hash_table_t *parent_dict,
2384
           cairo_hash_table_t *private_dict)
2385
0
{
2386
0
    int offset;
2387
0
    int size;
2388
0
    unsigned char buf[10];
2389
0
    unsigned char *buf_end;
2390
0
    unsigned char *p;
2391
0
    cairo_status_t status;
2392
2393
    /* Write private dict and update offset and size in top dict */
2394
0
    font->private_dict_offset[dict_num] = _cairo_array_num_elements (&font->output);
2395
0
    status = cff_dict_write (private_dict, &font->output);
2396
0
    if (unlikely (status))
2397
0
        return status;
2398
2399
0
    size = _cairo_array_num_elements (&font->output) - font->private_dict_offset[dict_num];
2400
    /* private entry has two operands - size and offset */
2401
0
    buf_end = encode_integer_max (buf, size);
2402
0
    buf_end = encode_integer_max (buf_end, font->private_dict_offset[dict_num]);
2403
0
    offset = cff_dict_get_location (parent_dict, PRIVATE_OP, &size);
2404
0
    assert (offset > 0);
2405
0
    p = _cairo_array_index (&font->output, offset);
2406
0
    memcpy (p, buf, buf_end - buf);
2407
2408
0
    return CAIRO_STATUS_SUCCESS;
2409
0
}
2410
2411
static cairo_status_t
2412
cairo_cff_font_write_local_sub (cairo_cff_font_t   *font,
2413
                                int                 dict_num,
2414
                                cairo_hash_table_t *private_dict,
2415
                                cairo_array_t      *local_sub_index,
2416
                                cairo_bool_t       *local_subs_used)
2417
0
{
2418
0
    int offset;
2419
0
    int size;
2420
0
    unsigned char buf[10];
2421
0
    unsigned char *buf_end;
2422
0
    unsigned char *p;
2423
0
    cairo_status_t status;
2424
0
    unsigned int i;
2425
0
    unsigned char return_op = TYPE2_return;
2426
2427
0
    if (_cairo_array_num_elements (local_sub_index) > 0) {
2428
        /* Write local subroutines and update offset in private
2429
         * dict. Local subroutines offset is relative to start of
2430
         * private dict */
2431
0
        offset = _cairo_array_num_elements (&font->output) - font->private_dict_offset[dict_num];
2432
0
        buf_end = encode_integer_max (buf, offset);
2433
0
        offset = cff_dict_get_location (private_dict, LOCAL_SUB_OP, &size);
2434
0
        assert (offset > 0);
2435
0
        p = _cairo_array_index (&font->output, offset);
2436
0
        memcpy (p, buf, buf_end - buf);
2437
2438
  /* poppler and fontforge don't like zero length subroutines so
2439
   * we replace unused subroutines with a 'return' instruction.
2440
   */
2441
0
        if (font->subset_subroutines) {
2442
0
            for (i = 0; i < _cairo_array_num_elements (local_sub_index); i++) {
2443
0
                if (! local_subs_used[i])
2444
0
                    cff_index_set_object (local_sub_index, i, &return_op, 1);
2445
0
            }
2446
0
        }
2447
0
        status = cff_index_write (local_sub_index, &font->output);
2448
0
        if (unlikely (status))
2449
0
            return status;
2450
0
    }
2451
2452
0
    return CAIRO_STATUS_SUCCESS;
2453
0
}
2454
2455
2456
static cairo_status_t
2457
cairo_cff_font_write_cid_private_dict_and_local_sub (cairo_cff_font_t  *font)
2458
0
{
2459
0
    unsigned int i;
2460
0
    cairo_int_status_t status;
2461
2462
0
    if (font->is_cid) {
2463
0
        for (i = 0; i < font->num_subset_fontdicts; i++) {
2464
0
            status = cairo_cff_font_write_private_dict (
2465
0
                            font,
2466
0
                            i,
2467
0
                            font->fd_dict[font->fd_subset_map[i]],
2468
0
                            font->fd_private_dict[font->fd_subset_map[i]]);
2469
0
            if (unlikely (status))
2470
0
                return status;
2471
0
        }
2472
2473
0
        for (i = 0; i < font->num_subset_fontdicts; i++) {
2474
0
            status = cairo_cff_font_write_local_sub (
2475
0
                            font,
2476
0
                            i,
2477
0
                            font->fd_private_dict[font->fd_subset_map[i]],
2478
0
                            &font->fd_local_sub_index[font->fd_subset_map[i]],
2479
0
                            font->fd_local_subs_used[font->fd_subset_map[i]]);
2480
0
            if (unlikely (status))
2481
0
                return status;
2482
0
        }
2483
0
    } else {
2484
0
        status = cairo_cff_font_write_private_dict (font,
2485
0
                                                    0,
2486
0
                                                    font->fd_dict[0],
2487
0
                                                    font->private_dict);
2488
0
  if (unlikely (status))
2489
0
      return status;
2490
2491
0
        status = cairo_cff_font_write_local_sub (font,
2492
0
                                                 0,
2493
0
                                                 font->private_dict,
2494
0
                                                 &font->local_sub_index,
2495
0
                                                 font->local_subs_used);
2496
0
  if (unlikely (status))
2497
0
      return status;
2498
0
    }
2499
2500
0
    return CAIRO_STATUS_SUCCESS;
2501
0
}
2502
2503
static cairo_status_t
2504
cairo_cff_font_write_type1_private_dict_and_local_sub (cairo_cff_font_t  *font)
2505
0
{
2506
0
    cairo_int_status_t status;
2507
2508
0
    status = cairo_cff_font_write_private_dict (font,
2509
0
            0,
2510
0
            font->top_dict,
2511
0
            font->private_dict);
2512
0
    if (unlikely (status))
2513
0
  return status;
2514
2515
0
    status = cairo_cff_font_write_local_sub (font,
2516
0
               0,
2517
0
               font->private_dict,
2518
0
               &font->local_sub_index,
2519
0
               font->local_subs_used);
2520
0
    if (unlikely (status))
2521
0
  return status;
2522
2523
0
    return CAIRO_STATUS_SUCCESS;
2524
0
}
2525
2526
2527
typedef cairo_status_t
2528
(*font_write_t) (cairo_cff_font_t *font);
2529
2530
static const font_write_t font_write_cid_funcs[] = {
2531
    cairo_cff_font_write_header,
2532
    cairo_cff_font_write_name,
2533
    cairo_cff_font_write_top_dict,
2534
    cairo_cff_font_write_strings,
2535
    cairo_cff_font_write_global_subrs,
2536
    cairo_cff_font_write_cid_charset,
2537
    cairo_cff_font_write_fdselect,
2538
    cairo_cff_font_write_charstrings,
2539
    cairo_cff_font_write_cid_fontdict,
2540
    cairo_cff_font_write_cid_private_dict_and_local_sub,
2541
};
2542
2543
static const font_write_t font_write_type1_funcs[] = {
2544
    cairo_cff_font_write_header,
2545
    cairo_cff_font_write_name,
2546
    cairo_cff_font_write_top_dict,
2547
    cairo_cff_font_write_strings,
2548
    cairo_cff_font_write_global_subrs,
2549
    cairo_cff_font_write_encoding,
2550
    cairo_cff_font_write_type1_charset,
2551
    cairo_cff_font_write_charstrings,
2552
    cairo_cff_font_write_type1_private_dict_and_local_sub,
2553
};
2554
2555
static cairo_status_t
2556
cairo_cff_font_write_subset (cairo_cff_font_t *font)
2557
0
{
2558
0
    cairo_int_status_t status;
2559
0
    unsigned int i;
2560
2561
0
    if (font->scaled_font_subset->is_latin) {
2562
0
        for (i = 0; i < ARRAY_LENGTH (font_write_type1_funcs); i++) {
2563
0
            status = font_write_type1_funcs[i] (font);
2564
0
            if (unlikely (status))
2565
0
                return status;
2566
0
        }
2567
0
    } else {
2568
0
        for (i = 0; i < ARRAY_LENGTH (font_write_cid_funcs); i++) {
2569
0
            status = font_write_cid_funcs[i] (font);
2570
0
            if (unlikely (status))
2571
0
                return status;
2572
0
        }
2573
0
    }
2574
2575
0
    return CAIRO_STATUS_SUCCESS;
2576
0
}
2577
2578
static cairo_int_status_t
2579
cairo_cff_font_generate (cairo_cff_font_t  *font,
2580
                         const char       **data,
2581
                         unsigned long     *length)
2582
0
{
2583
0
    cairo_int_status_t status;
2584
2585
0
    status = cairo_cff_font_read_font (font);
2586
0
    if (unlikely (status))
2587
0
        return status;
2588
2589
    /* If the PS name is not found, create a CairoFont-x-y name. */
2590
0
    if (font->ps_name == NULL) {
2591
0
        font->ps_name = _cairo_malloc (30);
2592
0
        if (unlikely (font->ps_name == NULL))
2593
0
      return _cairo_error (CAIRO_STATUS_NO_MEMORY);
2594
2595
0
        snprintf(font->ps_name, 30, "CairoFont-%u-%u",
2596
0
                 font->scaled_font_subset->font_id,
2597
0
                 font->scaled_font_subset->subset_id);
2598
0
    }
2599
2600
0
    status = cairo_cff_font_subset_font (font);
2601
0
    if (unlikely (status))
2602
0
        return status;
2603
2604
0
    status = cairo_cff_font_write_subset (font);
2605
0
    if (unlikely (status))
2606
0
        return status;
2607
2608
2609
0
    *data = _cairo_array_index (&font->output, 0);
2610
0
    *length = _cairo_array_num_elements (&font->output);
2611
2612
0
    return CAIRO_STATUS_SUCCESS;
2613
0
}
2614
2615
static cairo_int_status_t
2616
cairo_cff_font_create_set_widths (cairo_cff_font_t *font)
2617
0
{
2618
0
    unsigned long size;
2619
0
    unsigned long long_entry_size;
2620
0
    unsigned long short_entry_size;
2621
0
    unsigned int i;
2622
0
    tt_hhea_t hhea;
2623
0
    int num_hmetrics;
2624
0
    uint16_t short_entry;
2625
0
    int glyph_index;
2626
0
    cairo_int_status_t status;
2627
2628
0
    size = sizeof (tt_hhea_t);
2629
0
    status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
2630
0
                                                 TT_TAG_hhea, 0,
2631
0
                                                 (unsigned char*) &hhea, &size);
2632
0
    if (unlikely (status))
2633
0
        return status;
2634
0
    num_hmetrics = be16_to_cpu (hhea.num_hmetrics);
2635
2636
0
    for (i = 0; i < font->scaled_font_subset->num_glyphs; i++) {
2637
0
        glyph_index = font->scaled_font_subset->glyphs[i];
2638
0
        long_entry_size = 2 * sizeof (int16_t);
2639
0
        short_entry_size = sizeof (int16_t);
2640
0
        if (glyph_index < num_hmetrics) {
2641
0
            status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
2642
0
                                                         TT_TAG_hmtx,
2643
0
                                                         glyph_index * long_entry_size,
2644
0
                                                         (unsigned char *) &short_entry,
2645
0
               &short_entry_size);
2646
0
            if (unlikely (status))
2647
0
                return status;
2648
0
        }
2649
0
        else
2650
0
        {
2651
0
            status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
2652
0
                                                         TT_TAG_hmtx,
2653
0
                                                         (num_hmetrics - 1) * long_entry_size,
2654
0
                                                         (unsigned char *) &short_entry,
2655
0
               &short_entry_size);
2656
0
            if (unlikely (status))
2657
0
                return status;
2658
0
        }
2659
0
  font->widths[i] = be16_to_cpu (short_entry);
2660
0
    }
2661
2662
0
    return CAIRO_STATUS_SUCCESS;
2663
0
}
2664
2665
static cairo_bool_t
2666
check_fontdata_is_cff (const unsigned char *data, long length)
2667
0
{
2668
0
    cff_header_t *header;
2669
2670
0
    if (length < (long)sizeof (cff_header_t))
2671
0
        return FALSE;
2672
2673
0
    header = (cff_header_t *) data;
2674
0
    if (header->major == 1 &&
2675
0
  header->minor == 0 &&
2676
0
  header->header_size == 4)
2677
0
    {
2678
0
  return TRUE;
2679
0
    }
2680
2681
0
    return FALSE;
2682
0
}
2683
2684
static cairo_int_status_t
2685
_cairo_cff_font_load_opentype_cff (cairo_cff_font_t  *font)
2686
0
{
2687
0
    const cairo_scaled_font_backend_t *backend = font->backend;
2688
0
    cairo_status_t status;
2689
0
    tt_head_t head;
2690
0
    tt_hhea_t hhea;
2691
0
    unsigned long size, data_length;
2692
2693
0
    if (!backend->load_truetype_table)
2694
0
  return CAIRO_INT_STATUS_UNSUPPORTED;
2695
2696
0
    data_length = 0;
2697
0
    status = backend->load_truetype_table (font->scaled_font_subset->scaled_font,
2698
0
                                           TT_TAG_CFF, 0, NULL, &data_length);
2699
0
    if (status)
2700
0
        return status;
2701
2702
0
    size = sizeof (tt_head_t);
2703
0
    status = backend->load_truetype_table (font->scaled_font_subset->scaled_font,
2704
0
                                           TT_TAG_head, 0,
2705
0
                                           (unsigned char *) &head, &size);
2706
0
    if (unlikely (status))
2707
0
        return status;
2708
2709
0
    size = sizeof (tt_hhea_t);
2710
0
    status = backend->load_truetype_table (font->scaled_font_subset->scaled_font,
2711
0
                                           TT_TAG_hhea, 0,
2712
0
                                           (unsigned char *) &hhea, &size);
2713
0
    if (unlikely (status))
2714
0
        return status;
2715
2716
0
    size = 0;
2717
0
    status = backend->load_truetype_table (font->scaled_font_subset->scaled_font,
2718
0
                                           TT_TAG_hmtx, 0, NULL, &size);
2719
0
    if (unlikely (status))
2720
0
        return status;
2721
2722
0
    font->x_min = (int16_t) be16_to_cpu (head.x_min);
2723
0
    font->y_min = (int16_t) be16_to_cpu (head.y_min);
2724
0
    font->x_max = (int16_t) be16_to_cpu (head.x_max);
2725
0
    font->y_max = (int16_t) be16_to_cpu (head.y_max);
2726
0
    font->ascent = (int16_t) be16_to_cpu (hhea.ascender);
2727
0
    font->descent = (int16_t) be16_to_cpu (hhea.descender);
2728
0
    font->units_per_em = (int16_t) be16_to_cpu (head.units_per_em);
2729
0
    if (font->units_per_em == 0)
2730
0
        font->units_per_em = 1000;
2731
2732
0
    font->font_name = NULL;
2733
0
    status = _cairo_truetype_read_font_name (font->scaled_font_subset->scaled_font,
2734
0
               &font->ps_name,
2735
0
               &font->font_name);
2736
0
    if (_cairo_status_is_error (status))
2737
0
  return status;
2738
2739
0
    font->is_opentype = TRUE;
2740
0
    font->data_length = data_length;
2741
0
    font->data = _cairo_malloc (data_length);
2742
0
    if (unlikely (font->data == NULL))
2743
0
        return _cairo_error (CAIRO_STATUS_NO_MEMORY);
2744
2745
0
    status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
2746
0
             TT_TAG_CFF, 0, font->data,
2747
0
             &font->data_length);
2748
0
    if (unlikely (status))
2749
0
        return status;
2750
2751
0
    if (!check_fontdata_is_cff (font->data, data_length))
2752
0
  return CAIRO_INT_STATUS_UNSUPPORTED;
2753
2754
0
    return CAIRO_STATUS_SUCCESS;
2755
0
}
2756
2757
static cairo_int_status_t
2758
_cairo_cff_font_load_cff (cairo_cff_font_t  *font)
2759
0
{
2760
0
    const cairo_scaled_font_backend_t *backend = font->backend;
2761
0
    cairo_status_t status;
2762
0
    unsigned long data_length;
2763
2764
0
    if (!backend->load_type1_data)
2765
0
  return CAIRO_INT_STATUS_UNSUPPORTED;
2766
2767
0
    data_length = 0;
2768
0
    status = backend->load_type1_data (font->scaled_font_subset->scaled_font,
2769
0
              0, NULL, &data_length);
2770
0
    if (unlikely (status))
2771
0
        return status;
2772
2773
0
    font->font_name = NULL;
2774
0
    font->is_opentype = FALSE;
2775
0
    font->data_length = data_length;
2776
0
    font->data = _cairo_malloc (data_length);
2777
0
    if (unlikely (font->data == NULL))
2778
0
        return _cairo_error (CAIRO_STATUS_NO_MEMORY);
2779
2780
0
    status = font->backend->load_type1_data (font->scaled_font_subset->scaled_font,
2781
0
               0, font->data, &font->data_length);
2782
0
    if (unlikely (status))
2783
0
        return status;
2784
2785
0
    if (!check_fontdata_is_cff (font->data, data_length))
2786
0
  return CAIRO_INT_STATUS_UNSUPPORTED;
2787
2788
0
    return CAIRO_STATUS_SUCCESS;
2789
0
}
2790
2791
static cairo_int_status_t
2792
_cairo_cff_font_create (cairo_scaled_font_subset_t  *scaled_font_subset,
2793
                        cairo_cff_font_t           **font_return,
2794
                        const char                  *subset_name)
2795
0
{
2796
0
    const cairo_scaled_font_backend_t *backend;
2797
0
    cairo_int_status_t status;
2798
0
    cairo_bool_t is_synthetic;
2799
0
    cairo_cff_font_t *font;
2800
2801
0
    backend = scaled_font_subset->scaled_font->backend;
2802
2803
    /* We need to use a fallback font if this font differs from the CFF outlines. */
2804
0
    if (backend->is_synthetic) {
2805
0
  status = backend->is_synthetic (scaled_font_subset->scaled_font, &is_synthetic);
2806
0
  if (unlikely (status))
2807
0
      return status;
2808
2809
0
  if (is_synthetic)
2810
0
      return CAIRO_INT_STATUS_UNSUPPORTED;
2811
0
    }
2812
2813
0
    font = calloc (1, sizeof (cairo_cff_font_t));
2814
0
    if (unlikely (font == NULL))
2815
0
        return _cairo_error (CAIRO_STATUS_NO_MEMORY);
2816
2817
0
    font->backend = backend;
2818
0
    font->scaled_font_subset = scaled_font_subset;
2819
2820
0
    status = _cairo_cff_font_load_opentype_cff (font);
2821
0
    if (status == CAIRO_INT_STATUS_UNSUPPORTED)
2822
0
  status = _cairo_cff_font_load_cff (font);
2823
0
    if (status)
2824
0
  goto fail1;
2825
2826
0
    font->data_end = font->data + font->data_length;
2827
0
    _cairo_array_init (&font->output, sizeof (char));
2828
0
    status = _cairo_array_grow_by (&font->output, 4096);
2829
0
    if (unlikely (status))
2830
0
  goto fail2;
2831
2832
0
    font->subset_font_name = strdup (subset_name);
2833
0
    if (unlikely (font->subset_font_name == NULL)) {
2834
0
        status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
2835
0
  goto fail2;
2836
0
    }
2837
2838
0
    font->widths = calloc (font->scaled_font_subset->num_glyphs, sizeof (int));
2839
0
    if (unlikely (font->widths == NULL)) {
2840
0
        status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
2841
0
        goto fail3;
2842
0
    }
2843
2844
0
    if (font->is_opentype) {
2845
0
  status = cairo_cff_font_create_set_widths (font);
2846
0
  if (unlikely (status))
2847
0
      goto fail4;
2848
0
    }
2849
2850
0
    status = cff_dict_init (&font->top_dict);
2851
0
    if (unlikely (status))
2852
0
  goto fail4;
2853
2854
0
    status = cff_dict_init (&font->private_dict);
2855
0
    if (unlikely (status))
2856
0
  goto fail5;
2857
2858
0
    cff_index_init (&font->strings_index);
2859
0
    cff_index_init (&font->charstrings_index);
2860
0
    cff_index_init (&font->global_sub_index);
2861
0
    cff_index_init (&font->local_sub_index);
2862
0
    cff_index_init (&font->charstrings_subset_index);
2863
0
    cff_index_init (&font->strings_subset_index);
2864
0
    font->euro_sid = 0;
2865
0
    font->fdselect = NULL;
2866
0
    font->fd_dict = NULL;
2867
0
    font->fd_private_dict = NULL;
2868
0
    font->fd_local_sub_index = NULL;
2869
0
    font->fd_local_sub_bias = NULL;
2870
0
    font->fdselect_subset = NULL;
2871
0
    font->fd_subset_map = NULL;
2872
0
    font->private_dict_offset = NULL;
2873
0
    font->global_subs_used = NULL;
2874
0
    font->local_subs_used = NULL;
2875
0
    font->fd_local_subs_used = NULL;
2876
2877
0
    *font_return = font;
2878
2879
0
    return CAIRO_STATUS_SUCCESS;
2880
2881
0
fail5:
2882
0
    _cairo_hash_table_destroy (font->top_dict);
2883
0
fail4:
2884
0
    free (font->widths);
2885
0
fail3:
2886
0
    free (font->subset_font_name);
2887
0
fail2:
2888
0
    free (font->ps_name);
2889
0
    _cairo_array_fini (&font->output);
2890
0
fail1:
2891
0
    free (font->data);
2892
0
    free (font->font_name);
2893
0
    free (font);
2894
2895
0
    return status;
2896
0
}
2897
2898
static void
2899
cairo_cff_font_destroy (cairo_cff_font_t *font)
2900
0
{
2901
0
    unsigned int i;
2902
2903
0
    free (font->widths);
2904
0
    free (font->font_name);
2905
0
    free (font->ps_name);
2906
0
    free (font->subset_font_name);
2907
0
    _cairo_array_fini (&font->output);
2908
0
    cff_dict_fini (font->top_dict);
2909
0
    cff_dict_fini (font->private_dict);
2910
0
    cff_index_fini (&font->strings_index);
2911
0
    cff_index_fini (&font->charstrings_index);
2912
0
    cff_index_fini (&font->global_sub_index);
2913
0
    cff_index_fini (&font->local_sub_index);
2914
0
    cff_index_fini (&font->charstrings_subset_index);
2915
0
    cff_index_fini (&font->strings_subset_index);
2916
2917
    /* If we bailed out early as a result of an error some of the
2918
     * following cairo_cff_font_t members may still be NULL */
2919
0
    if (font->fd_dict) {
2920
0
        for (i = 0; i < font->num_fontdicts; i++) {
2921
0
            if (font->fd_dict[i])
2922
0
                cff_dict_fini (font->fd_dict[i]);
2923
0
        }
2924
0
        free (font->fd_dict);
2925
0
    }
2926
0
    free (font->global_subs_used);
2927
0
    free (font->local_subs_used);
2928
0
    free (font->fd_subset_map);
2929
0
    free (font->private_dict_offset);
2930
2931
0
    if (font->is_cid) {
2932
0
  free (font->fdselect);
2933
0
  free (font->fdselect_subset);
2934
0
        if (font->fd_private_dict) {
2935
0
            for (i = 0; i < font->num_fontdicts; i++) {
2936
0
                if (font->fd_private_dict[i])
2937
0
                    cff_dict_fini (font->fd_private_dict[i]);
2938
0
            }
2939
0
            free (font->fd_private_dict);
2940
0
        }
2941
0
        if (font->fd_local_sub_index) {
2942
0
            for (i = 0; i < font->num_fontdicts; i++)
2943
0
                cff_index_fini (&font->fd_local_sub_index[i]);
2944
0
            free (font->fd_local_sub_index);
2945
0
        }
2946
0
  free (font->fd_local_sub_bias);
2947
0
        if (font->fd_local_subs_used) {
2948
0
            for (i = 0; i < font->num_fontdicts; i++) {
2949
0
    free (font->fd_local_subs_used[i]);
2950
0
            }
2951
0
            free (font->fd_local_subs_used);
2952
0
        }
2953
0
  free (font->fd_default_width);
2954
0
  free (font->fd_nominal_width);
2955
0
    }
2956
2957
0
    free (font->data);
2958
2959
0
    free (font);
2960
0
}
2961
2962
cairo_status_t
2963
_cairo_cff_subset_init (cairo_cff_subset_t          *cff_subset,
2964
                        const char        *subset_name,
2965
                        cairo_scaled_font_subset_t  *font_subset)
2966
0
{
2967
0
    cairo_cff_font_t *font = NULL; /* squelch bogus compiler warning */
2968
0
    cairo_status_t status;
2969
0
    const char *data = NULL; /* squelch bogus compiler warning */
2970
0
    unsigned long length = 0; /* squelch bogus compiler warning */
2971
0
    unsigned int i;
2972
2973
0
    status = _cairo_cff_font_create (font_subset, &font, subset_name);
2974
0
    if (unlikely (status))
2975
0
  return status;
2976
2977
0
    status = cairo_cff_font_generate (font, &data, &length);
2978
0
    if (unlikely (status))
2979
0
  goto fail1;
2980
2981
0
    cff_subset->ps_name = strdup (font->ps_name);
2982
0
    if (unlikely (cff_subset->ps_name == NULL)) {
2983
0
  status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
2984
0
  goto fail1;
2985
0
    }
2986
2987
0
    if (font->font_name) {
2988
0
  cff_subset->family_name_utf8 = strdup (font->font_name);
2989
0
  if (cff_subset->family_name_utf8 == NULL) {
2990
0
      status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
2991
0
      goto fail2;
2992
0
  }
2993
0
    } else {
2994
0
  cff_subset->family_name_utf8 = NULL;
2995
0
    }
2996
2997
0
    cff_subset->widths = calloc (sizeof (double), font->scaled_font_subset->num_glyphs);
2998
0
    if (unlikely (cff_subset->widths == NULL)) {
2999
0
  status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
3000
0
  goto fail3;
3001
0
    }
3002
0
    for (i = 0; i < font->scaled_font_subset->num_glyphs; i++)
3003
0
        cff_subset->widths[i] = (double)font->widths[i]/font->units_per_em;
3004
3005
0
    cff_subset->x_min = (double)font->x_min/font->units_per_em;
3006
0
    cff_subset->y_min = (double)font->y_min/font->units_per_em;
3007
0
    cff_subset->x_max = (double)font->x_max/font->units_per_em;
3008
0
    cff_subset->y_max = (double)font->y_max/font->units_per_em;
3009
0
    cff_subset->ascent = (double)font->ascent/font->units_per_em;
3010
0
    cff_subset->descent = (double)font->descent/font->units_per_em;
3011
3012
0
    cff_subset->data = _cairo_malloc (length);
3013
0
    if (unlikely (cff_subset->data == NULL)) {
3014
0
  status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
3015
0
  goto fail4;
3016
0
    }
3017
3018
0
    memcpy (cff_subset->data, data, length);
3019
0
    cff_subset->data_length = length;
3020
3021
0
    cairo_cff_font_destroy (font);
3022
3023
0
    return CAIRO_STATUS_SUCCESS;
3024
3025
0
 fail4:
3026
0
    free (cff_subset->widths);
3027
0
 fail3:
3028
0
    free (cff_subset->family_name_utf8);
3029
0
 fail2:
3030
0
    free (cff_subset->ps_name);
3031
0
 fail1:
3032
0
    cairo_cff_font_destroy (font);
3033
3034
0
    return status;
3035
0
}
3036
3037
void
3038
_cairo_cff_subset_fini (cairo_cff_subset_t *subset)
3039
0
{
3040
0
    free (subset->ps_name);
3041
0
    free (subset->family_name_utf8);
3042
0
    free (subset->widths);
3043
0
    free (subset->data);
3044
0
}
3045
3046
cairo_bool_t
3047
_cairo_cff_scaled_font_is_cid_cff (cairo_scaled_font_t *scaled_font)
3048
0
{
3049
0
    const cairo_scaled_font_backend_t *backend;
3050
0
    cairo_int_status_t status;
3051
0
    unsigned char *data;
3052
0
    unsigned long data_length;
3053
0
    unsigned char *current_ptr;
3054
0
    unsigned char *data_end;
3055
0
    cff_header_t  *header;
3056
0
    cff_index_element_t *element;
3057
0
    cairo_hash_table_t  *top_dict;
3058
0
    cairo_array_t index;
3059
0
    int size;
3060
0
    cairo_bool_t is_cid = FALSE;
3061
3062
0
    backend = scaled_font->backend;
3063
0
    data = NULL;
3064
0
    data_length = 0;
3065
0
    status = CAIRO_INT_STATUS_UNSUPPORTED;
3066
    /* Try to load an OpenType/CFF font */
3067
0
    if (backend->load_truetype_table &&
3068
0
  (status = backend->load_truetype_table (scaled_font, TT_TAG_CFF,
3069
0
            0, NULL, &data_length)) == CAIRO_INT_STATUS_SUCCESS)
3070
0
    {
3071
0
  data = _cairo_malloc (data_length);
3072
0
  if (unlikely (data == NULL)) {
3073
0
      status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
3074
0
      return FALSE;
3075
0
  }
3076
3077
0
  status = backend->load_truetype_table (scaled_font, TT_TAG_CFF,
3078
0
             0, data, &data_length);
3079
0
  if (unlikely (status))
3080
0
      goto fail1;
3081
0
    }
3082
    /* Try to load a CFF font */
3083
0
    if (status == CAIRO_INT_STATUS_UNSUPPORTED &&
3084
0
  backend->load_type1_data &&
3085
0
  (status = backend->load_type1_data (scaled_font,
3086
0
              0, NULL, &data_length)) == CAIRO_INT_STATUS_SUCCESS)
3087
0
    {
3088
0
  data = _cairo_malloc (data_length);
3089
0
  if (unlikely (data == NULL)) {
3090
0
      status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
3091
0
      return FALSE;
3092
0
  }
3093
3094
0
  status = backend->load_type1_data (scaled_font, 0, data, &data_length);
3095
0
  if (unlikely (status))
3096
0
      goto fail1;
3097
0
    }
3098
0
    if (status)
3099
0
  goto fail1;
3100
3101
    /* Check if it looks like a CFF font */
3102
0
    if (!check_fontdata_is_cff (data, data_length))
3103
0
  goto fail1;
3104
3105
0
    data_end = data + data_length;
3106
3107
    /* skip header */
3108
0
    if (data_length < sizeof (cff_header_t))
3109
0
        goto fail1;
3110
3111
0
    header = (cff_header_t *) data;
3112
0
    current_ptr = data + header->header_size;
3113
3114
    /* skip name */
3115
0
    cff_index_init (&index);
3116
0
    status = cff_index_read (&index, &current_ptr, data_end);
3117
0
    cff_index_fini (&index);
3118
3119
0
    if (status)
3120
0
        goto fail1;
3121
3122
    /* read top dict */
3123
0
    cff_index_init (&index);
3124
0
    status = cff_index_read (&index, &current_ptr, data_end);
3125
0
    if (unlikely (status))
3126
0
        goto fail2;
3127
3128
0
    status = cff_dict_init (&top_dict);
3129
0
    if (unlikely (status))
3130
0
  goto fail2;
3131
3132
0
    element = _cairo_array_index (&index, 0);
3133
0
    status = cff_dict_read (top_dict, element->data, element->length);
3134
0
    if (unlikely (status))
3135
0
        goto fail3;
3136
3137
    /* check for ROS operator indicating a CID font */
3138
0
    if (cff_dict_get_operands (top_dict, ROS_OP, &size) != NULL)
3139
0
        is_cid = TRUE;
3140
3141
0
fail3:
3142
0
    cff_dict_fini (top_dict);
3143
3144
0
fail2:
3145
0
    cff_index_fini (&index);
3146
3147
0
fail1:
3148
0
    free (data);
3149
3150
0
    return is_cid;
3151
0
}
3152
3153
static cairo_int_status_t
3154
_cairo_cff_font_fallback_create (cairo_scaled_font_subset_t  *scaled_font_subset,
3155
                                 cairo_cff_font_t           **font_return,
3156
                                 const char                  *subset_name)
3157
0
{
3158
0
    cairo_status_t status;
3159
0
    cairo_cff_font_t *font;
3160
3161
0
    font = _cairo_malloc (sizeof (cairo_cff_font_t));
3162
0
    if (unlikely (font == NULL))
3163
0
  return _cairo_error (CAIRO_STATUS_NO_MEMORY);
3164
3165
0
    font->backend = NULL;
3166
0
    font->scaled_font_subset = scaled_font_subset;
3167
3168
0
    _cairo_array_init (&font->output, sizeof (char));
3169
0
    status = _cairo_array_grow_by (&font->output, 4096);
3170
0
    if (unlikely (status))
3171
0
  goto fail1;
3172
3173
0
    font->subset_font_name = strdup (subset_name);
3174
0
    if (unlikely (font->subset_font_name == NULL)) {
3175
0
        status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
3176
0
  goto fail1;
3177
0
    }
3178
3179
0
    font->ps_name = strdup (subset_name);
3180
0
    if (unlikely (font->ps_name == NULL)) {
3181
0
        status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
3182
0
  goto fail2;
3183
0
    }
3184
0
    font->font_name = NULL;
3185
3186
0
    font->x_min = 0;
3187
0
    font->y_min = 0;
3188
0
    font->x_max = 0;
3189
0
    font->y_max = 0;
3190
0
    font->ascent = 0;
3191
0
    font->descent = 0;
3192
3193
0
    font->widths = calloc (font->scaled_font_subset->num_glyphs, sizeof (int));
3194
0
    if (unlikely (font->widths == NULL)) {
3195
0
        status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
3196
0
        goto fail3;
3197
0
    }
3198
3199
0
    font->data_length = 0;
3200
0
    font->data = NULL;
3201
0
    font->data_end = NULL;
3202
3203
0
    status = cff_dict_init (&font->top_dict);
3204
0
    if (unlikely (status))
3205
0
  goto fail4;
3206
3207
0
    status = cff_dict_init (&font->private_dict);
3208
0
    if (unlikely (status))
3209
0
  goto fail5;
3210
3211
0
    cff_index_init (&font->strings_index);
3212
0
    cff_index_init (&font->charstrings_index);
3213
0
    cff_index_init (&font->global_sub_index);
3214
0
    cff_index_init (&font->local_sub_index);
3215
0
    cff_index_init (&font->charstrings_subset_index);
3216
0
    cff_index_init (&font->strings_subset_index);
3217
0
    font->global_subs_used = NULL;
3218
0
    font->local_subs_used = NULL;
3219
0
    font->subset_subroutines = FALSE;
3220
0
    font->fdselect = NULL;
3221
0
    font->fd_dict = NULL;
3222
0
    font->fd_private_dict = NULL;
3223
0
    font->fd_local_sub_index = NULL;
3224
0
    font->fdselect_subset = NULL;
3225
0
    font->fd_subset_map = NULL;
3226
0
    font->private_dict_offset = NULL;
3227
3228
0
    *font_return = font;
3229
3230
0
    return CAIRO_STATUS_SUCCESS;
3231
3232
0
fail5:
3233
0
    _cairo_hash_table_destroy (font->top_dict);
3234
0
fail4:
3235
0
    free (font->widths);
3236
0
fail3:
3237
0
    free (font->font_name);
3238
0
    free (font->ps_name);
3239
0
fail2:
3240
0
    free (font->subset_font_name);
3241
0
fail1:
3242
0
    _cairo_array_fini (&font->output);
3243
0
    free (font);
3244
0
    return status;
3245
0
}
3246
3247
static cairo_int_status_t
3248
cairo_cff_font_fallback_generate (cairo_cff_font_t           *font,
3249
                                  cairo_type2_charstrings_t  *type2_subset,
3250
                                  const char                **data,
3251
                                  unsigned long              *length)
3252
0
{
3253
0
    cairo_int_status_t status;
3254
0
    cff_header_t header;
3255
0
    cairo_array_t *charstring;
3256
0
    unsigned char buf[40];
3257
0
    unsigned char *end_buf, *end_buf2;
3258
0
    unsigned int i;
3259
0
    int sid;
3260
3261
    /* Create header */
3262
0
    header.major = 1;
3263
0
    header.minor = 0;
3264
0
    header.header_size = 4;
3265
0
    header.offset_size = 4;
3266
0
    font->header = &header;
3267
3268
    /* Create Top Dict */
3269
0
    font->is_cid = FALSE;
3270
3271
0
    snprintf((char*)buf, sizeof(buf), "CairoFont-%u-%u",
3272
0
       font->scaled_font_subset->font_id,
3273
0
       font->scaled_font_subset->subset_id);
3274
0
    sid = NUM_STD_STRINGS + _cairo_array_num_elements (&font->strings_subset_index);
3275
0
    status = cff_index_append_copy (&font->strings_subset_index,
3276
0
                                    (unsigned char *)buf,
3277
0
                                    strlen((char*)buf));
3278
0
    if (unlikely (status))
3279
0
  return status;
3280
3281
0
    end_buf = encode_integer (buf, sid);
3282
0
    status = cff_dict_set_operands (font->top_dict, FULLNAME_OP,
3283
0
            buf, end_buf - buf);
3284
0
    if (unlikely (status))
3285
0
  return status;
3286
3287
0
    status = cff_dict_set_operands (font->top_dict, FAMILYNAME_OP,
3288
0
            buf, end_buf - buf);
3289
0
    if (unlikely (status))
3290
0
  return status;
3291
3292
0
    end_buf = encode_integer (buf, type2_subset->x_min);
3293
0
    end_buf = encode_integer (end_buf, type2_subset->y_min);
3294
0
    end_buf = encode_integer (end_buf, type2_subset->x_max);
3295
0
    end_buf = encode_integer (end_buf, type2_subset->y_max);
3296
0
    status = cff_dict_set_operands (font->top_dict,
3297
0
                              FONTBBOX_OP, buf, end_buf - buf);
3298
0
    if (unlikely (status))
3299
0
  return status;
3300
3301
0
    end_buf = encode_integer_max (buf, 0);
3302
0
    status = cff_dict_set_operands (font->top_dict,
3303
0
                              CHARSTRINGS_OP, buf, end_buf - buf);
3304
0
    if (unlikely (status))
3305
0
  return status;
3306
3307
3308
0
    if (font->scaled_font_subset->is_latin) {
3309
0
  status = cff_dict_set_operands (font->top_dict,
3310
0
                                        ENCODING_OP, buf, end_buf - buf);
3311
0
        if (unlikely (status))
3312
0
      return status;
3313
3314
  /* Private has two operands - size and offset */
3315
0
  end_buf2 = encode_integer_max (end_buf, 0);
3316
0
  cff_dict_set_operands (font->top_dict, PRIVATE_OP, buf, end_buf2 - buf);
3317
0
        if (unlikely (status))
3318
0
      return status;
3319
3320
0
    } else {
3321
0
  status = cff_dict_set_operands (font->top_dict,
3322
0
          FDSELECT_OP, buf, end_buf - buf);
3323
0
  if (unlikely (status))
3324
0
      return status;
3325
3326
0
  status = cff_dict_set_operands (font->top_dict,
3327
0
          FDARRAY_OP, buf, end_buf - buf);
3328
0
  if (unlikely (status))
3329
0
      return status;
3330
0
    }
3331
3332
0
    status = cff_dict_set_operands (font->top_dict,
3333
0
                              CHARSET_OP, buf, end_buf - buf);
3334
0
    if (unlikely (status))
3335
0
  return status;
3336
3337
0
    if (!font->scaled_font_subset->is_latin) {
3338
0
  status = cairo_cff_font_set_ros_strings (font);
3339
0
  if (unlikely (status))
3340
0
      return status;
3341
3342
  /* Create CID FD dictionary */
3343
0
  status = cairo_cff_font_create_cid_fontdict (font);
3344
0
  if (unlikely (status))
3345
0
      return status;
3346
0
    } else {
3347
0
  font->private_dict_offset = _cairo_malloc (sizeof (int));
3348
0
  if (unlikely (font->private_dict_offset == NULL))
3349
0
      return _cairo_error (CAIRO_STATUS_NO_MEMORY);
3350
0
    }
3351
3352
    /* Create charstrings */
3353
0
    for (i = 0; i < font->scaled_font_subset->num_glyphs; i++) {
3354
0
        charstring = _cairo_array_index(&type2_subset->charstrings, i);
3355
3356
0
        status = cff_index_append (&font->charstrings_subset_index,
3357
0
                                   _cairo_array_index (charstring, 0),
3358
0
                                   _cairo_array_num_elements (charstring));
3359
3360
0
        if (unlikely (status))
3361
0
            return status;
3362
0
    }
3363
3364
0
    if (font->scaled_font_subset->is_latin)
3365
0
  status = cairo_cff_font_add_euro_charset_string (font);
3366
3367
0
    status = cairo_cff_font_write_subset (font);
3368
0
    if (unlikely (status))
3369
0
        return status;
3370
3371
0
    *data = _cairo_array_index (&font->output, 0);
3372
0
    *length = _cairo_array_num_elements (&font->output);
3373
3374
0
    return CAIRO_STATUS_SUCCESS;
3375
0
}
3376
3377
cairo_status_t
3378
_cairo_cff_fallback_init (cairo_cff_subset_t          *cff_subset,
3379
                          const char          *subset_name,
3380
                          cairo_scaled_font_subset_t  *font_subset)
3381
0
{
3382
0
    cairo_cff_font_t *font = NULL; /* squelch bogus compiler warning */
3383
0
    cairo_status_t status;
3384
0
    const char *data = NULL; /* squelch bogus compiler warning */
3385
0
    unsigned long length = 0; /* squelch bogus compiler warning */
3386
0
    unsigned int i;
3387
0
    cairo_type2_charstrings_t type2_subset;
3388
3389
0
    status = _cairo_cff_font_fallback_create (font_subset, &font, subset_name);
3390
0
    if (unlikely (status))
3391
0
  return status;
3392
3393
0
    status = _cairo_type2_charstrings_init (&type2_subset, font_subset);
3394
0
    if (unlikely (status))
3395
0
  goto fail1;
3396
3397
0
    status = cairo_cff_font_fallback_generate (font, &type2_subset, &data, &length);
3398
0
    if (unlikely (status))
3399
0
  goto fail2;
3400
3401
0
    cff_subset->family_name_utf8 = NULL;
3402
0
    cff_subset->ps_name = strdup (font->ps_name);
3403
0
    if (unlikely (cff_subset->ps_name == NULL)) {
3404
0
  status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
3405
0
  goto fail2;
3406
0
    }
3407
3408
0
    cff_subset->widths = calloc (sizeof (double), font->scaled_font_subset->num_glyphs);
3409
0
    if (unlikely (cff_subset->widths == NULL)) {
3410
0
  status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
3411
0
  goto fail3;
3412
0
    }
3413
3414
0
    for (i = 0; i < font->scaled_font_subset->num_glyphs; i++)
3415
0
        cff_subset->widths[i] = (double)type2_subset.widths[i]/1000;
3416
3417
0
    cff_subset->x_min = (double)type2_subset.x_min/1000;
3418
0
    cff_subset->y_min = (double)type2_subset.y_min/1000;
3419
0
    cff_subset->x_max = (double)type2_subset.x_max/1000;
3420
0
    cff_subset->y_max = (double)type2_subset.y_max/1000;
3421
0
    cff_subset->ascent = (double)type2_subset.y_max/1000;
3422
0
    cff_subset->descent = (double)type2_subset.y_min/1000;
3423
3424
0
    cff_subset->data = _cairo_malloc (length);
3425
0
    if (unlikely (cff_subset->data == NULL)) {
3426
0
  status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
3427
0
  goto fail4;
3428
0
    }
3429
3430
0
    memcpy (cff_subset->data, data, length);
3431
0
    cff_subset->data_length = length;
3432
3433
0
    _cairo_type2_charstrings_fini (&type2_subset);
3434
0
    cairo_cff_font_destroy (font);
3435
3436
0
    return CAIRO_STATUS_SUCCESS;
3437
3438
0
 fail4:
3439
0
    free (cff_subset->widths);
3440
0
 fail3:
3441
0
    free (cff_subset->ps_name);
3442
0
 fail2:
3443
0
    _cairo_type2_charstrings_fini (&type2_subset);
3444
0
 fail1:
3445
0
    cairo_cff_font_destroy (font);
3446
3447
0
    return status;
3448
0
}
3449
3450
void
3451
_cairo_cff_fallback_fini (cairo_cff_subset_t *subset)
3452
0
{
3453
0
    free (subset->ps_name);
3454
0
    free (subset->widths);
3455
0
    free (subset->data);
3456
0
}
3457
3458
#endif /* CAIRO_HAS_FONT_SUBSET */