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