Coverage Report

Created: 2021-08-22 09:07

/src/skia/third_party/externals/freetype/src/cff/cffload.c
Line
Count
Source (jump to first uncovered line)
1
/****************************************************************************
2
 *
3
 * cffload.c
4
 *
5
 *   OpenType and CFF data/program tables loader (body).
6
 *
7
 * Copyright (C) 1996-2021 by
8
 * David Turner, Robert Wilhelm, and Werner Lemberg.
9
 *
10
 * This file is part of the FreeType project, and may only be used,
11
 * modified, and distributed under the terms of the FreeType project
12
 * license, LICENSE.TXT.  By continuing to use, modify, or distribute
13
 * this file you indicate that you have read the license and
14
 * understand and accept it fully.
15
 *
16
 */
17
18
19
#include <freetype/internal/ftdebug.h>
20
#include <freetype/internal/ftobjs.h>
21
#include <freetype/internal/ftstream.h>
22
#include <freetype/tttags.h>
23
#include <freetype/t1tables.h>
24
#include <freetype/internal/psaux.h>
25
26
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
27
#include <freetype/ftmm.h>
28
#include <freetype/internal/services/svmm.h>
29
#endif
30
31
#include "cffload.h"
32
#include "cffparse.h"
33
34
#include "cfferrs.h"
35
36
37
0
#define FT_FIXED_ONE  ( (FT_Fixed)0x10000 )
38
39
40
#if 1
41
42
  static const FT_UShort  cff_isoadobe_charset[229] =
43
  {
44
      0,   1,   2,   3,   4,   5,   6,   7,
45
      8,   9,  10,  11,  12,  13,  14,  15,
46
     16,  17,  18,  19,  20,  21,  22,  23,
47
     24,  25,  26,  27,  28,  29,  30,  31,
48
     32,  33,  34,  35,  36,  37,  38,  39,
49
     40,  41,  42,  43,  44,  45,  46,  47,
50
     48,  49,  50,  51,  52,  53,  54,  55,
51
     56,  57,  58,  59,  60,  61,  62,  63,
52
     64,  65,  66,  67,  68,  69,  70,  71,
53
     72,  73,  74,  75,  76,  77,  78,  79,
54
     80,  81,  82,  83,  84,  85,  86,  87,
55
     88,  89,  90,  91,  92,  93,  94,  95,
56
     96,  97,  98,  99, 100, 101, 102, 103,
57
    104, 105, 106, 107, 108, 109, 110, 111,
58
    112, 113, 114, 115, 116, 117, 118, 119,
59
    120, 121, 122, 123, 124, 125, 126, 127,
60
    128, 129, 130, 131, 132, 133, 134, 135,
61
    136, 137, 138, 139, 140, 141, 142, 143,
62
    144, 145, 146, 147, 148, 149, 150, 151,
63
    152, 153, 154, 155, 156, 157, 158, 159,
64
    160, 161, 162, 163, 164, 165, 166, 167,
65
    168, 169, 170, 171, 172, 173, 174, 175,
66
    176, 177, 178, 179, 180, 181, 182, 183,
67
    184, 185, 186, 187, 188, 189, 190, 191,
68
    192, 193, 194, 195, 196, 197, 198, 199,
69
    200, 201, 202, 203, 204, 205, 206, 207,
70
    208, 209, 210, 211, 212, 213, 214, 215,
71
    216, 217, 218, 219, 220, 221, 222, 223,
72
    224, 225, 226, 227, 228
73
  };
74
75
  static const FT_UShort  cff_expert_charset[166] =
76
  {
77
      0,   1, 229, 230, 231, 232, 233, 234,
78
    235, 236, 237, 238,  13,  14,  15,  99,
79
    239, 240, 241, 242, 243, 244, 245, 246,
80
    247, 248,  27,  28, 249, 250, 251, 252,
81
    253, 254, 255, 256, 257, 258, 259, 260,
82
    261, 262, 263, 264, 265, 266, 109, 110,
83
    267, 268, 269, 270, 271, 272, 273, 274,
84
    275, 276, 277, 278, 279, 280, 281, 282,
85
    283, 284, 285, 286, 287, 288, 289, 290,
86
    291, 292, 293, 294, 295, 296, 297, 298,
87
    299, 300, 301, 302, 303, 304, 305, 306,
88
    307, 308, 309, 310, 311, 312, 313, 314,
89
    315, 316, 317, 318, 158, 155, 163, 319,
90
    320, 321, 322, 323, 324, 325, 326, 150,
91
    164, 169, 327, 328, 329, 330, 331, 332,
92
    333, 334, 335, 336, 337, 338, 339, 340,
93
    341, 342, 343, 344, 345, 346, 347, 348,
94
    349, 350, 351, 352, 353, 354, 355, 356,
95
    357, 358, 359, 360, 361, 362, 363, 364,
96
    365, 366, 367, 368, 369, 370, 371, 372,
97
    373, 374, 375, 376, 377, 378
98
  };
99
100
  static const FT_UShort  cff_expertsubset_charset[87] =
101
  {
102
      0,   1, 231, 232, 235, 236, 237, 238,
103
     13,  14,  15,  99, 239, 240, 241, 242,
104
    243, 244, 245, 246, 247, 248,  27,  28,
105
    249, 250, 251, 253, 254, 255, 256, 257,
106
    258, 259, 260, 261, 262, 263, 264, 265,
107
    266, 109, 110, 267, 268, 269, 270, 272,
108
    300, 301, 302, 305, 314, 315, 158, 155,
109
    163, 320, 321, 322, 323, 324, 325, 326,
110
    150, 164, 169, 327, 328, 329, 330, 331,
111
    332, 333, 334, 335, 336, 337, 338, 339,
112
    340, 341, 342, 343, 344, 345, 346
113
  };
114
115
  static const FT_UShort  cff_standard_encoding[256] =
116
  {
117
      0,   0,   0,   0,   0,   0,   0,   0,
118
      0,   0,   0,   0,   0,   0,   0,   0,
119
      0,   0,   0,   0,   0,   0,   0,   0,
120
      0,   0,   0,   0,   0,   0,   0,   0,
121
      1,   2,   3,   4,   5,   6,   7,   8,
122
      9,  10,  11,  12,  13,  14,  15,  16,
123
     17,  18,  19,  20,  21,  22,  23,  24,
124
     25,  26,  27,  28,  29,  30,  31,  32,
125
     33,  34,  35,  36,  37,  38,  39,  40,
126
     41,  42,  43,  44,  45,  46,  47,  48,
127
     49,  50,  51,  52,  53,  54,  55,  56,
128
     57,  58,  59,  60,  61,  62,  63,  64,
129
     65,  66,  67,  68,  69,  70,  71,  72,
130
     73,  74,  75,  76,  77,  78,  79,  80,
131
     81,  82,  83,  84,  85,  86,  87,  88,
132
     89,  90,  91,  92,  93,  94,  95,   0,
133
      0,   0,   0,   0,   0,   0,   0,   0,
134
      0,   0,   0,   0,   0,   0,   0,   0,
135
      0,   0,   0,   0,   0,   0,   0,   0,
136
      0,   0,   0,   0,   0,   0,   0,   0,
137
      0,  96,  97,  98,  99, 100, 101, 102,
138
    103, 104, 105, 106, 107, 108, 109, 110,
139
      0, 111, 112, 113, 114,   0, 115, 116,
140
    117, 118, 119, 120, 121, 122,   0, 123,
141
      0, 124, 125, 126, 127, 128, 129, 130,
142
    131,   0, 132, 133,   0, 134, 135, 136,
143
    137,   0,   0,   0,   0,   0,   0,   0,
144
      0,   0,   0,   0,   0,   0,   0,   0,
145
      0, 138,   0, 139,   0,   0,   0,   0,
146
    140, 141, 142, 143,   0,   0,   0,   0,
147
      0, 144,   0,   0,   0, 145,   0,   0,
148
    146, 147, 148, 149,   0,   0,   0,   0
149
  };
150
151
  static const FT_UShort  cff_expert_encoding[256] =
152
  {
153
      0,   0,   0,   0,   0,   0,   0,   0,
154
      0,   0,   0,   0,   0,   0,   0,   0,
155
      0,   0,   0,   0,   0,   0,   0,   0,
156
      0,   0,   0,   0,   0,   0,   0,   0,
157
      1, 229, 230,   0, 231, 232, 233, 234,
158
    235, 236, 237, 238,  13,  14,  15,  99,
159
    239, 240, 241, 242, 243, 244, 245, 246,
160
    247, 248,  27,  28, 249, 250, 251, 252,
161
      0, 253, 254, 255, 256, 257,   0,   0,
162
      0, 258,   0,   0, 259, 260, 261, 262,
163
      0,   0, 263, 264, 265,   0, 266, 109,
164
    110, 267, 268, 269,   0, 270, 271, 272,
165
    273, 274, 275, 276, 277, 278, 279, 280,
166
    281, 282, 283, 284, 285, 286, 287, 288,
167
    289, 290, 291, 292, 293, 294, 295, 296,
168
    297, 298, 299, 300, 301, 302, 303,   0,
169
      0,   0,   0,   0,   0,   0,   0,   0,
170
      0,   0,   0,   0,   0,   0,   0,   0,
171
      0,   0,   0,   0,   0,   0,   0,   0,
172
      0,   0,   0,   0,   0,   0,   0,   0,
173
      0, 304, 305, 306,   0,   0, 307, 308,
174
    309, 310, 311,   0, 312,   0,   0, 312,
175
      0,   0, 314, 315,   0,   0, 316, 317,
176
    318,   0,   0,   0, 158, 155, 163, 319,
177
    320, 321, 322, 323, 324, 325,   0,   0,
178
    326, 150, 164, 169, 327, 328, 329, 330,
179
    331, 332, 333, 334, 335, 336, 337, 338,
180
    339, 340, 341, 342, 343, 344, 345, 346,
181
    347, 348, 349, 350, 351, 352, 353, 354,
182
    355, 356, 357, 358, 359, 360, 361, 362,
183
    363, 364, 365, 366, 367, 368, 369, 370,
184
    371, 372, 373, 374, 375, 376, 377, 378
185
  };
186
187
#endif /* 1 */
188
189
190
  FT_LOCAL_DEF( FT_UShort )
191
  cff_get_standard_encoding( FT_UInt  charcode )
192
0
  {
193
0
    return (FT_UShort)( charcode < 256 ? cff_standard_encoding[charcode]
194
0
                                       : 0 );
195
0
  }
196
197
198
  /**************************************************************************
199
   *
200
   * The macro FT_COMPONENT is used in trace mode.  It is an implicit
201
   * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log
202
   * messages during execution.
203
   */
204
#undef  FT_COMPONENT
205
#define FT_COMPONENT  cffload
206
207
208
  /* read an offset from the index's stream current position */
209
  static FT_ULong
210
  cff_index_read_offset( CFF_Index  idx,
211
                         FT_Error  *errorp )
212
18.5k
  {
213
18.5k
    FT_Error   error;
214
18.5k
    FT_Stream  stream = idx->stream;
215
18.5k
    FT_Byte    tmp[4];
216
18.5k
    FT_ULong   result = 0;
217
218
219
18.5k
    if ( !FT_STREAM_READ( tmp, idx->off_size ) )
220
18.5k
    {
221
18.5k
      FT_Int  nn;
222
223
224
48.5k
      for ( nn = 0; nn < idx->off_size; nn++ )
225
30.0k
        result = ( result << 8 ) | tmp[nn];
226
18.5k
    }
227
228
18.5k
    *errorp = error;
229
18.5k
    return result;
230
18.5k
  }
231
232
233
  static FT_Error
234
  cff_index_init( CFF_Index  idx,
235
                  FT_Stream  stream,
236
                  FT_Bool    load,
237
                  FT_Bool    cff2 )
238
13.5k
  {
239
13.5k
    FT_Error   error;
240
13.5k
    FT_Memory  memory = stream->memory;
241
13.5k
    FT_UInt    count;
242
243
244
13.5k
    FT_ZERO( idx );
245
246
13.5k
    idx->stream = stream;
247
13.5k
    idx->start  = FT_STREAM_POS();
248
249
13.5k
    if ( cff2 )
250
0
    {
251
0
      if ( FT_READ_ULONG( count ) )
252
0
        goto Exit;
253
0
      idx->hdr_size = 5;
254
0
    }
255
13.5k
    else
256
13.5k
    {
257
13.5k
      if ( FT_READ_USHORT( count ) )
258
0
        goto Exit;
259
13.5k
      idx->hdr_size = 3;
260
13.5k
    }
261
262
13.5k
    if ( count > 0 )
263
10.8k
    {
264
10.8k
      FT_Byte   offsize;
265
10.8k
      FT_ULong  size;
266
267
268
      /* there is at least one element; read the offset size,           */
269
      /* then access the offset table to compute the index's total size */
270
10.8k
      if ( FT_READ_BYTE( offsize ) )
271
0
        goto Exit;
272
273
10.8k
      if ( offsize < 1 || offsize > 4 )
274
689
      {
275
689
        error = FT_THROW( Invalid_Table );
276
689
        goto Exit;
277
689
      }
278
279
10.1k
      idx->count    = count;
280
10.1k
      idx->off_size = offsize;
281
10.1k
      size          = (FT_ULong)( count + 1 ) * offsize;
282
283
10.1k
      idx->data_offset = idx->start + idx->hdr_size + size;
284
285
10.1k
      if ( FT_STREAM_SKIP( size - offsize ) )
286
13
        goto Exit;
287
288
10.1k
      size = cff_index_read_offset( idx, &error );
289
10.1k
      if ( error )
290
0
        goto Exit;
291
292
10.1k
      if ( size == 0 )
293
76
      {
294
76
        error = FT_THROW( Invalid_Table );
295
76
        goto Exit;
296
76
      }
297
298
10.0k
      idx->data_size = --size;
299
300
10.0k
      if ( load )
301
2.99k
      {
302
        /* load the data */
303
2.99k
        if ( FT_FRAME_EXTRACT( size, idx->bytes ) )
304
26
          goto Exit;
305
7.09k
      }
306
7.09k
      else
307
7.09k
      {
308
        /* skip the data */
309
7.09k
        if ( FT_STREAM_SKIP( size ) )
310
20
          goto Exit;
311
13.5k
      }
312
10.0k
    }
313
314
13.5k
  Exit:
315
13.5k
    if ( error )
316
13.5k
      FT_FREE( idx->offsets );
317
318
13.5k
    return error;
319
13.5k
  }
