Bug Summary

File:root/firefox-clang/gfx/cairo/cairo/src/cairo-cff-subset.c
Warning:line 1158, column 13
Value stored to 'p' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

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