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