320
321
322
  static void
323
  cff_index_done( CFF_Index  idx )
324
29.5k
  {
325
29.5k
    if ( idx->stream )
326
13.5k
    {
327
13.5k
      FT_Stream  stream = idx->stream;
328
13.5k
      FT_Memory  memory = stream->memory;
329
330
331
13.5k
      if ( idx->bytes )
332
13.5k
        FT_FRAME_RELEASE( idx->bytes );
333
334
13.5k
      FT_FREE( idx->offsets );
335
13.5k
      FT_ZERO( idx );
336
13.5k
    }
337
29.5k
  }
338
339
340
  static FT_Error
341
  cff_index_load_offsets( CFF_Index  idx )
342
4.20k
  {
343
4.20k
    FT_Error   error  = FT_Err_Ok;
344
4.20k
    FT_Stream  stream = idx->stream;
345
4.20k
    FT_Memory  memory = stream->memory;
346
347
348
4.20k
    if ( idx->count > 0 && !idx->offsets )
349
2.50k
    {
350
2.50k
      FT_Byte    offsize = idx->off_size;
351
2.50k
      FT_ULong   data_size;
352
2.50k
      FT_Byte*   p;
353
2.50k
      FT_Byte*   p_end;
354
2.50k
      FT_ULong*  poff;
355
356
357
2.50k
      data_size = (FT_ULong)( idx->count + 1 ) * offsize;
358
359
2.50k
      if ( FT_QNEW_ARRAY( idx->offsets, idx->count + 1 ) ||
360
2.50k
           FT_STREAM_SEEK( idx->start + idx->hdr_size )  ||
361
2.50k
           FT_FRAME_ENTER( data_size )                   )
362
0
        goto Exit;
363
364
2.50k
      poff   = idx->offsets;
365
2.50k
      p      = (FT_Byte*)stream->cursor;
366
2.50k
      p_end  = p + data_size;
367
368
2.50k
      switch ( offsize )
369
2.50k
      {
370
173
      case 1:
371
1.50M
        for ( ; p < p_end; p++, poff++ )
372
1.50M
          poff[0] = p[0];
373
173
        break;
374
375
2.33k
      case 2:
376
518k
        for ( ; p < p_end; p += 2, poff++ )
377
516k
          poff[0] = FT_PEEK_USHORT( p );
378
2.33k
        break;
379
380
1
      case 3:
381
955
        for ( ; p < p_end; p += 3, poff++ )
382
954
          poff[0] = FT_PEEK_UOFF3( p );
383
1
        break;
384
385
0
      default:
386
0
        for ( ; p < p_end; p += 4, poff++ )
387
0
          poff[0] = FT_PEEK_ULONG( p );
388
2.50k
      }
389
390
2.50k
      FT_FRAME_EXIT();
391
2.50k
    }
392
393
4.20k
  Exit:
394
4.20k
    if ( error )
395
4.20k
      FT_FREE( idx->offsets );
396
397
4.20k
    return error;
398
4.20k
  }
399
400
401
  /* Allocate a table containing pointers to an index's elements. */
402
  /* The `pool' argument makes this function convert the index    */
403
  /* entries to C-style strings (this is, NULL-terminated).       */
404
  static FT_Error
405
  cff_index_get_pointers( CFF_Index   idx,
406
                          FT_Byte***  table,
407
                          FT_Byte**   pool,
408
                          FT_ULong*   pool_size )
409
4.20k
  {
410
4.20k
    FT_Error   error     = FT_Err_Ok;
411
4.20k
    FT_Memory  memory    = idx->stream->memory;
412
413
4.20k
    FT_Byte**  tbl       = NULL;
414
4.20k
    FT_Byte*   new_bytes = NULL;
415
4.20k
    FT_ULong   new_size;
416
417
418
4.20k
    *table = NULL;
419
420
4.20k
    if ( !idx->offsets )
421
4.20k
    {
422
4.20k
      error = cff_index_load_offsets( idx );
423
4.20k
      if ( error )
424
0
        goto Exit;
425
4.20k
    }
426
427
4.20k
    new_size = idx->data_size + idx->count;
428
429
4.20k
    if ( idx->count > 0                                &&
430
2.50k
         !FT_QNEW_ARRAY( tbl, idx->count + 1 )         &&
431
2.50k
         ( !pool || !FT_ALLOC( new_bytes, new_size ) ) )
432
2.50k
    {
433
2.50k
      FT_ULong  n, cur_offset;
434
2.50k
      FT_ULong  extra     = 0;
435
2.50k
      FT_Byte*  org_bytes = idx->bytes;
436
437
438
      /* at this point, `idx->offsets' can't be NULL */
439
2.50k
      cur_offset = idx->offsets[0] - 1;
440
441
      /* sanity check */
442
2.50k
      if ( cur_offset != 0 )
443
153
      {
444
153
        FT_TRACE0(( "cff_index_get_pointers:"
445
153
                    " invalid first offset value %ld set to zero\n",
446
153
                    cur_offset ));
447
153
        cur_offset = 0;
448
153
      }
449
450
2.50k
      if ( !pool )
451
179
        tbl[0] = org_bytes + cur_offset;
452
2.32k
      else
453
2.32k
        tbl[0] = new_bytes + cur_offset;
454
455
2.01M
      for ( n = 1; n <= idx->count; n++ )
456
2.01M
      {
457
2.01M
        FT_ULong  next_offset = idx->offsets[n] - 1;
458
459
460
        /* two sanity checks for invalid offset tables */
461
2.01M
        if ( next_offset < cur_offset )
462
341k
          next_offset = cur_offset;
463
1.67M
        else if ( next_offset > idx->data_size )
464
1.20M
          next_offset = idx->data_size;
465
466
2.01M
        if ( !pool )
467
1.50M
          tbl[n] = org_bytes + next_offset;
468
510k
        else
469
510k
        {
470
510k
          tbl[n] = new_bytes + next_offset + extra;
471
472
510k
          if ( next_offset != cur_offset )
473
417k
          {
474
417k
            FT_MEM_COPY( tbl[n - 1],
475
417k
                         org_bytes + cur_offset,
476
417k
                         tbl[n] - tbl[n - 1] );
477
417k
            tbl[n][0] = '\0';
478
417k
            tbl[n]   += 1;
479
417k
            extra++;
480
417k
          }
481
510k
        }
482
483
2.01M
        cur_offset = next_offset;
484
2.01M
      }
485
2.50k
      *table = tbl;
486
487
2.50k
      if ( pool )
488
2.32k
        *pool = new_bytes;
489
2.50k
      if ( pool_size )
490
2.32k
        *pool_size = new_size;
491
2.50k
    }
492
493
4.20k
  Exit:
494
4.20k
    if ( error && new_bytes )
495
4.20k
      FT_FREE( new_bytes );
496
4.20k
    if ( error && tbl )
497
4.20k
      FT_FREE( tbl );
498
499
4.20k
    return error;
500
4.20k
  }
501
502
503
  FT_LOCAL_DEF( FT_Error )
504
  cff_index_access_element( CFF_Index  idx,
505
                            FT_UInt    element,
506
                            FT_Byte**  pbytes,
507
                            FT_ULong*  pbyte_len )
508
4.17k
  {
509
4.17k
    FT_Error  error = FT_Err_Ok;
510
511
512
4.17k
    if ( idx && idx->count > element )
513
4.17k
    {
514
      /* compute start and end offsets */
515
4.17k
      FT_Stream  stream = idx->stream;
516
4.17k
      FT_ULong   off1, off2 = 0;
517
518
519
      /* load offsets from file or the offset table */
520
4.17k
      if ( !idx->offsets )
521
4.17k
      {
522
4.17k
        FT_ULong  pos = element * idx->off_size;
523
524
525
4.17k
        if ( FT_STREAM_SEEK( idx->start + idx->hdr_size + pos ) )
526
0
          goto Exit;
527
528
4.17k
        off1 = cff_index_read_offset( idx, &error );
529
4.17k
        if ( error )
530
0
          goto Exit;
531
532
4.17k
        if ( off1 != 0 )
533
4.16k
        {
534
4.16k
          do
535
4.16k
          {
536
4.16k
            element++;
537
4.16k
            off2 = cff_index_read_offset( idx, &error );
538
539
4.16k
          } while ( off2 == 0 && element < idx->count );
540
4.16k
        }
541
4.17k
      }
542
0
      else   /* use offsets table */
543
0
      {
544
0
        off1 = idx->offsets[element];
545
0
        if ( off1 )
546
0
        {
547
0
          do
548
0
          {
549
0
            element++;
550
0
            off2 = idx->offsets[element];
551
552
0
          } while ( off2 == 0 && element < idx->count );
553
0
        }
554
0
      }
555
556
      /* XXX: should check off2 does not exceed the end of this entry; */
557
      /*      at present, only truncate off2 at the end of this stream */
558
4.17k
      if ( off2 > stream->size + 1                    ||
559
4.17k
           idx->data_offset > stream->size - off2 + 1 )
560
0
      {
561
0
        FT_ERROR(( "cff_index_access_element:"
562
0
                   " offset to next entry (%ld)"
563
0
                   " exceeds the end of stream (%ld)\n",
564
0
                   off2, stream->size - idx->data_offset + 1 ));
565
0
        off2 = stream->size - idx->data_offset + 1;
566
0
      }
567
568
      /* access element */
569
4.17k
      if ( off1 && off2 > off1 )
570
4.15k
      {
571
4.15k
        *pbyte_len = off2 - off1;
572
573
4.15k
        if ( idx->bytes )
574
0
        {
575
          /* this index was completely loaded in memory, that's easy */
576
0
          *pbytes = idx->bytes + off1 - 1;
577
0
        }
578
4.15k
        else
579
4.15k
        {
580
          /* this index is still on disk/file, access it through a frame */
581
4.15k
          if ( FT_STREAM_SEEK( idx->data_offset + off1 - 1 ) ||
582
4.15k
               FT_FRAME_EXTRACT( off2 - off1, *pbytes )      )
583
0
            goto Exit;
584
11
        }
585
11
      }
586
11
      else
587
11
      {
588
        /* empty index element */
589
11
        *pbytes    = 0;
590
11
        *pbyte_len = 0;
591
11
      }
592
4.17k
    }
593
0
    else
594
0
      error = FT_THROW( Invalid_Argument );
595
596
4.17k
  Exit:
597
4.17k
    return error;
598
4.17k
  }
599
600
601
  FT_LOCAL_DEF( void )
602
  cff_index_forget_element( CFF_Index  idx,
603
                            FT_Byte**  pbytes )
604
4.17k
  {
605
4.17k
    if ( idx->bytes == 0 )
606
4.17k
    {
607
4.17k
      FT_Stream  stream = idx->stream;
608
609
610
4.17k
      FT_FRAME_RELEASE( *pbytes );
611
4.17k
    }
612
4.17k
  }
613
614
615
  /* get an entry from Name INDEX */
616
  FT_LOCAL_DEF( FT_String* )
617
  cff_index_get_name( CFF_Font  font,
618
                      FT_UInt   element )
619
1.81k
  {
620
1.81k
    CFF_Index   idx = &font->name_index;
621
1.81k
    FT_Memory   memory;
622
1.81k
    FT_Byte*    bytes;
623
1.81k
    FT_ULong    byte_len;
624
1.81k
    FT_Error    error;
625
1.81k
    FT_String*  name = 0;
626
627
628
1.81k
    if ( !idx->stream )  /* CFF2 does not include a name index */
629
0
      goto Exit;
630
631
1.81k
    memory = idx->stream->memory;
632
633
1.81k
    error = cff_index_access_element( idx, element, &bytes, &byte_len );
634
1.81k
    if ( error )
635
0
      goto Exit;
636
637
1.81k
    if ( !FT_QALLOC( name, byte_len + 1 ) )
638
1.81k
    {
639
1.81k
      FT_MEM_COPY( name, bytes, byte_len );
640
1.81k
      name[byte_len] = 0;
641
1.81k
    }
642
1.81k
    cff_index_forget_element( idx, &bytes );
643
644
1.81k
  Exit:
645
1.81k
    return name;
646
1.81k
  }
647
648
649
  /* get an entry from String INDEX */
650
  FT_LOCAL_DEF( FT_String* )
651
  cff_index_get_string( CFF_Font  font,
652
                        FT_UInt   element )
653
1.67M
  {
654
1.67M
    return ( element < font->num_strings )
655
299k
             ? (FT_String*)font->strings[element]
656
1.67M
             : NULL;
657
1.67M
  }
658
659
660
  FT_LOCAL_DEF( FT_String* )
661
  cff_index_get_sid_string( CFF_Font  font,
662
                            FT_UInt   sid )
663
2.27M
  {
664
    /* value 0xFFFFU indicates a missing dictionary entry */
665
2.27M
    if ( sid == 0xFFFFU )
666
1.00k
      return NULL;
667
668
    /* if it is not a standard string, return it */
669
2.27M
    if ( sid > 390 )
670
1.67M
      return cff_index_get_string( font, sid - 391 );
671
672
    /* CID-keyed CFF fonts don't have glyph names */
673
593k
    if ( !font->psnames )
674
0
      return NULL;
675
676
    /* this is a standard string */
677
593k
    return (FT_String *)font->psnames->adobe_std_strings( sid );
678
593k
  }
679
680
681
  /*************************************************************************/
682
  /*************************************************************************/
683
  /***                                                                   ***/
684
  /***   FD Select table support                                         ***/
685
  /***                                                                   ***/
686
  /*************************************************************************/
687
  /*************************************************************************/
688
689
690
  static void
691
  CFF_Done_FD_Select( CFF_FDSelect  fdselect,
692
                      FT_Stream     stream )
693
4.93k
  {
694
4.93k
    if ( fdselect->data )
695
4.93k
      FT_FRAME_RELEASE( fdselect->data );
696
697
4.93k
    fdselect->data_size   = 0;
698
4.93k
    fdselect->format      = 0;
699
4.93k
    fdselect->range_count = 0;
700
4.93k
  }
701
702
703
  static FT_Error
704
  CFF_Load_FD_Select( CFF_FDSelect  fdselect,
705
                      FT_UInt       num_glyphs,
706
                      FT_Stream     stream,
707
                      FT_ULong      offset )
708
0
  {
709
0
    FT_Error  error;
710
0
    FT_Byte   format;
711
0
    FT_UInt   num_ranges;
712
713
714
    /* read format */
715
0
    if ( FT_STREAM_SEEK( offset ) || FT_READ_BYTE( format ) )
716
0
      goto Exit;
717
718
0
    fdselect->format      = format;
719
0
    fdselect->cache_count = 0;   /* clear cache */
720
721
0
    switch ( format )
722
0
    {
723
0
    case 0:     /* format 0, that's simple */
724
0
      fdselect->data_size = num_glyphs;
725
0
      goto Load_Data;
726
727
0
    case 3:     /* format 3, a tad more complex */
728
0
      if ( FT_READ_USHORT( num_ranges ) )
729
0
        goto Exit;
730
731
0
      if ( !num_ranges )
732
0
      {
733
0
        FT_TRACE0(( "CFF_Load_FD_Select: empty FDSelect array\n" ));
734
0
        error = FT_THROW( Invalid_File_Format );
735
0
        goto Exit;
736
0
      }
737
738
0
      fdselect->data_size = num_ranges * 3 + 2;
739
740
0
    Load_Data:
741
0
      if ( FT_FRAME_EXTRACT( fdselect->data_size, fdselect->data ) )
742
0
        goto Exit;
743
0
      break;
744
745
0
    default:    /* hmm... that's wrong */
746
0
      error = FT_THROW( Invalid_File_Format );
747
0
    }
748
749
0
  Exit:
750
0
    return error;
751
0
  }
752
753
754
  FT_LOCAL_DEF( FT_Byte )
755
  cff_fd_select_get( CFF_FDSelect  fdselect,
756
                     FT_UInt       glyph_index )
757
0
  {
758
0
    FT_Byte  fd = 0;
759
760
761
    /* if there is no FDSelect, return zero               */
762
    /* Note: CFF2 with just one Font Dict has no FDSelect */
763
0
    if ( !fdselect->data )
764
0
      goto Exit;
765
766
0
    switch ( fdselect->format )
767
0
    {
768
0
    case 0:
769
0
      fd = fdselect->data[glyph_index];
770
0
      break;
771
772
0
    case 3:
773
      /* first, compare to the cache */
774
0
      if ( (FT_UInt)( glyph_index - fdselect->cache_first ) <
775
0
                        fdselect->cache_count )
776
0
      {
777
0
        fd = fdselect->cache_fd;
778
0
        break;
779
0
      }
780
781
      /* then, look up the ranges array */
782
0
      {
783
0
        FT_Byte*  p       = fdselect->data;
784
0
        FT_Byte*  p_limit = p + fdselect->data_size;
785
0
        FT_Byte   fd2;
786
0
        FT_UInt   first, limit;
787
788
789
0
        first = FT_NEXT_USHORT( p );
790
0
        do
791
0
        {
792
0
          if ( glyph_index < first )
793
0
            break;
794
795
0
          fd2   = *p++;
796
0
          limit = FT_NEXT_USHORT( p );
797
798
0
          if ( glyph_index < limit )
799
0
          {
800
0
            fd = fd2;
801
802
            /* update cache */
803
0
            fdselect->cache_first = first;
804
0
            fdselect->cache_count = limit - first;
805
0
            fdselect->cache_fd    = fd2;
806
0
            break;
807
0
          }
808
0
          first = limit;
809
810
0
        } while ( p < p_limit );
811
0
      }
812
0
      break;
813
814
0
    default:
815
0
      ;
816
0
    }
817
818
0
  Exit:
819
0
    return fd;
820
0
  }
821
822
823
  /*************************************************************************/
824
  /*************************************************************************/
825
  /***                                                                   ***/
826
  /***   CFF font support                                                ***/
827
  /***                                                                   ***/
828
  /*************************************************************************/
829
  /*************************************************************************/
830
831
  static FT_Error
832
  cff_charset_compute_cids( CFF_Charset  charset,
833
                            FT_UInt      num_glyphs,
834
                            FT_Memory    memory )
835
1.36k
  {
836
1.36k
    FT_Error   error   = FT_Err_Ok;
837
1.36k
    FT_UInt    i;
838
1.36k
    FT_Long    j;
839
1.36k
    FT_UShort  max_cid = 0;
840
841
842
1.36k
    if ( charset->max_cid > 0 )
843
0
      goto Exit;
844
845
2.29M
    for ( i = 0; i < num_glyphs; i++ )
846
2.28M
    {
847
2.28M
      if ( charset->sids[i] > max_cid )
848
230k
        max_cid = charset->sids[i];
849
2.28M
    }
850
851
1.36k
    if ( FT_NEW_ARRAY( charset->cids, (FT_ULong)max_cid + 1 ) )
852
0
      goto Exit;
853
854
    /* When multiple GIDs map to the same CID, we choose the lowest */
855
    /* GID.  This is not described in any spec, but it matches the  */
856
    /* behaviour of recent Acroread versions.                       */
857
2.29M
    for ( j = (FT_Long)num_glyphs - 1; j >= 0; j-- )
858
2.28M
      charset->cids[charset->sids[j]] = (FT_UShort)j;
859
860
1.36k
    charset->max_cid    = max_cid;
861
1.36k
    charset->num_glyphs = num_glyphs;
862
863
1.36k
  Exit:
864
1.36k
    return error;
865
1.36k
  }
866
867
868
  FT_LOCAL_DEF( FT_UInt )
869
  cff_charset_cid_to_gindex( CFF_Charset  charset,
870
                             FT_UInt      cid )
871
202k
  {
872
202k
    FT_UInt  result = 0;
873
874
875
202k
    if ( cid <= charset->max_cid )
876
202k
      result = charset->cids[cid];
877
878
202k
    return result;
879
202k
  }
880
881
882
  static void
883
  cff_charset_free_cids( CFF_Charset  charset,
884
                         FT_Memory    memory )
885
4.93k
  {
886
4.93k
    FT_FREE( charset->cids );
887
4.93k
    charset->max_cid = 0;
888
4.93k
  }
889
890
891
  static void
892
  cff_charset_done( CFF_Charset  charset,
893
                    FT_Stream    stream )
894
4.93k
  {
895
4.93k
    FT_Memory  memory = stream->memory;
896
897
898
4.93k
    cff_charset_free_cids( charset, memory );
899
900
4.93k
    FT_FREE( charset->sids );
901
4.93k
    charset->format = 0;
902
4.93k
    charset->offset = 0;
903
4.93k
  }
904
905
906
  static FT_Error
907
  cff_charset_load( CFF_Charset  charset,
908
                    FT_UInt      num_glyphs,
909
                    FT_Stream    stream,
910
                    FT_ULong     base_offset,
911
                    FT_ULong     offset,
912
                    FT_Bool      invert )
913
1.37k
  {
914
1.37k
    FT_Memory  memory = stream->memory;
915
1.37k
    FT_Error   error  = FT_Err_Ok;
916
1.37k
    FT_UShort  glyph_sid;
917
918
919
    /* If the offset is greater than 2, we have to parse the charset */
920
    /* table.                                                        */
921
1.37k
    if ( offset > 2 )
922
1.36k
    {
923
1.36k
      FT_UInt  j;
924
925
926
1.36k
      charset->offset = base_offset + offset;
927
928
      /* Get the format of the table. */
929
1.36k
      if ( FT_STREAM_SEEK( charset->offset ) ||
930
1.36k
           FT_READ_BYTE( charset->format )   )
931
3
        goto Exit;
932
933
      /* Allocate memory for sids. */
934
1.36k
      if ( FT_QNEW_ARRAY( charset->sids, num_glyphs ) )
935
0
        goto Exit;
936
937
      /* assign the .notdef glyph */
938
1.36k
      charset->sids[0] = 0;
939
940
1.36k
      switch ( charset->format )
941
1.36k
      {
942
1.27k
      case 0:
943
1.27k
        if ( num_glyphs > 0 )
944
1.27k
        {
945
1.27k
          if ( FT_FRAME_ENTER( ( num_glyphs - 1 ) * 2 ) )
946
3
            goto Exit;
947
948
2.26M
          for ( j = 1; j < num_glyphs; j++ )
949
2.25M
            charset->sids[j] = FT_GET_USHORT();
950
951
1.27k
          FT_FRAME_EXIT();
952
1.27k
        }
953
1.27k
        break;
954
955
86
      case 1:
956
89
      case 2:
957
89
        {
958
89
          FT_UInt  nleft;
959
89
          FT_UInt  i;
960
961
962
89
          j = 1;
963
964
4.02k
          while ( j < num_glyphs )
965
3.93k
          {
966
            /* Read the first glyph sid of the range. */
967
3.93k
            if ( FT_READ_USHORT( glyph_sid ) )
968
0
              goto Exit;
969
970
            /* Read the number of glyphs in the range.  */
971
3.93k
            if ( charset->format == 2 )
972
3
            {
973
3
              if ( FT_READ_USHORT( nleft ) )
974
0
                goto Exit;
975
3.93k
            }
976
3.93k
            else
977
3.93k
            {
978
3.93k
              if ( FT_READ_BYTE( nleft ) )
979
0
                goto Exit;
980
3.93k
            }
981
982
            /* try to rescue some of the SIDs if `nleft' is too large */
983
3.93k
            if ( glyph_sid > 0xFFFFL - nleft )
984
0
            {
985
0
              FT_ERROR(( "cff_charset_load: invalid SID range trimmed"
986
0
                         " nleft=%d -> %ld\n", nleft, 0xFFFFL - glyph_sid ));
987
0
              nleft = ( FT_UInt )( 0xFFFFL - glyph_sid );
988
0
            }
989
990
            /* Fill in the range of sids -- `nleft + 1' glyphs. */
991
33.5k
            for ( i = 0; j < num_glyphs && i <= nleft; i++, j++, glyph_sid++ )
992
29.5k
              charset->sids[j] = glyph_sid;
993
3.93k
          }
994
89
        }
995
89
        break;
996
997
1
      default:
998
1
        FT_ERROR(( "cff_charset_load: invalid table format\n" ));
999
1
        error = FT_THROW( Invalid_File_Format );
1000
1
        goto Exit;
1001
4
      }
1002
4
    }
1003
4
    else
1004
4
    {
1005
      /* Parse default tables corresponding to offset == 0, 1, or 2.  */
1006
      /* CFF specification intimates the following:                   */
1007
      /*                                                              */
1008
      /* In order to use a predefined charset, the following must be  */
1009
      /* true: The charset constructed for the glyphs in the font's   */
1010
      /* charstrings dictionary must match the predefined charset in  */
1011
      /* the first num_glyphs.                                        */
1012
1013
4
      charset->offset = offset;  /* record charset type */
1014
1015
4
      switch ( (FT_UInt)offset )
1016
4
      {
1017
4
      case 0:
1018
4
        if ( num_glyphs > 229 )
1019
1
        {
1020
1
          FT_ERROR(( "cff_charset_load: implicit charset larger than\n" ));
1021
1
          FT_ERROR(( "predefined charset (Adobe ISO-Latin)\n" ));
1022
1
          error = FT_THROW( Invalid_File_Format );
1023
1
          goto Exit;
1024
1
        }
1025
1026
        /* Allocate memory for sids. */
1027
3
        if ( FT_QNEW_ARRAY( charset->sids, num_glyphs ) )
1028
0
          goto Exit;
1029
1030
        /* Copy the predefined charset into the allocated memory. */
1031
3
        FT_ARRAY_COPY( charset->sids, cff_isoadobe_charset, num_glyphs );
1032
1033
3
        break;
1034
1035
0
      case 1:
1036
0
        if ( num_glyphs > 166 )
1037
0
        {
1038
0
          FT_ERROR(( "cff_charset_load: implicit charset larger than\n" ));
1039
0
          FT_ERROR(( "predefined charset (Adobe Expert)\n" ));
1040
0
          error = FT_THROW( Invalid_File_Format );
1041
0
          goto Exit;
1042
0
        }
1043
1044
        /* Allocate memory for sids. */
1045
0
        if ( FT_QNEW_ARRAY( charset->sids, num_glyphs ) )
1046
0
          goto Exit;
1047
1048
        /* Copy the predefined charset into the allocated memory.     */
1049
0
        FT_ARRAY_COPY( charset->sids, cff_expert_charset, num_glyphs );
1050
1051
0
        break;
1052
1053
0
      case 2:
1054
0
        if ( num_glyphs > 87 )
1055
0
        {
1056
0
          FT_ERROR(( "cff_charset_load: implicit charset larger than\n" ));
1057
0
          FT_ERROR(( "predefined charset (Adobe Expert Subset)\n" ));
1058
0
          error = FT_THROW( Invalid_File_Format );
1059
0
          goto Exit;
1060
0
        }
1061
1062
        /* Allocate memory for sids. */
1063
0
        if ( FT_QNEW_ARRAY( charset->sids, num_glyphs ) )
1064
0
          goto Exit;
1065
1066
        /* Copy the predefined charset into the allocated memory.     */
1067
0
        FT_ARRAY_COPY( charset->sids, cff_expertsubset_charset, num_glyphs );
1068
1069
0
        break;
1070
1071
0
      default:
1072
0
        error = FT_THROW( Invalid_File_Format );
1073
0
        goto Exit;
1074
1.36k
      }
1075
1.36k
    }
1076
1077
    /* we have to invert the `sids' array for subsetted CID-keyed fonts */
1078
1.36k
    if ( invert )
1079
0
      error = cff_charset_compute_cids( charset, num_glyphs, memory );
1080
1081
1.37k
  Exit:
1082
    /* Clean up if there was an error. */
1083
1.37k
    if ( error )
1084
8
    {
1085
8
      FT_FREE( charset->sids );
1086
8
      FT_FREE( charset->cids );
1087
8
      charset->format = 0;
1088
8
      charset->offset = 0;
1089
8
    }
1090
1091
1.37k
    return error;
1092
1.36k
  }
1093
1094
1095
  static void
1096
  cff_vstore_done( CFF_VStoreRec*  vstore,
1097
                   FT_Memory       memory )
1098
4.93k
  {
1099
4.93k
    FT_UInt  i;
1100
1101
1102
    /* free regionList and axisLists */
1103
4.93k
    if ( vstore->varRegionList )
1104
0
    {
1105
0
      for ( i = 0; i < vstore->regionCount; i++ )
1106
0
        FT_FREE( vstore->varRegionList[i].axisList );
1107
0
    }
1108
4.93k
    FT_FREE( vstore->varRegionList );
1109
1110
    /* free varData and indices */
1111
4.93k
    if ( vstore->varData )
1112
0
    {
1113
0
      for ( i = 0; i < vstore->dataCount; i++ )
1114
0
        FT_FREE( vstore->varData[i].regionIndices );
1115
0
    }
1116
4.93k
    FT_FREE( vstore->varData );
1117
4.93k
  }
1118
1119
1120
  /* convert 2.14 to Fixed */
1121
0
  #define FT_fdot14ToFixed( x )  ( (FT_Fixed)( (FT_ULong)(x) << 2 ) )
1122
1123
1124
  static FT_Error
1125
  cff_vstore_load( CFF_VStoreRec*  vstore,
1126
                   FT_Stream       stream,
1127
                   FT_ULong        base_offset,
1128
                   FT_ULong        offset )
1129
0
  {
1130
0
    FT_Memory  memory = stream->memory;
1131
0
    FT_Error   error  = FT_ERR( Invalid_File_Format );
1132
1133
0
    FT_ULong*  dataOffsetArray = NULL;
1134
0
    FT_UInt    i, j;
1135
1136
1137
    /* no offset means no vstore to parse */
1138
0
    if ( offset )
1139
0
    {
1140
0
      FT_UInt   vsOffset;
1141
0
      FT_UInt   format;
1142
0
      FT_ULong  regionListOffset;
1143
1144
1145
      /* we need to parse the table to determine its size; */
1146
      /* skip table length                                 */
1147
0
      if ( FT_STREAM_SEEK( base_offset + offset ) ||
1148
0
           FT_STREAM_SKIP( 2 )                    )
1149
0
        goto Exit;
1150
1151
      /* actual variation store begins after the length */
1152
0
      vsOffset = FT_STREAM_POS();
1153
1154
      /* check the header */
1155
0
      if ( FT_READ_USHORT( format ) )
1156
0
        goto Exit;
1157
0
      if ( format != 1 )
1158
0
      {
1159
0
        error = FT_THROW( Invalid_File_Format );
1160
0
        goto Exit;
1161
0
      }
1162
1163
      /* read top level fields */
1164
0
      if ( FT_READ_ULONG( regionListOffset )   ||
1165
0
           FT_READ_USHORT( vstore->dataCount ) )
1166
0
        goto Exit;
1167
1168
      /* make temporary copy of item variation data offsets; */
1169
      /* we'll parse region list first, then come back       */
1170
0
      if ( FT_QNEW_ARRAY( dataOffsetArray, vstore->dataCount ) )
1171
0
        goto Exit;
1172
1173
0
      for ( i = 0; i < vstore->dataCount; i++ )
1174
0
      {
1175
0
        if ( FT_READ_ULONG( dataOffsetArray[i] ) )
1176
0
          goto Exit;
1177
0
      }
1178
1179
      /* parse regionList and axisLists */
1180
0
      if ( FT_STREAM_SEEK( vsOffset + regionListOffset ) ||
1181
0
           FT_READ_USHORT( vstore->axisCount )           ||
1182
0
           FT_READ_USHORT( vstore->regionCount )         )
1183
0
        goto Exit;
1184
1185
0
      if ( FT_QNEW_ARRAY( vstore->varRegionList, vstore->regionCount ) )
1186
0
        goto Exit;
1187
1188
0
      for ( i = 0; i < vstore->regionCount; i++ )
1189
0
      {
1190
0
        CFF_VarRegion*  region = &vstore->varRegionList[i];
1191
1192
1193
0
        if ( FT_QNEW_ARRAY( region->axisList, vstore->axisCount ) )
1194
0
          goto Exit;
1195
1196
0
        for ( j = 0; j < vstore->axisCount; j++ )
1197
0
        {
1198
0
          CFF_AxisCoords*  axis = &region->axisList[j];
1199
1200
0
          FT_Int16  start14, peak14, end14;
1201
1202
1203
0
          if ( FT_READ_SHORT( start14 ) ||
1204
0
               FT_READ_SHORT( peak14 )  ||
1205
0
               FT_READ_SHORT( end14 )   )
1206
0
            goto Exit;
1207
1208
0
          axis->startCoord = FT_fdot14ToFixed( start14 );
1209
0
          axis->peakCoord  = FT_fdot14ToFixed( peak14 );
1210
0
          axis->endCoord   = FT_fdot14ToFixed( end14 );
1211
0
        }
1212
0
      }
1213
1214
      /* use dataOffsetArray now to parse varData items */
1215
0
      if ( FT_QNEW_ARRAY( vstore->varData, vstore->dataCount ) )
1216
0
        goto Exit;
1217
1218
0
      for ( i = 0; i < vstore->dataCount; i++ )
1219
0
      {
1220
0
        CFF_VarData*  data = &vstore->varData[i];
1221
1222
1223
0
        if ( FT_STREAM_SEEK( vsOffset + dataOffsetArray[i] ) )
1224
0
          goto Exit;
1225
1226
        /* ignore `itemCount' and `shortDeltaCount' */
1227
        /* because CFF2 has no delta sets           */
1228
0
        if ( FT_STREAM_SKIP( 4 ) )
1229
0
          goto Exit;
1230
1231
        /* Note: just record values; consistency is checked later    */
1232
        /*       by cff_blend_build_vector when it consumes `vstore' */
1233
1234
0
        if ( FT_READ_USHORT( data->regionIdxCount ) )
1235
0
          goto Exit;
1236
1237
0
        if ( FT_QNEW_ARRAY( data->regionIndices, data->regionIdxCount ) )
1238
0
          goto Exit;
1239
1240
0
        for ( j = 0; j < data->regionIdxCount; j++ )
1241
0
        {
1242
0
          if ( FT_READ_USHORT( data->regionIndices[j] ) )
1243
0
            goto Exit;
1244
0
        }
1245
0
      }
1246
0
    }
1247
1248
0
    error = FT_Err_Ok;
1249
1250
0
  Exit:
1251
0
    FT_FREE( dataOffsetArray );
1252
0
    if ( error )
1253
0
      cff_vstore_done( vstore, memory );
1254
1255
0
    return error;
1256
0
  }
1257
1258
1259
  /* Clear blend stack (after blend values are consumed). */
1260
  /*                                                      */
1261
  /* TODO: Should do this in cff_run_parse, but subFont   */
1262
  /*       ref is not available there.                    */
1263
  /*                                                      */
1264
  /* Allocation is not changed when stack is cleared.     */
1265
  FT_LOCAL_DEF( void )
1266
  cff_blend_clear( CFF_SubFont  subFont )
1267
2.28k
  {
1268
2.28k
    subFont->blend_top  = subFont->blend_stack;
1269
2.28k
    subFont->blend_used = 0;
1270
2.28k
  }
1271
1272
1273
  /* Blend numOperands on the stack,                       */
1274
  /* store results into the first numBlends values,        */
1275
  /* then pop remaining arguments.                         */
1276
  /*                                                       */
1277
  /* This is comparable to `cf2_doBlend' but               */
1278
  /* the cffparse stack is different and can't be written. */
1279
  /* Blended values are written to a different buffer,     */
1280
  /* using reserved operator 255.                          */
1281
  /*                                                       */
1282
  /* Blend calculation is done in 16.16 fixed point.       */
1283
  FT_LOCAL_DEF( FT_Error )
1284
  cff_blend_doBlend( CFF_SubFont  subFont,
1285
                     CFF_Parser   parser,
1286
                     FT_UInt      numBlends )
1287
0
  {
1288
0
    FT_UInt  delta;
1289
0
    FT_UInt  base;
1290
0
    FT_UInt  i, j;
1291
0
    FT_UInt  size;
1292
1293
0
    CFF_Blend  blend = &subFont->blend;
1294
1295
0
    FT_Memory  memory = subFont->blend.font->memory; /* for FT_REALLOC */
1296
0
    FT_Error   error  = FT_Err_Ok;                   /* for FT_REALLOC */
1297
1298
    /* compute expected number of operands for this blend */
1299
0
    FT_UInt  numOperands = (FT_UInt)( numBlends * blend->lenBV );
1300
0
    FT_UInt  count       = (FT_UInt)( parser->top - 1 - parser->stack );
1301
1302
1303
0
    if ( numOperands > count )
1304
0
    {
1305
0
      FT_TRACE4(( " cff_blend_doBlend: Stack underflow %d argument%s\n",
1306
0
                  count,
1307
0
                  count == 1 ? "" : "s" ));
1308
1309
0
      error = FT_THROW( Stack_Underflow );
1310
0
      goto Exit;
1311
0
    }
1312
1313
    /* check whether we have room for `numBlends' values at `blend_top' */
1314
0
    size = 5 * numBlends;           /* add 5 bytes per entry    */
1315
0
    if ( subFont->blend_used + size > subFont->blend_alloc )
1316
0
    {
1317
0
      FT_Byte*  blend_stack_old = subFont->blend_stack;
1318
0
      FT_Byte*  blend_top_old   = subFont->blend_top;
1319
1320
1321
      /* increase or allocate `blend_stack' and reset `blend_top'; */
1322
      /* prepare to append `numBlends' values to the buffer        */
1323
0
      if ( FT_QREALLOC( subFont->blend_stack,
1324
0
                        subFont->blend_alloc,
1325
0
                        subFont->blend_alloc + size ) )
1326
0
        goto Exit;
1327
1328
0
      subFont->blend_top    = subFont->blend_stack + subFont->blend_used;
1329
0
      subFont->blend_alloc += size;
1330
1331
      /* iterate over the parser stack and adjust pointers */
1332
      /* if the reallocated buffer has a different address */
1333
0
      if ( blend_stack_old                         &&
1334
0
           subFont->blend_stack != blend_stack_old )
1335
0
      {
1336
0
        FT_PtrDist  offset = subFont->blend_stack - blend_stack_old;
1337
0
        FT_Byte**   p;
1338
1339
1340
0
        for ( p = parser->stack; p < parser->top; p++ )
1341
0
        {
1342
0
          if ( *p >= blend_stack_old && *p < blend_top_old )
1343
0
            *p += offset;
1344
0
        }
1345
0
      }
1346
0
    }
1347
0
    subFont->blend_used += size;
1348
1349
0
    base  = count - numOperands;     /* index of first blend arg */
1350
0
    delta = base + numBlends;        /* index of first delta arg */
1351
1352
0
    for ( i = 0; i < numBlends; i++ )
1353
0
    {
1354
0
      const FT_Int32*  weight = &blend->BV[1];
1355
0
      FT_UInt32        sum;
1356
1357
1358
      /* convert inputs to 16.16 fixed point */
1359
0
      sum = cff_parse_num( parser, &parser->stack[i + base] ) * 0x10000;
1360
1361
0
      for ( j = 1; j < blend->lenBV; j++ )
1362
0
        sum += cff_parse_num( parser, &parser->stack[delta++] ) * *weight++;
1363
1364
      /* point parser stack to new value on blend_stack */
1365
0
      parser->stack[i + base] = subFont->blend_top;
1366
1367
      /* Push blended result as Type 2 5-byte fixed point number.  This */
1368
      /* will not conflict with actual DICTs because 255 is a reserved  */
1369
      /* opcode in both CFF and CFF2 DICTs.  See `cff_parse_num' for    */
1370
      /* decode of this, which rounds to an integer.                    */
1371
0
      *subFont->blend_top++ = 255;
1372
0
      *subFont->blend_top++ = (FT_Byte)( sum >> 24 );
1373
0
      *subFont->blend_top++ = (FT_Byte)( sum >> 16 );
1374
0
      *subFont->blend_top++ = (FT_Byte)( sum >>  8 );
1375
0
      *subFont->blend_top++ = (FT_Byte)sum;
1376
0
    }
1377
1378
    /* leave only numBlends results on parser stack */
1379
0
    parser->top = &parser->stack[base + numBlends];
1380
1381
0
  Exit:
1382
0
    return error;
1383
0
  }
1384
1385
1386
  /* Compute a blend vector from variation store index and normalized  */
1387
  /* vector based on pseudo-code in OpenType Font Variations Overview. */
1388
  /*                                                                   */
1389
  /* Note: lenNDV == 0 produces a default blend vector, (1,0,0,...).   */
1390
  FT_LOCAL_DEF( FT_Error )
1391
  cff_blend_build_vector( CFF_Blend  blend,
1392
                          FT_UInt    vsindex,
1393
                          FT_UInt    lenNDV,
1394
                          FT_Fixed*  NDV )
1395
0
  {
1396
0
    FT_Error   error  = FT_Err_Ok;            /* for FT_REALLOC */
1397
0
    FT_Memory  memory = blend->font->memory;  /* for FT_REALLOC */
1398
1399
0
    FT_UInt       len;
1400
0
    CFF_VStore    vs;
1401
0
    CFF_VarData*  varData;
1402
0
    FT_UInt       master;
1403
1404
1405
    /* protect against malformed fonts */
1406
0
    if ( !( lenNDV == 0 || NDV ) )
1407
0
    {
1408
0
      FT_TRACE4(( " cff_blend_build_vector:"
1409
0
                  " Malformed Normalize Design Vector data\n" ));
1410
0
      error = FT_THROW( Invalid_File_Format );
1411
0
      goto Exit;
1412
0
    }
1413
1414
0
    blend->builtBV = FALSE;
1415
1416
0
    vs = &blend->font->vstore;
1417
1418
    /* VStore and fvar must be consistent */
1419
0
    if ( lenNDV != 0 && lenNDV != vs->axisCount )
1420
0
    {
1421
0
      FT_TRACE4(( " cff_blend_build_vector: Axis count mismatch\n" ));
1422
0
      error = FT_THROW( Invalid_File_Format );
1423
0
      goto Exit;
1424
0
    }
1425
1426
0
    if ( vsindex >= vs->dataCount )
1427
0
    {
1428
0
      FT_TRACE4(( " cff_blend_build_vector: vsindex out of range\n" ));
1429
0
      error = FT_THROW( Invalid_File_Format );
1430
0
      goto Exit;
1431
0
    }
1432
1433
    /* select the item variation data structure */
1434
0
    varData = &vs->varData[vsindex];
1435
1436
    /* prepare buffer for the blend vector */
1437
0
    len = varData->regionIdxCount + 1;    /* add 1 for default component */
1438
0
    if ( FT_QRENEW_ARRAY( blend->BV, blend->lenBV, len ) )
1439
0
      goto Exit;
1440
1441
0
    blend->lenBV = len;
1442
1443
    /* outer loop steps through master designs to be blended */
1444
0
    for ( master = 0; master < len; master++ )
1445
0
    {
1446
0
      FT_UInt         j;
1447
0
      FT_UInt         idx;
1448
0
      CFF_VarRegion*  varRegion;
1449
1450
1451
      /* default factor is always one */
1452
0
      if ( master == 0 )
1453
0
      {
1454
0
        blend->BV[master] = FT_FIXED_ONE;
1455
0
        FT_TRACE4(( "   build blend vector len %d\n", len ));
1456
0
        FT_TRACE4(( "   [ %f ", blend->BV[master] / 65536.0 ));
1457
0
        continue;
1458
0
      }
1459
1460
      /* VStore array does not include default master, so subtract one */
1461
0
      idx       = varData->regionIndices[master - 1];
1462
0
      varRegion = &vs->varRegionList[idx];
1463
1464
0
      if ( idx >= vs->regionCount )
1465
0
      {
1466
0
        FT_TRACE4(( " cff_blend_build_vector:"
1467
0
                    " region index out of range\n" ));
1468
0
        error = FT_THROW( Invalid_File_Format );
1469
0
        goto Exit;
1470
0
      }
1471
1472
      /* Note: `lenNDV' could be zero.                              */
1473
      /*       In that case, build default blend vector (1,0,0...). */
1474
0
      if ( !lenNDV )
1475
0
      {
1476
0
        blend->BV[master] = 0;
1477
0
        continue;
1478
0
      }
1479
1480
      /* In the normal case, initialize each component to 1 */
1481
      /* before inner loop.                                 */
1482
0
      blend->BV[master] = FT_FIXED_ONE; /* default */
1483
1484
      /* inner loop steps through axes in this region */
1485
0
      for ( j = 0; j < lenNDV; j++ )
1486
0
      {
1487
0
        CFF_AxisCoords*  axis = &varRegion->axisList[j];
1488
0
        FT_Fixed         axisScalar;
1489
1490
1491
        /* compute the scalar contribution of this axis; */
1492
        /* ignore invalid ranges                         */
1493
0
        if ( axis->startCoord > axis->peakCoord ||
1494
0
             axis->peakCoord > axis->endCoord   )
1495
0
          axisScalar = FT_FIXED_ONE;
1496
1497
0
        else if ( axis->startCoord < 0 &&
1498
0
                  axis->endCoord > 0   &&
1499
0
                  axis->peakCoord != 0 )
1500
0
          axisScalar = FT_FIXED_ONE;
1501
1502
        /* peak of 0 means ignore this axis */
1503
0
        else if ( axis->peakCoord == 0 )
1504
0
          axisScalar = FT_FIXED_ONE;
1505
1506
        /* ignore this region if coords are out of range */
1507
0
        else if ( NDV[j] < axis->startCoord ||
1508
0
                  NDV[j] > axis->endCoord   )
1509
0
          axisScalar = 0;
1510
1511
        /* calculate a proportional factor */
1512
0
        else
1513
0
        {
1514
0
          if ( NDV[j] == axis->peakCoord )
1515
0
            axisScalar = FT_FIXED_ONE;
1516
0
          else if ( NDV[j] < axis->peakCoord )
1517
0
            axisScalar = FT_DivFix( NDV[j] - axis->startCoord,
1518
0
                                    axis->peakCoord - axis->startCoord );
1519
0
          else
1520
0
            axisScalar = FT_DivFix( axis->endCoord - NDV[j],
1521
0
                                    axis->endCoord - axis->peakCoord );
1522
0
        }
1523
1524
        /* take product of all the axis scalars */
1525
0
        blend->BV[master] = FT_MulFix( blend->BV[master], axisScalar );
1526
0
      }
1527
1528
0
      FT_TRACE4(( ", %f ",
1529
0
                  blend->BV[master] / 65536.0 ));
1530
0
    }
1531
1532
0
    FT_TRACE4(( "]\n" ));
1533
1534
    /* record the parameters used to build the blend vector */
1535
0
    blend->lastVsindex = vsindex;
1536
1537
0
    if ( lenNDV != 0 )
1538
0
    {
1539
      /* user has set a normalized vector */
1540
0
      if ( FT_QRENEW_ARRAY( blend->lastNDV, blend->lenNDV, lenNDV ) )
1541
0
        goto Exit;
1542
1543
0
      FT_MEM_COPY( blend->lastNDV,
1544
0
                   NDV,
1545
0
                   lenNDV * sizeof ( *NDV ) );
1546
0
    }
1547
1548
0
    blend->lenNDV  = lenNDV;
1549
0
    blend->builtBV = TRUE;
1550
1551
0
  Exit:
1552
0
    return error;
1553
0
  }
1554
1555
1556
  /* `lenNDV' is zero for default vector;           */
1557
  /* return TRUE if blend vector needs to be built. */
1558
  FT_LOCAL_DEF( FT_Bool )
1559
  cff_blend_check_vector( CFF_Blend  blend,
1560
                          FT_UInt    vsindex,
1561
                          FT_UInt    lenNDV,
1562
                          FT_Fixed*  NDV )
1563
0
  {
1564
0
    if ( !blend->builtBV                                ||
1565
0
         blend->lastVsindex != vsindex                  ||
1566
0
         blend->lenNDV != lenNDV                        ||
1567
0
         ( lenNDV                                     &&
1568
0
           ft_memcmp( NDV,
1569
0
                      blend->lastNDV,
1570
0
                      lenNDV * sizeof ( *NDV ) ) != 0 ) )
1571
0
    {
1572
      /* need to build blend vector */
1573
0
      return TRUE;
1574
0
    }
1575
1576
0
    return FALSE;
1577
0
  }
1578
1579
1580
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
1581
1582
  FT_LOCAL_DEF( FT_Error )
1583
  cff_get_var_blend( CFF_Face     face,
1584
                     FT_UInt     *num_coords,
1585
                     FT_Fixed*   *coords,
1586
                     FT_Fixed*   *normalizedcoords,
1587
                     FT_MM_Var*  *mm_var )
1588
0
  {
1589
0
    FT_Service_MultiMasters  mm = (FT_Service_MultiMasters)face->mm;
1590
1591
1592
0
    return mm->get_var_blend( FT_FACE( face ),
1593
0
                              num_coords,
1594
0
                              coords,
1595
0
                              normalizedcoords,
1596
0
                              mm_var );
1597
0
  }
1598
1599
1600
  FT_LOCAL_DEF( void )
1601
  cff_done_blend( CFF_Face  face )
1602
5.86k
  {
1603
5.86k
    FT_Service_MultiMasters  mm = (FT_Service_MultiMasters)face->mm;
1604
1605
1606
5.86k
    if (mm)
1607
5.86k
      mm->done_blend( FT_FACE( face ) );
1608
5.86k
  }
1609
1610
#endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */
1611
1612
1613
  static void
1614
  cff_encoding_done( CFF_Encoding  encoding )
1615
4.93k
  {
1616
4.93k
    encoding->format = 0;
1617
4.93k
    encoding->offset = 0;
1618
4.93k
    encoding->count  = 0;
1619
4.93k
  }
1620
1621
1622
  static FT_Error
1623
  cff_encoding_load( CFF_Encoding  encoding,
1624
                     CFF_Charset   charset,
1625
                     FT_UInt       num_glyphs,
1626
                     FT_Stream     stream,
1627
                     FT_ULong      base_offset,
1628
                     FT_ULong      offset )
1629
1.36k
  {
1630
1.36k
    FT_Error   error = FT_Err_Ok;
1631
1.36k
    FT_UInt    count;
1632
1.36k
    FT_UInt    j;
1633
1.36k
    FT_UShort  glyph_sid;
1634
1.36k
    FT_UInt    glyph_code;
1635
1636
1637
    /* Check for charset->sids.  If we do not have this, we fail. */
1638
1.36k
    if ( !charset->sids )
1639
0
    {
1640
0
      error = FT_THROW( Invalid_File_Format );
1641
0
      goto Exit;
1642
0
    }
1643
1644
    /* Zero out the code to gid/sid mappings. */
1645
350k
    for ( j = 0; j < 256; j++ )
1646
349k
    {
1647
349k
      encoding->sids [j] = 0;
1648
349k
      encoding->codes[j] = 0;
1649
349k
    }
1650
1651
    /* Note: The encoding table in a CFF font is indexed by glyph index;  */
1652
    /* the first encoded glyph index is 1.  Hence, we read the character  */
1653
    /* code (`glyph_code') at index j and make the assignment:            */
1654
    /*                                                                    */
1655
    /*    encoding->codes[glyph_code] = j + 1                             */
1656
    /*                                                                    */
1657
    /* We also make the assignment:                                       */
1658
    /*                                                                    */
1659
    /*    encoding->sids[glyph_code] = charset->sids[j + 1]               */
1660
    /*                                                                    */
1661
    /* This gives us both a code to GID and a code to SID mapping.        */
1662
1663
1.36k
    if ( offset > 1 )
1664
3
    {
1665
3
      encoding->offset = base_offset + offset;
1666
1667
      /* we need to parse the table to determine its size */
1668
3
      if ( FT_STREAM_SEEK( encoding->offset ) ||
1669
3
           FT_READ_BYTE( encoding->format )   ||
1670
3
           FT_READ_BYTE( count )              )
1671
1
        goto Exit;
1672
1673
2
      switch ( encoding->format & 0x7F )
1674
2
      {
1675
0
      case 0:
1676
0
        {
1677
0
          FT_Byte*  p;
1678
1679
1680
          /* By convention, GID 0 is always ".notdef" and is never */
1681
          /* coded in the font.  Hence, the number of codes found  */
1682
          /* in the table is `count+1'.                            */
1683
          /*                                                       */
1684
0
          encoding->count = count + 1;
1685
1686
0
          if ( FT_FRAME_ENTER( count ) )
1687
0
            goto Exit;
1688
1689
0
          p = (FT_Byte*)stream->cursor;
1690
1691
0
          for ( j = 1; j <= count; j++ )
1692
0
          {
1693
0
            glyph_code = *p++;
1694
1695
            /* Make sure j is not too big. */
1696
0
            if ( j < num_glyphs )
1697
0
            {
1698
              /* Assign code to GID mapping. */
1699
0
              encoding->codes[glyph_code] = (FT_UShort)j;
1700
1701
              /* Assign code to SID mapping. */
1702
0
              encoding->sids[glyph_code] = charset->sids[j];
1703
0
            }
1704
0
          }
1705
1706
0
          FT_FRAME_EXIT();
1707
0
        }
1708
0
        break;
1709
1710
0
      case 1:
1711
0
        {
1712
0
          FT_UInt  nleft;
1713
0
          FT_UInt  i = 1;
1714
0
          FT_UInt  k;
1715
1716
1717
0
          encoding->count = 0;
1718
1719
          /* Parse the Format1 ranges. */
1720
0
          for ( j = 0;  j < count; j++, i += nleft )
1721
0
          {
1722
            /* Read the first glyph code of the range. */
1723
0
            if ( FT_READ_BYTE( glyph_code ) )
1724
0
              goto Exit;
1725
1726
            /* Read the number of codes in the range. */
1727
0
            if ( FT_READ_BYTE( nleft ) )
1728
0
              goto Exit;
1729
1730
            /* Increment nleft, so we read `nleft + 1' codes/sids. */
1731
0
            nleft++;
1732
1733
            /* compute max number of character codes */
1734
0
            if ( (FT_UInt)nleft > encoding->count )
1735
0
              encoding->count = nleft;
1736
1737
            /* Fill in the range of codes/sids. */
1738
0
            for ( k = i; k < nleft + i; k++, glyph_code++ )
1739
0
            {
1740
              /* Make sure k is not too big. */
1741
0
              if ( k < num_glyphs && glyph_code < 256 )
1742
0
              {
1743
                /* Assign code to GID mapping. */
1744
0
                encoding->codes[glyph_code] = (FT_UShort)k;
1745
1746
                /* Assign code to SID mapping. */
1747
0
                encoding->sids[glyph_code] = charset->sids[k];
1748
0
              }
1749
0
            }
1750
0
          }
1751
1752
          /* simple check; one never knows what can be found in a font */
1753
0
          if ( encoding->count > 256 )
1754
0
            encoding->count = 256;
1755
0
        }
1756
0
        break;
1757
1758
2
      default:
1759
2
        FT_ERROR(( "cff_encoding_load: invalid table format\n" ));
1760
2
        error = FT_THROW( Invalid_File_Format );
1761
2
        goto Exit;
1762
0
      }
1763
1764
      /* Parse supplemental encodings, if any. */
1765
0
      if ( encoding->format & 0x80 )
1766
0
      {
1767
0
        FT_UInt  gindex;
1768
1769
1770
        /* count supplements */
1771
0
        if ( FT_READ_BYTE( count ) )
1772
0
          goto Exit;
1773
1774
0
        for ( j = 0; j < count; j++ )
1775
0
        {
1776
          /* Read supplemental glyph code. */
1777
0
          if ( FT_READ_BYTE( glyph_code ) )
1778
0
            goto Exit;
1779
1780
          /* Read the SID associated with this glyph code. */
1781
0
          if ( FT_READ_USHORT( glyph_sid ) )
1782
0
            goto Exit;
1783
1784
          /* Assign code to SID mapping. */
1785
0
          encoding->sids[glyph_code] = glyph_sid;
1786
1787
          /* First, look up GID which has been assigned to */
1788
          /* SID glyph_sid.                                */
1789
0
          for ( gindex = 0; gindex < num_glyphs; gindex++ )
1790
0
          {
1791
0
            if ( charset->sids[gindex] == glyph_sid )
1792
0
            {
1793
0
              encoding->codes[glyph_code] = (FT_UShort)gindex;
1794
0
              break;
1795
0
            }
1796
0
          }
1797
0
        }
1798
0
      }
1799
0
    }
1800
1.36k
    else
1801
1.36k
    {
1802
      /* We take into account the fact a CFF font can use a predefined */
1803
      /* encoding without containing all of the glyphs encoded by this */
1804
      /* encoding (see the note at the end of section 12 in the CFF    */
1805
      /* specification).                                               */
1806
1807
1.36k
      switch ( (FT_UInt)offset )
1808
1.36k
      {
1809
1.36k
      case 0:
1810
        /* First, copy the code to SID mapping. */
1811
1.36k
        FT_ARRAY_COPY( encoding->sids, cff_standard_encoding, 256 );
1812
1.36k
        goto Populate;
1813
1814
0
      case 1:
1815
        /* First, copy the code to SID mapping. */
1816
0
        FT_ARRAY_COPY( encoding->sids, cff_expert_encoding, 256 );
1817
1818
1.36k
      Populate:
1819
        /* Construct code to GID mapping from code to SID mapping */
1820
        /* and charset.                                           */
1821
1822
1.36k
        encoding->count = 0;
1823
1824
1.36k
        error = cff_charset_compute_cids( charset, num_glyphs,
1825
1.36k
                                          stream->memory );
1826
1.36k
        if ( error )
1827
0
          goto Exit;
1828
1829
349k
        for ( j = 0; j < 256; j++ )
1830
348k
        {
1831
348k
          FT_UInt  sid = encoding->sids[j];
1832
348k
          FT_UInt  gid = 0;
1833
1834
1835
348k
          if ( sid )
1836
202k
            gid = cff_charset_cid_to_gindex( charset, sid );
1837
1838
348k
          if ( gid != 0 )
1839
19.3k
          {
1840
19.3k
            encoding->codes[j] = (FT_UShort)gid;
1841
19.3k
            encoding->count    = j + 1;
1842
19.3k
          }
1843
329k
          else
1844
329k
          {
1845
329k
            encoding->codes[j] = 0;
1846
329k
            encoding->sids [j] = 0;
1847
329k
          }
1848
348k
        }
1849
1.36k
        break;
1850
1851
0
      default:
1852
0
        FT_ERROR(( "cff_encoding_load: invalid table format\n" ));
1853
0
        error = FT_THROW( Invalid_File_Format );
1854
0
        goto Exit;
1855
1.36k
      }
1856
1.36k
    }
1857
1858
1.36k
  Exit:
1859
1860
    /* Clean up if there was an error. */
1861
1.36k
    return error;
1862
1.36k
  }
1863
1864
1865
  /* Parse private dictionary; first call is always from `cff_face_init', */
1866
  /* so NDV has not been set for CFF2 variation.                          */
1867
  /*                                                                      */
1868
  /* `cff_slot_load' must call this function each time NDV changes.       */
1869
  FT_LOCAL_DEF( FT_Error )
1870
  cff_load_private_dict( CFF_Font     font,
1871
                         CFF_SubFont  subfont,
1872
                         FT_UInt      lenNDV,
1873
                         FT_Fixed*    NDV )
1874
2.30k
  {
1875
2.30k
    FT_Error         error  = FT_Err_Ok;
1876
2.30k
    CFF_ParserRec    parser;
1877
2.30k
    CFF_FontRecDict  top    = &subfont->font_dict;
1878
2.30k
    CFF_Private      priv   = &subfont->private_dict;
1879
2.30k
    FT_Stream        stream = font->stream;
1880
2.30k
    FT_UInt          stackSize;
1881
1882
1883
    /* store handle needed to access memory, vstore for blend;    */
1884
    /* we need this for clean-up even if there is no private DICT */
1885
2.30k
    subfont->blend.font   = font;
1886
2.30k
    subfont->blend.usedBV = FALSE;  /* clear state */
1887
1888
2.30k
    if ( !top->private_offset || !top->private_size )
1889
18
      goto Exit2;       /* no private DICT, do nothing */
1890
1891
    /* set defaults */
1892
2.28k
    FT_ZERO( priv );
1893
1894
2.28k
    priv->blue_shift       = 7;
1895
2.28k
    priv->blue_fuzz        = 1;
1896
2.28k
    priv->lenIV            = -1;
1897
2.28k
    priv->expansion_factor = (FT_Fixed)( 0.06 * 0x10000L );
1898
2.28k
    priv->blue_scale       = (FT_Fixed)( 0.039625 * 0x10000L * 1000 );
1899
1900
    /* provide inputs for blend calculations */
1901
2.28k
    priv->subfont   = subfont;
1902
2.28k
    subfont->lenNDV = lenNDV;
1903
2.28k
    subfont->NDV    = NDV;
1904
1905
    /* add 1 for the operator */
1906
0
    stackSize = font->cff2 ? font->top_font.font_dict.maxstack + 1
1907
2.28k
                           : CFF_MAX_STACK_DEPTH + 1;
1908
1909
2.28k
    if ( cff_parser_init( &parser,
1910
2.28k
                          font->cff2 ? CFF2_CODE_PRIVATE : CFF_CODE_PRIVATE,
1911
2.28k
                          priv,
1912
2.28k
                          font->library,
1913
2.28k
                          stackSize,
1914
2.28k
                          top->num_designs,
1915
2.28k
                          top->num_axes ) )
1916
0
      goto Exit;
1917
1918
2.28k
    if ( FT_STREAM_SEEK( font->base_offset + top->private_offset ) ||
1919
2.28k
         FT_FRAME_ENTER( top->private_size )                       )
1920
7
      goto Exit;
1921
1922
2.27k
    FT_TRACE4(( " private dictionary:\n" ));
1923
2.27k
    error = cff_parser_run( &parser,
1924
2.27k
                            (FT_Byte*)stream->cursor,
1925
2.27k
                            (FT_Byte*)stream->limit );
1926
2.27k
    FT_FRAME_EXIT();
1927
1928
2.27k
    if ( error )
1929
144
      goto Exit;
1930
1931
    /* ensure that `num_blue_values' is even */
1932
2.13k
    priv->num_blue_values &= ~1;
1933
1934
    /* sanitize `initialRandomSeed' to be a positive value, if necessary;  */
1935
    /* this is not mandated by the specification but by our implementation */
1936
2.13k
    if ( priv->initial_random_seed < 0 )
1937
0
      priv->initial_random_seed = -priv->initial_random_seed;
1938
2.13k
    else if ( priv->initial_random_seed == 0 )
1939
2.13k
      priv->initial_random_seed = 987654321;
1940
1941
    /* some sanitizing to avoid overflows later on; */
1942
    /* the upper limits are ad-hoc values           */
1943
2.13k
    if ( priv->blue_shift > 1000 || priv->blue_shift < 0 )
1944
0
    {
1945
0
      FT_TRACE2(( "cff_load_private_dict:"
1946
0
                  " setting unlikely BlueShift value %ld to default (7)\n",
1947
0
                  priv->blue_shift ));
1948
0
      priv->blue_shift = 7;
1949
0
    }
1950
1951
2.13k
    if ( priv->blue_fuzz > 1000 || priv->blue_fuzz < 0 )
1952
1
    {
1953
1
      FT_TRACE2(( "cff_load_private_dict:"
1954
1
                  " setting unlikely BlueFuzz value %ld to default (1)\n",
1955
1
                  priv->blue_fuzz ));
1956
1
      priv->blue_fuzz = 1;
1957
1
    }
1958
1959
2.28k
  Exit:
1960
    /* clean up */
1961
2.28k
    cff_blend_clear( subfont ); /* clear blend stack */
1962
2.28k
    cff_parser_done( &parser ); /* free parser stack */
1963
1964
2.30k
  Exit2:
1965
    /* no clean up (parser not initialized) */
1966
2.30k
    return error;
1967
2.28k
  }
1968
1969
1970
  /* There are 3 ways to call this function, distinguished by code.  */
1971
  /*                                                                 */
1972
  /* . CFF_CODE_TOPDICT for either a CFF Top DICT or a CFF Font DICT */
1973
  /* . CFF2_CODE_TOPDICT for CFF2 Top DICT                           */
1974
  /* . CFF2_CODE_FONTDICT for CFF2 Font DICT                         */
1975
1976
  static FT_Error
1977
  cff_subfont_load( CFF_SubFont  subfont,
1978
                    CFF_Index    idx,
1979
                    FT_UInt      font_index,
1980
                    FT_Stream    stream,
1981
                    FT_ULong     base_offset,
1982
                    FT_UInt      code,
1983
                    CFF_Font     font,
1984
                    CFF_Face     face )
1985
2.35k
  {
1986
2.35k
    FT_Error         error;
1987
2.35k
    CFF_ParserRec    parser;
1988
2.35k
    FT_Byte*         dict = NULL;
1989
2.35k
    FT_ULong         dict_len;
1990
2.35k
    CFF_FontRecDict  top  = &subfont->font_dict;
1991
2.35k
    CFF_Private      priv = &subfont->private_dict;
1992
1993
2.35k
    PSAux_Service  psaux = (PSAux_Service)face->psaux;
1994
1995
2.35k
    FT_Bool  cff2      = FT_BOOL( code == CFF2_CODE_TOPDICT  ||
1996
2.35k
                                  code == CFF2_CODE_FONTDICT );
1997
0
    FT_UInt  stackSize = cff2 ? CFF2_DEFAULT_STACK
1998
2.35k
                              : CFF_MAX_STACK_DEPTH;
1999
2000
2001
    /* Note: We use default stack size for CFF2 Font DICT because        */
2002
    /*       Top and Font DICTs are not allowed to have blend operators. */
2003
2.35k
    error = cff_parser_init( &parser,
2004
2.35k
                             code,
2005
2.35k
                             &subfont->font_dict,
2006
2.35k
                             font->library,
2007
2.35k
                             stackSize,
2008
2.35k
                             0,
2009
2.35k
                             0 );
2010
2.35k
    if ( error )
2011
0
      goto Exit;
2012
2013
    /* set defaults */
2014
2.35k
    FT_ZERO( top );
2015
2016
2.35k
    top->underline_position  = -( 100L << 16 );
2017
2.35k
    top->underline_thickness = 50L << 16;
2018
2.35k
    top->charstring_type     = 2;
2019
2.35k
    top->font_matrix.xx      = 0x10000L;
2020
2.35k
    top->font_matrix.yy      = 0x10000L;
2021
2.35k
    top->cid_count           = 8720;
2022
2023
    /* we use the implementation specific SID value 0xFFFF to indicate */
2024
    /* missing entries                                                 */
2025
2.35k
    top->version             = 0xFFFFU;
2026
2.35k
    top->notice              = 0xFFFFU;
2027
2.35k
    top->copyright           = 0xFFFFU;
2028
2.35k
    top->full_name           = 0xFFFFU;
2029
2.35k
    top->family_name         = 0xFFFFU;
2030
2.35k
    top->weight              = 0xFFFFU;
2031
2.35k
    top->embedded_postscript = 0xFFFFU;
2032
2033
2.35k
    top->cid_registry        = 0xFFFFU;
2034
2.35k
    top->cid_ordering        = 0xFFFFU;
2035
2.35k
    top->cid_font_name       = 0xFFFFU;
2036
2037
    /* set default stack size */
2038
2.35k
    top->maxstack            = cff2 ? CFF2_DEFAULT_STACK : 48;
2039
2040
2.35k
    if ( idx->count )   /* count is nonzero for a real index */
2041
2.35k
      error = cff_index_access_element( idx, font_index, &dict, &dict_len );
2042
1
    else
2043
1
    {
2044
      /* CFF2 has a fake top dict index;     */
2045
      /* simulate `cff_index_access_element' */
2046
2047
      /* Note: macros implicitly use `stream' and set `error' */
2048
1
      if ( FT_STREAM_SEEK( idx->data_offset )       ||
2049
1
           FT_FRAME_EXTRACT( idx->data_size, dict ) )
2050
0
        goto Exit;
2051
2052
1
      dict_len = idx->data_size;
2053
1
    }
2054
2055
2.35k
    if ( !error )
2056
2.35k
    {
2057
2.35k
      FT_TRACE4(( " top dictionary:\n" ));
2058
2.35k
      error = cff_parser_run( &parser, dict, FT_OFFSET( dict, dict_len ) );
2059
2.35k
    }
2060
2061
    /* clean up regardless of error */
2062
2.35k
    if ( idx->count )
2063
2.35k
      cff_index_forget_element( idx, &dict );
2064
2.35k
    else
2065
2.35k
      FT_FRAME_RELEASE( dict );
2066
2067
2.35k
    if ( error )
2068
54
      goto Exit;
2069
2070
    /* if it is a CID font, we stop there */
2071
2.30k
    if ( top->cid_registry != 0xFFFFU )
2072
0
      goto Exit;
2073
2074
    /* Parse the private dictionary, if any.                   */
2075
    /*                                                         */
2076
    /* CFF2 does not have a private dictionary in the Top DICT */
2077
    /* but may have one in a Font DICT.  We need to parse      */
2078
    /* the latter here in order to load any local subrs.       */
2079
2.30k
    error = cff_load_private_dict( font, subfont, 0, 0 );
2080
2.30k
    if ( error )
2081
151
      goto Exit;
2082
2083
2.15k
    if ( !cff2 )
2084
2.15k
    {
2085
      /*
2086
       * Initialize the random number generator.
2087
       *
2088
       * - If we have a face-specific seed, use it.
2089
       *   If non-zero, update it to a positive value.
2090
       *
2091
       * - Otherwise, use the seed from the CFF driver.
2092
       *   If non-zero, update it to a positive value.
2093
       *
2094
       * - If the random value is zero, use the seed given by the subfont's
2095
       *   `initialRandomSeed' value.
2096
       *
2097
       */
2098
2.15k
      if ( face->root.internal->random_seed == -1 )
2099
2.15k
      {
2100
2.15k
        PS_Driver  driver = (PS_Driver)FT_FACE_DRIVER( face );
2101
2102
2103
2.15k
        subfont->random = (FT_UInt32)driver->random_seed;
2104
2.15k
        if ( driver->random_seed )
2105
2.15k
        {
2106
2.15k
          do
2107
4.32k
          {
2108
4.32k
            driver->random_seed =
2109
4.32k
              (FT_Int32)psaux->cff_random( (FT_UInt32)driver->random_seed );
2110
2111
4.32k
          } while ( driver->random_seed < 0 );
2112
2.15k
        }
2113
2.15k
      }
2114
0
      else
2115
0
      {
2116
0
        subfont->random = (FT_UInt32)face->root.internal->random_seed;
2117
0
        if ( face->root.internal->random_seed )
2118
0
        {
2119
0
          do
2120
0
          {
2121
0
            face->root.internal->random_seed =
2122
0
              (FT_Int32)psaux->cff_random(
2123
0
                (FT_UInt32)face->root.internal->random_seed );
2124
2125
0
          } while ( face->root.internal->random_seed < 0 );
2126
0
        }
2127
0
      }
2128
2129
2.15k
      if ( !subfont->random )
2130
0
        subfont->random = (FT_UInt32)priv->initial_random_seed;
2131
2.15k
    }
2132
2133
    /* read the local subrs, if any */
2134
2.15k
    if ( priv->local_subrs_offset )
2135
58
    {
2136
58
      if ( FT_STREAM_SEEK( base_offset + top->private_offset +
2137
58
                           priv->local_subrs_offset ) )
2138
0
        goto Exit;
2139
2140
58
      error = cff_index_init( &subfont->local_subrs_index, stream, 1, cff2 );
2141
58
      if ( error )
2142
40
        goto Exit;
2143
2144
18
      error = cff_index_get_pointers( &subfont->local_subrs_index,
2145
18
                                      &subfont->local_subrs, NULL, NULL );
2146
18
      if ( error )
2147
0
        goto Exit;
2148
2.35k
    }
2149
2150
2.35k
  Exit:
2151
2.35k
    cff_parser_done( &parser ); /* free parser stack */
2152
2153
2.35k
    return error;
2154
2.15k
  }
2155
2156
2157
  static void
2158
  cff_subfont_done( FT_Memory    memory,
2159
                    CFF_SubFont  subfont )
2160
4.93k
  {
2161
4.93k
    if ( subfont )
2162
4.93k
    {
2163
4.93k
      cff_index_done( &subfont->local_subrs_index );
2164
4.93k
      FT_FREE( subfont->local_subrs );
2165
2166
4.93k
      FT_FREE( subfont->blend.lastNDV );
2167
4.93k
      FT_FREE( subfont->blend.BV );
2168
4.93k
      FT_FREE( subfont->blend_stack );
2169
4.93k
    }
2170
4.93k
  }
2171
2172
2173
  FT_LOCAL_DEF( FT_Error )
2174
  cff_font_load( FT_Library library,
2175
                 FT_Stream  stream,
2176
                 FT_Int     face_index,
2177
                 CFF_Font   font,
2178
                 CFF_Face   face,
2179
                 FT_Bool    pure_cff,
2180
                 FT_Bool    cff2 )
2181
4.93k
  {
2182
4.93k
    static const FT_Frame_Field  cff_header_fields[] =
2183
4.93k
    {
2184
4.93k
#undef  FT_STRUCTURE
2185
4.93k
#define FT_STRUCTURE  CFF_FontRec
2186
2187
4.93k
      FT_FRAME_START( 3 ),
2188
4.93k
        FT_FRAME_BYTE( version_major ),
2189
4.93k
        FT_FRAME_BYTE( version_minor ),
2190
4.93k
        FT_FRAME_BYTE( header_size ),
2191
4.93k
      FT_FRAME_END
2192
4.93k
    };
2193
2194
4.93k
    FT_Error         error;
2195
4.93k
    FT_Memory        memory = stream->memory;
2196
4.93k
    FT_ULong         base_offset;
2197
4.93k
    CFF_FontRecDict  dict;
2198
4.93k
    CFF_IndexRec     string_index;
2199
4.93k
    FT_UInt          subfont_index;
2200
2201
2202
4.93k
    FT_ZERO( font );
2203
4.93k
    FT_ZERO( &string_index );
2204
2205
4.93k
    dict        = &font->top_font.font_dict;
2206
4.93k
    base_offset = FT_STREAM_POS();
2207
2208
4.93k
    font->library     = library;
2209
4.93k
    font->stream      = stream;
2210
4.93k
    font->memory      = memory;
2211
4.93k
    font->cff2        = cff2;
2212
4.93k
    font->base_offset = base_offset;
2213
2214
    /* read CFF font header */
2215
4.93k
    if ( FT_STREAM_READ_FIELDS( cff_header_fields, font ) )
2216
0
      goto Exit;
2217
2218
4.93k
    if ( cff2 )
2219
0
    {
2220
0
      if ( font->version_major != 2 ||
2221
0
           font->header_size < 5    )
2222
0
      {
2223
0
        FT_TRACE2(( "  not a CFF2 font header\n" ));
2224
0
        error = FT_THROW( Unknown_File_Format );
2225
0
        goto Exit;
2226
0
      }
2227
2228
0
      if ( FT_READ_USHORT( font->top_dict_length ) )
2229
0
        goto Exit;
2230
4.93k
    }
2231
4.93k
    else
2232
4.93k
    {
2233
4.93k
      FT_Byte  absolute_offset;
2234
2235
2236
4.93k
      if ( FT_READ_BYTE( absolute_offset ) )
2237
0
        goto Exit;
2238
2239
4.93k
      if ( font->version_major != 1 ||
2240
2.87k
           font->header_size < 4    ||
2241
2.87k
           absolute_offset > 4      )
2242
2.06k
      {
2243
2.06k
        FT_TRACE2(( "  not a CFF font header\n" ));
2244
2.06k
        error = FT_THROW( Unknown_File_Format );
2245
2.06k
        goto Exit;
2246
2.06k
      }
2247
2.86k
    }
2248
2249
    /* skip the rest of the header */
2250
2.86k
    if ( FT_STREAM_SEEK( base_offset + font->header_size ) )
2251
0
    {
2252
      /* For pure CFFs we have read only four bytes so far.  Contrary to */
2253
      /* other formats like SFNT those bytes doesn't define a signature; */
2254
      /* it is thus possible that the font isn't a CFF at all.           */
2255
0
      if ( pure_cff )
2256
0
      {
2257
0
        FT_TRACE2(( "  not a CFF file\n" ));
2258
0
        error = FT_THROW( Unknown_File_Format );
2259
0
      }
2260
0
      goto Exit;
2261
0
    }
2262
2263
2.86k
    if ( cff2 )
2264
0
    {
2265
      /* For CFF2, the top dict data immediately follow the header    */
2266
      /* and the length is stored in the header `offSize' field;      */
2267
      /* there is no index for it.                                    */
2268
      /*                                                              */
2269
      /* Use the `font_dict_index' to save the current position       */
2270
      /* and length of data, but leave count at zero as an indicator. */
2271
0
      FT_ZERO( &font->font_dict_index );
2272
2273
0
      font->font_dict_index.data_offset = FT_STREAM_POS();
2274
0
      font->font_dict_index.data_size   = font->top_dict_length;
2275
2276
      /* skip the top dict data for now, we will parse it later */
2277
0
      if ( FT_STREAM_SKIP( font->top_dict_length ) )
2278
0
        goto Exit;
2279
2280
      /* next, read the global subrs index */
2281
0
      if ( FT_SET_ERROR( cff_index_init( &font->global_subrs_index,
2282
0
                                         stream, 1, cff2 ) ) )
2283
0
        goto Exit;
2284
2.86k
    }
2285
2.86k
    else
2286
2.86k
    {
2287
      /* for CFF, read the name, top dict, string and global subrs index */
2288
2.86k
      if ( FT_SET_ERROR( cff_index_init( &font->name_index,
2289
2.86k
                                         stream, 0, cff2 ) ) )
2290
6
      {
2291
6
        if ( pure_cff )
2292
3
        {
2293
3
          FT_TRACE2(( "  not a CFF file\n" ));
2294
3
          error = FT_THROW( Unknown_File_Format );
2295
3
        }
2296
6
        goto Exit;
2297
6
      }
2298
2299
      /* if we have an empty font name,      */
2300
      /* it must be the only font in the CFF */
2301
2.86k
      if ( font->name_index.count > 1                          &&
2302
5
           font->name_index.data_size < font->name_index.count )
2303
4
      {
2304
        /* for pure CFFs, we still haven't checked enough bytes */
2305
        /* to be sure that it is a CFF at all                   */
2306
4
        error = pure_cff ? FT_THROW( Unknown_File_Format )
2307
4
                         : FT_THROW( Invalid_File_Format );
2308
4
        goto Exit;
2309
4
      }
2310
2311
2.85k
      if ( FT_SET_ERROR( cff_index_init( &font->font_dict_index,
2312
2.85k
                                         stream, 0, cff2 ) )                 ||
2313
2.85k
           FT_SET_ERROR( cff_index_init( &string_index,
2314
2.85k
                                         stream, 1, cff2 ) )                 ||
2315
2.85k
           FT_SET_ERROR( cff_index_init( &font->global_subrs_index,
2316
2.85k
                                         stream, 1, cff2 ) )                 ||
2317
2.85k
           FT_SET_ERROR( cff_index_get_pointers( &string_index,
2318
2.85k
                                                 &font->strings,
2319
2.85k
                                                 &font->string_pool,
2320
2.85k
                                                 &font->string_pool_size ) ) )
2321
498
        goto Exit;
2322
2323
      /* there must be a Top DICT index entry for each name index entry */
2324
2.35k
      if ( font->name_index.count > font->font_dict_index.count )
2325
3
      {
2326
3
        FT_ERROR(( "cff_font_load:"
2327
3
                   " not enough entries in Top DICT index\n" ));
2328
3
        error = FT_THROW( Invalid_File_Format );
2329
3
        goto Exit;
2330
3
      }
2331
2.35k
    }
2332
2333
2.35k
    font->num_strings = string_index.count;
2334
2335
2.35k
    if ( pure_cff )
2336
310
    {
2337
      /* well, we don't really forget the `disabled' fonts... */
2338
310
      subfont_index = (FT_UInt)( face_index & 0xFFFF );
2339
2340
310
      if ( face_index > 0 && subfont_index >= font->name_index.count )
2341
0
      {
2342
0
        FT_ERROR(( "cff_font_load:"
2343
0
                   " invalid subfont index for pure CFF font (%d)\n",
2344
0
                   subfont_index ));
2345
0
        error = FT_THROW( Invalid_Argument );
2346
0
        goto Exit;
2347
0
      }
2348
2349
310
      font->num_faces = font->name_index.count;
2350
310
    }
2351
2.04k
    else
2352
2.04k
    {
2353
2.04k
      subfont_index = 0;
2354
2355
2.04k
      if ( font->name_index.count > 1 )
2356
0
      {
2357
0
        FT_ERROR(( "cff_font_load:"
2358
0
                   " invalid CFF font with multiple subfonts\n" ));
2359
0
        FT_ERROR(( "              "
2360
0
                   " in SFNT wrapper\n" ));
2361
0
        error = FT_THROW( Invalid_File_Format );
2362
0
        goto Exit;
2363
0
      }
2364
2.35k
    }
2365
2366
    /* in case of a font format check, simply exit now */
2367
2.35k
    if ( face_index < 0 )
2368
0
      goto Exit;
2369
2370
    /* now, parse the top-level font dictionary */
2371
2.35k
    FT_TRACE4(( "parsing top-level\n" ));
2372
2.35k
    error = cff_subfont_load( &font->top_font,
2373
2.35k
                              &font->font_dict_index,
2374
2.35k
                              subfont_index,
2375
2.35k
                              stream,
2376
2.35k
                              base_offset,
2377
2.35k
                              cff2 ? CFF2_CODE_TOPDICT : CFF_CODE_TOPDICT,
2378
2.35k
                              font,
2379
2.35k
                              face );
2380
2.35k
    if ( error )
2381
245
      goto Exit;
2382
2383
2.11k
    if ( FT_STREAM_SEEK( base_offset + dict->charstrings_offset ) )
2384
3
      goto Exit;
2385
2386
2.10k
    error = cff_index_init( &font->charstrings_index, stream, 0, cff2 );
2387
2.10k
    if ( error )
2388
280
      goto Exit;
2389
2390
    /* now, check for a CID or CFF2 font */
2391
1.82k
    if ( dict->cid_registry != 0xFFFFU ||
2392
1.82k
         cff2                          )
2393
0
    {
2394
0
      CFF_IndexRec  fd_index;
2395
0
      CFF_SubFont   sub = NULL;
2396
0
      FT_UInt       idx;
2397
2398
2399
      /* for CFF2, read the Variation Store if available;                 */
2400
      /* this must follow the Top DICT parse and precede any Private DICT */
2401
0
      error = cff_vstore_load( &font->vstore,
2402
0
                               stream,
2403
0
                               base_offset,
2404
0
                               dict->vstore_offset );
2405
0
      if ( error )
2406
0
        goto Exit;
2407
2408
      /* this is a CID-keyed font, we must now allocate a table of */
2409
      /* sub-fonts, then load each of them separately              */
2410
0
      if ( FT_STREAM_SEEK( base_offset + dict->cid_fd_array_offset ) )
2411
0
        goto Exit;
2412
2413
0
      error = cff_index_init( &fd_index, stream, 0, cff2 );
2414
0
      if ( error )
2415
0
        goto Exit;
2416
2417
      /* Font Dicts are not limited to 256 for CFF2. */
2418
      /* TODO: support this for CFF2                 */
2419
0
      if ( fd_index.count > CFF_MAX_CID_FONTS )
2420
0
      {
2421
0
        FT_TRACE0(( "cff_font_load: FD array too large in CID font\n" ));
2422
0
        goto Fail_CID;
2423
0
      }
2424
2425
      /* allocate & read each font dict independently */
2426
0
      font->num_subfonts = fd_index.count;
2427
0
      if ( FT_NEW_ARRAY( sub, fd_index.count ) )
2428
0
        goto Fail_CID;
2429
2430
      /* set up pointer table */
2431
0
      for ( idx = 0; idx < fd_index.count; idx++ )
2432
0
        font->subfonts[idx] = sub + idx;
2433
2434
      /* now load each subfont independently */
2435
0
      for ( idx = 0; idx < fd_index.count; idx++ )
2436
0
      {
2437
0
        sub = font->subfonts[idx];
2438
0
        FT_TRACE4(( "parsing subfont %u\n", idx ));
2439
0
        error = cff_subfont_load( sub,
2440
0
                                  &fd_index,
2441
0
                                  idx,
2442
0
                                  stream,
2443
0
                                  base_offset,
2444
0
                                  cff2 ? CFF2_CODE_FONTDICT
2445
0
                                       : CFF_CODE_TOPDICT,
2446
0
                                  font,
2447
0
                                  face );
2448
0
        if ( error )
2449
0
          goto Fail_CID;
2450
0
      }
2451
2452
      /* now load the FD Select array;               */
2453
      /* CFF2 omits FDSelect if there is only one FD */
2454
0
      if ( !cff2 || fd_index.count > 1 )
2455
0
        error = CFF_Load_FD_Select( &font->fd_select,
2456
0
                                    font->charstrings_index.count,
2457
0
                                    stream,
2458
0
                                    base_offset + dict->cid_fd_select_offset );
2459
2460
0
    Fail_CID:
2461
0
      cff_index_done( &fd_index );
2462
2463
0
      if ( error )
2464
0
        goto Exit;
2465
1.82k
    }
2466
1.82k
    else
2467
1.82k
      font->num_subfonts = 0;
2468
2469
    /* read the charstrings index now */
2470
1.82k
    if ( dict->charstrings_offset == 0 )
2471
0
    {
2472
0
      FT_ERROR(( "cff_font_load: no charstrings offset\n" ));
2473
0
      error = FT_THROW( Invalid_File_Format );
2474
0
      goto Exit;
2475
0
    }
2476
2477
1.82k
    font->num_glyphs = font->charstrings_index.count;
2478
2479
1.82k
    error = cff_index_get_pointers( &font->global_subrs_index,
2480
1.82k
                                    &font->global_subrs, NULL, NULL );
2481
2482
1.82k
    if ( error )
2483
0
      goto Exit;
2484
2485
    /* read the Charset and Encoding tables if available */
2486
1.82k
    if ( !cff2 && font->num_glyphs > 0 )
2487
1.37k
    {
2488
1.37k
      FT_Bool  invert = FT_BOOL( dict->cid_registry != 0xFFFFU && pure_cff );
2489
2490
2491
1.37k
      error = cff_charset_load( &font->charset, font->num_glyphs, stream,
2492
1.37k
                                base_offset, dict->charset_offset, invert );
2493
1.37k
      if ( error )
2494
8
        goto Exit;
2495
2496
      /* CID-keyed CFFs don't have an encoding */
2497
1.36k
      if ( dict->cid_registry == 0xFFFFU )
2498
1.36k
      {
2499
1.36k
        error = cff_encoding_load( &font->encoding,
2500
1.36k
                                   &font->charset,
2501
1.36k
                                   font->num_glyphs,
2502
1.36k
                                   stream,
2503
1.36k
                                   base_offset,
2504
1.36k
                                   dict->encoding_offset );
2505
1.36k
        if ( error )
2506
3
          goto Exit;
2507
1.81k
      }
2508
1.36k
    }
2509
2510
    /* get the font name (/CIDFontName for CID-keyed fonts, */
2511
    /* /FontName otherwise)                                 */
2512
1.81k
    font->font_name = cff_index_get_name( font, subfont_index );
2513
2514
4.93k
  Exit:
2515
4.93k
    cff_index_done( &string_index );
2516
2517
4.93k
    return error;
2518
1.81k
  }
2519
2520
2521
  FT_LOCAL_DEF( void )
2522
  cff_font_done( CFF_Font  font )
2523
4.93k
  {
2524
4.93k
    FT_Memory  memory = font->memory;
2525
4.93k
    FT_UInt    idx;
2526
2527
2528
4.93k
    cff_index_done( &font->global_subrs_index );
2529
4.93k
    cff_index_done( &font->font_dict_index );
2530
4.93k
    cff_index_done( &font->name_index );
2531
4.93k
    cff_index_done( &font->charstrings_index );
2532
2533
    /* release font dictionaries, but only if working with */
2534
    /* a CID keyed CFF font or a CFF2 font                 */
2535
4.93k
    if ( font->num_subfonts > 0 )
2536
0
    {
2537
0
      for ( idx = 0; idx < font->num_subfonts; idx++ )
2538
0
        cff_subfont_done( memory, font->subfonts[idx] );
2539
2540
      /* the subfonts array has been allocated as a single block */
2541
0
      FT_FREE( font->subfonts[0] );
2542
0
    }
2543
2544
4.93k
    cff_encoding_done( &font->encoding );
2545
4.93k
    cff_charset_done( &font->charset, font->stream );
2546
4.93k
    cff_vstore_done( &font->vstore, memory );
2547
2548
4.93k
    cff_subfont_done( memory, &font->top_font );
2549
2550
4.93k
    CFF_Done_FD_Select( &font->fd_select, font->stream );
2551
2552
4.93k
    FT_FREE( font->font_info );
2553
2554
4.93k
    FT_FREE( font->font_name );
2555
4.93k
    FT_FREE( font->global_subrs );
2556
4.93k
    FT_FREE( font->strings );
2557
4.93k
    FT_FREE( font->string_pool );
2558
2559
4.93k
    if ( font->cf2_instance.finalizer )
2560
0
    {
2561
0
      font->cf2_instance.finalizer( font->cf2_instance.data );
2562
0
      FT_FREE( font->cf2_instance.data );
2563
0
    }
2564
2565
4.93k
    FT_FREE( font->font_extra );
2566
4.93k
  }
2567
2568
2569
/* END */