• 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     FT_ASSERT( lenNDV == 0 || NDV );
1402 
1403     blend->builtBV = FALSE;
1404 
1405     vs = &blend->font->vstore;
1406 
1407     /* VStore and fvar must be consistent */
1408     if ( lenNDV != 0 && lenNDV != vs->axisCount )
1409     {
1410       FT_TRACE4(( " cff_blend_build_vector: Axis count mismatch\n" ));
1411       error = FT_THROW( Invalid_File_Format );
1412       goto Exit;
1413     }
1414 
1415     if ( vsindex >= vs->dataCount )
1416     {
1417       FT_TRACE4(( " cff_blend_build_vector: vsindex out of range\n" ));
1418       error = FT_THROW( Invalid_File_Format );
1419       goto Exit;
1420     }
1421 
1422     /* select the item variation data structure */
1423     varData = &vs->varData[vsindex];
1424 
1425     /* prepare buffer for the blend vector */
1426     len = varData->regionIdxCount + 1;    /* add 1 for default component */
1427     if ( FT_REALLOC( blend->BV,
1428                      blend->lenBV * sizeof( *blend->BV ),
1429                      len * sizeof( *blend->BV ) ) )
1430       goto Exit;
1431 
1432     blend->lenBV = len;
1433 
1434     /* outer loop steps through master designs to be blended */
1435     for ( master = 0; master < len; master++ )
1436     {
1437       FT_UInt         j;
1438       FT_UInt         idx;
1439       CFF_VarRegion*  varRegion;
1440 
1441 
1442       /* default factor is always one */
1443       if ( master == 0 )
1444       {
1445         blend->BV[master] = FT_FIXED_ONE;
1446         FT_TRACE4(( "   build blend vector len %d\n"
1447                     "   [ %f ",
1448                     len,
1449                     blend->BV[master] / 65536.0 ));
1450         continue;
1451       }
1452 
1453       /* VStore array does not include default master, so subtract one */
1454       idx       = varData->regionIndices[master - 1];
1455       varRegion = &vs->varRegionList[idx];
1456 
1457       if ( idx >= vs->regionCount )
1458       {
1459         FT_TRACE4(( " cff_blend_build_vector:"
1460                     " region index out of range\n" ));
1461         error = FT_THROW( Invalid_File_Format );
1462         goto Exit;
1463       }
1464 
1465       /* Note: `lenNDV' could be zero.                              */
1466       /*       In that case, build default blend vector (1,0,0...). */
1467       if ( !lenNDV )
1468       {
1469         blend->BV[master] = 0;
1470         continue;
1471       }
1472 
1473       /* In the normal case, initialize each component to 1 */
1474       /* before inner loop.                                 */
1475       blend->BV[master] = FT_FIXED_ONE; /* default */
1476 
1477       /* inner loop steps through axes in this region */
1478       for ( j = 0; j < lenNDV; j++ )
1479       {
1480         CFF_AxisCoords*  axis = &varRegion->axisList[j];
1481         FT_Fixed         axisScalar;
1482 
1483 
1484         /* compute the scalar contribution of this axis; */
1485         /* ignore invalid ranges                         */
1486         if ( axis->startCoord > axis->peakCoord ||
1487              axis->peakCoord > axis->endCoord   )
1488           axisScalar = FT_FIXED_ONE;
1489 
1490         else if ( axis->startCoord < 0 &&
1491                   axis->endCoord > 0   &&
1492                   axis->peakCoord != 0 )
1493           axisScalar = FT_FIXED_ONE;
1494 
1495         /* peak of 0 means ignore this axis */
1496         else if ( axis->peakCoord == 0 )
1497           axisScalar = FT_FIXED_ONE;
1498 
1499         /* ignore this region if coords are out of range */
1500         else if ( NDV[j] < axis->startCoord ||
1501                   NDV[j] > axis->endCoord   )
1502           axisScalar = 0;
1503 
1504         /* calculate a proportional factor */
1505         else
1506         {
1507           if ( NDV[j] == axis->peakCoord )
1508             axisScalar = FT_FIXED_ONE;
1509           else if ( NDV[j] < axis->peakCoord )
1510             axisScalar = FT_DivFix( NDV[j] - axis->startCoord,
1511                                     axis->peakCoord - axis->startCoord );
1512           else
1513             axisScalar = FT_DivFix( axis->endCoord - NDV[j],
1514                                     axis->endCoord - axis->peakCoord );
1515         }
1516 
1517         /* take product of all the axis scalars */
1518         blend->BV[master] = FT_MulFix( blend->BV[master], axisScalar );
1519       }
1520 
1521       FT_TRACE4(( ", %f ",
1522                   blend->BV[master] / 65536.0 ));
1523     }
1524 
1525     FT_TRACE4(( "]\n" ));
1526 
1527     /* record the parameters used to build the blend vector */
1528     blend->lastVsindex = vsindex;
1529 
1530     if ( lenNDV != 0 )
1531     {
1532       /* user has set a normalized vector */
1533       if ( FT_REALLOC( blend->lastNDV,
1534                        blend->lenNDV * sizeof ( *NDV ),
1535                        lenNDV * sizeof ( *NDV ) ) )
1536         goto Exit;
1537 
1538       FT_MEM_COPY( blend->lastNDV,
1539                    NDV,
1540                    lenNDV * sizeof ( *NDV ) );
1541     }
1542 
1543     blend->lenNDV  = lenNDV;
1544     blend->builtBV = TRUE;
1545 
1546   Exit:
1547     return error;
1548   }
1549 
1550 
1551   /* `lenNDV' is zero for default vector;           */
1552   /* return TRUE if blend vector needs to be built. */
1553   FT_LOCAL_DEF( FT_Bool )
cff_blend_check_vector(CFF_Blend blend,FT_UInt vsindex,FT_UInt lenNDV,FT_Fixed * NDV)1554   cff_blend_check_vector( CFF_Blend  blend,
1555                           FT_UInt    vsindex,
1556                           FT_UInt    lenNDV,
1557                           FT_Fixed*  NDV )
1558   {
1559     if ( !blend->builtBV                                ||
1560          blend->lastVsindex != vsindex                  ||
1561          blend->lenNDV != lenNDV                        ||
1562          ( lenNDV                                     &&
1563            ft_memcmp( NDV,
1564                       blend->lastNDV,
1565                       lenNDV * sizeof ( *NDV ) ) != 0 ) )
1566     {
1567       /* need to build blend vector */
1568       return TRUE;
1569     }
1570 
1571     return FALSE;
1572   }
1573 
1574 
1575 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
1576 
1577   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)1578   cff_get_var_blend( CFF_Face     face,
1579                      FT_UInt     *num_coords,
1580                      FT_Fixed*   *coords,
1581                      FT_Fixed*   *normalizedcoords,
1582                      FT_MM_Var*  *mm_var )
1583   {
1584     FT_Service_MultiMasters  mm = (FT_Service_MultiMasters)face->mm;
1585 
1586 
1587     return mm->get_var_blend( FT_FACE( face ),
1588                               num_coords,
1589                               coords,
1590                               normalizedcoords,
1591                               mm_var );
1592   }
1593 
1594 
1595   FT_LOCAL_DEF( void )
cff_done_blend(CFF_Face face)1596   cff_done_blend( CFF_Face  face )
1597   {
1598     FT_Service_MultiMasters  mm = (FT_Service_MultiMasters)face->mm;
1599 
1600 
1601     if (mm)
1602       mm->done_blend( FT_FACE( face ) );
1603   }
1604 
1605 #endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */
1606 
1607 
1608   static void
cff_encoding_done(CFF_Encoding encoding)1609   cff_encoding_done( CFF_Encoding  encoding )
1610   {
1611     encoding->format = 0;
1612     encoding->offset = 0;
1613     encoding->count  = 0;
1614   }
1615 
1616 
1617   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)1618   cff_encoding_load( CFF_Encoding  encoding,
1619                      CFF_Charset   charset,
1620                      FT_UInt       num_glyphs,
1621                      FT_Stream     stream,
1622                      FT_ULong      base_offset,
1623                      FT_ULong      offset )
1624   {
1625     FT_Error   error = FT_Err_Ok;
1626     FT_UInt    count;
1627     FT_UInt    j;
1628     FT_UShort  glyph_sid;
1629     FT_UInt    glyph_code;
1630 
1631 
1632     /* Check for charset->sids.  If we do not have this, we fail. */
1633     if ( !charset->sids )
1634     {
1635       error = FT_THROW( Invalid_File_Format );
1636       goto Exit;
1637     }
1638 
1639     /* Zero out the code to gid/sid mappings. */
1640     for ( j = 0; j < 256; j++ )
1641     {
1642       encoding->sids [j] = 0;
1643       encoding->codes[j] = 0;
1644     }
1645 
1646     /* Note: The encoding table in a CFF font is indexed by glyph index;  */
1647     /* the first encoded glyph index is 1.  Hence, we read the character  */
1648     /* code (`glyph_code') at index j and make the assignment:            */
1649     /*                                                                    */
1650     /*    encoding->codes[glyph_code] = j + 1                             */
1651     /*                                                                    */
1652     /* We also make the assignment:                                       */
1653     /*                                                                    */
1654     /*    encoding->sids[glyph_code] = charset->sids[j + 1]               */
1655     /*                                                                    */
1656     /* This gives us both a code to GID and a code to SID mapping.        */
1657 
1658     if ( offset > 1 )
1659     {
1660       encoding->offset = base_offset + offset;
1661 
1662       /* we need to parse the table to determine its size */
1663       if ( FT_STREAM_SEEK( encoding->offset ) ||
1664            FT_READ_BYTE( encoding->format )   ||
1665            FT_READ_BYTE( count )              )
1666         goto Exit;
1667 
1668       switch ( encoding->format & 0x7F )
1669       {
1670       case 0:
1671         {
1672           FT_Byte*  p;
1673 
1674 
1675           /* By convention, GID 0 is always ".notdef" and is never */
1676           /* coded in the font.  Hence, the number of codes found  */
1677           /* in the table is `count+1'.                            */
1678           /*                                                       */
1679           encoding->count = count + 1;
1680 
1681           if ( FT_FRAME_ENTER( count ) )
1682             goto Exit;
1683 
1684           p = (FT_Byte*)stream->cursor;
1685 
1686           for ( j = 1; j <= count; j++ )
1687           {
1688             glyph_code = *p++;
1689 
1690             /* Make sure j is not too big. */
1691             if ( j < num_glyphs )
1692             {
1693               /* Assign code to GID mapping. */
1694               encoding->codes[glyph_code] = (FT_UShort)j;
1695 
1696               /* Assign code to SID mapping. */
1697               encoding->sids[glyph_code] = charset->sids[j];
1698             }
1699           }
1700 
1701           FT_FRAME_EXIT();
1702         }
1703         break;
1704 
1705       case 1:
1706         {
1707           FT_UInt  nleft;
1708           FT_UInt  i = 1;
1709           FT_UInt  k;
1710 
1711 
1712           encoding->count = 0;
1713 
1714           /* Parse the Format1 ranges. */
1715           for ( j = 0;  j < count; j++, i += nleft )
1716           {
1717             /* Read the first glyph code of the range. */
1718             if ( FT_READ_BYTE( glyph_code ) )
1719               goto Exit;
1720 
1721             /* Read the number of codes in the range. */
1722             if ( FT_READ_BYTE( nleft ) )
1723               goto Exit;
1724 
1725             /* Increment nleft, so we read `nleft + 1' codes/sids. */
1726             nleft++;
1727 
1728             /* compute max number of character codes */
1729             if ( (FT_UInt)nleft > encoding->count )
1730               encoding->count = nleft;
1731 
1732             /* Fill in the range of codes/sids. */
1733             for ( k = i; k < nleft + i; k++, glyph_code++ )
1734             {
1735               /* Make sure k is not too big. */
1736               if ( k < num_glyphs && glyph_code < 256 )
1737               {
1738                 /* Assign code to GID mapping. */
1739                 encoding->codes[glyph_code] = (FT_UShort)k;
1740 
1741                 /* Assign code to SID mapping. */
1742                 encoding->sids[glyph_code] = charset->sids[k];
1743               }
1744             }
1745           }
1746 
1747           /* simple check; one never knows what can be found in a font */
1748           if ( encoding->count > 256 )
1749             encoding->count = 256;
1750         }
1751         break;
1752 
1753       default:
1754         FT_ERROR(( "cff_encoding_load: invalid table format\n" ));
1755         error = FT_THROW( Invalid_File_Format );
1756         goto Exit;
1757       }
1758 
1759       /* Parse supplemental encodings, if any. */
1760       if ( encoding->format & 0x80 )
1761       {
1762         FT_UInt  gindex;
1763 
1764 
1765         /* count supplements */
1766         if ( FT_READ_BYTE( count ) )
1767           goto Exit;
1768 
1769         for ( j = 0; j < count; j++ )
1770         {
1771           /* Read supplemental glyph code. */
1772           if ( FT_READ_BYTE( glyph_code ) )
1773             goto Exit;
1774 
1775           /* Read the SID associated with this glyph code. */
1776           if ( FT_READ_USHORT( glyph_sid ) )
1777             goto Exit;
1778 
1779           /* Assign code to SID mapping. */
1780           encoding->sids[glyph_code] = glyph_sid;
1781 
1782           /* First, look up GID which has been assigned to */
1783           /* SID glyph_sid.                                */
1784           for ( gindex = 0; gindex < num_glyphs; gindex++ )
1785           {
1786             if ( charset->sids[gindex] == glyph_sid )
1787             {
1788               encoding->codes[glyph_code] = (FT_UShort)gindex;
1789               break;
1790             }
1791           }
1792         }
1793       }
1794     }
1795     else
1796     {
1797       /* We take into account the fact a CFF font can use a predefined */
1798       /* encoding without containing all of the glyphs encoded by this */
1799       /* encoding (see the note at the end of section 12 in the CFF    */
1800       /* specification).                                               */
1801 
1802       switch ( (FT_UInt)offset )
1803       {
1804       case 0:
1805         /* First, copy the code to SID mapping. */
1806         FT_ARRAY_COPY( encoding->sids, cff_standard_encoding, 256 );
1807         goto Populate;
1808 
1809       case 1:
1810         /* First, copy the code to SID mapping. */
1811         FT_ARRAY_COPY( encoding->sids, cff_expert_encoding, 256 );
1812 
1813       Populate:
1814         /* Construct code to GID mapping from code to SID mapping */
1815         /* and charset.                                           */
1816 
1817         encoding->count = 0;
1818 
1819         error = cff_charset_compute_cids( charset, num_glyphs,
1820                                           stream->memory );
1821         if ( error )
1822           goto Exit;
1823 
1824         for ( j = 0; j < 256; j++ )
1825         {
1826           FT_UInt  sid = encoding->sids[j];
1827           FT_UInt  gid = 0;
1828 
1829 
1830           if ( sid )
1831             gid = cff_charset_cid_to_gindex( charset, sid );
1832 
1833           if ( gid != 0 )
1834           {
1835             encoding->codes[j] = (FT_UShort)gid;
1836             encoding->count    = j + 1;
1837           }
1838           else
1839           {
1840             encoding->codes[j] = 0;
1841             encoding->sids [j] = 0;
1842           }
1843         }
1844         break;
1845 
1846       default:
1847         FT_ERROR(( "cff_encoding_load: invalid table format\n" ));
1848         error = FT_THROW( Invalid_File_Format );
1849         goto Exit;
1850       }
1851     }
1852 
1853   Exit:
1854 
1855     /* Clean up if there was an error. */
1856     return error;
1857   }
1858 
1859 
1860   /* Parse private dictionary; first call is always from `cff_face_init', */
1861   /* so NDV has not been set for CFF2 variation.                          */
1862   /*                                                                      */
1863   /* `cff_slot_load' must call this function each time NDV changes.       */
1864   FT_LOCAL_DEF( FT_Error )
cff_load_private_dict(CFF_Font font,CFF_SubFont subfont,FT_UInt lenNDV,FT_Fixed * NDV)1865   cff_load_private_dict( CFF_Font     font,
1866                          CFF_SubFont  subfont,
1867                          FT_UInt      lenNDV,
1868                          FT_Fixed*    NDV )
1869   {
1870     FT_Error         error  = FT_Err_Ok;
1871     CFF_ParserRec    parser;
1872     CFF_FontRecDict  top    = &subfont->font_dict;
1873     CFF_Private      priv   = &subfont->private_dict;
1874     FT_Stream        stream = font->stream;
1875     FT_UInt          stackSize;
1876 
1877 
1878     /* store handle needed to access memory, vstore for blend;    */
1879     /* we need this for clean-up even if there is no private DICT */
1880     subfont->blend.font   = font;
1881     subfont->blend.usedBV = FALSE;  /* clear state */
1882 
1883     if ( !top->private_offset || !top->private_size )
1884       goto Exit2;       /* no private DICT, do nothing */
1885 
1886     /* set defaults */
1887     FT_ZERO( priv );
1888 
1889     priv->blue_shift       = 7;
1890     priv->blue_fuzz        = 1;
1891     priv->lenIV            = -1;
1892     priv->expansion_factor = (FT_Fixed)( 0.06 * 0x10000L );
1893     priv->blue_scale       = (FT_Fixed)( 0.039625 * 0x10000L * 1000 );
1894 
1895     /* provide inputs for blend calculations */
1896     priv->subfont   = subfont;
1897     subfont->lenNDV = lenNDV;
1898     subfont->NDV    = NDV;
1899 
1900     /* add 1 for the operator */
1901     stackSize = font->cff2 ? font->top_font.font_dict.maxstack + 1
1902                            : CFF_MAX_STACK_DEPTH + 1;
1903 
1904     if ( cff_parser_init( &parser,
1905                           font->cff2 ? CFF2_CODE_PRIVATE : CFF_CODE_PRIVATE,
1906                           priv,
1907                           font->library,
1908                           stackSize,
1909                           top->num_designs,
1910                           top->num_axes ) )
1911       goto Exit;
1912 
1913     if ( FT_STREAM_SEEK( font->base_offset + top->private_offset ) ||
1914          FT_FRAME_ENTER( top->private_size )                       )
1915       goto Exit;
1916 
1917     FT_TRACE4(( " private dictionary:\n" ));
1918     error = cff_parser_run( &parser,
1919                             (FT_Byte*)stream->cursor,
1920                             (FT_Byte*)stream->limit );
1921     FT_FRAME_EXIT();
1922 
1923     if ( error )
1924       goto Exit;
1925 
1926     /* ensure that `num_blue_values' is even */
1927     priv->num_blue_values &= ~1;
1928 
1929     /* sanitize `initialRandomSeed' to be a positive value, if necessary;  */
1930     /* this is not mandated by the specification but by our implementation */
1931     if ( priv->initial_random_seed < 0 )
1932       priv->initial_random_seed = -priv->initial_random_seed;
1933     else if ( priv->initial_random_seed == 0 )
1934       priv->initial_random_seed = 987654321;
1935 
1936   Exit:
1937     /* clean up */
1938     cff_blend_clear( subfont ); /* clear blend stack */
1939     cff_parser_done( &parser ); /* free parser stack */
1940 
1941   Exit2:
1942     /* no clean up (parser not initialized) */
1943     return error;
1944   }
1945 
1946 
1947   /* There are 3 ways to call this function, distinguished by code.  */
1948   /*                                                                 */
1949   /* . CFF_CODE_TOPDICT for either a CFF Top DICT or a CFF Font DICT */
1950   /* . CFF2_CODE_TOPDICT for CFF2 Top DICT                           */
1951   /* . CFF2_CODE_FONTDICT for CFF2 Font DICT                         */
1952 
1953   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)1954   cff_subfont_load( CFF_SubFont  subfont,
1955                     CFF_Index    idx,
1956                     FT_UInt      font_index,
1957                     FT_Stream    stream,
1958                     FT_ULong     base_offset,
1959                     FT_UInt      code,
1960                     CFF_Font     font,
1961                     CFF_Face     face )
1962   {
1963     FT_Error         error;
1964     CFF_ParserRec    parser;
1965     FT_Byte*         dict = NULL;
1966     FT_ULong         dict_len;
1967     CFF_FontRecDict  top  = &subfont->font_dict;
1968     CFF_Private      priv = &subfont->private_dict;
1969 
1970     PSAux_Service  psaux = (PSAux_Service)face->psaux;
1971 
1972     FT_Bool  cff2      = FT_BOOL( code == CFF2_CODE_TOPDICT  ||
1973                                   code == CFF2_CODE_FONTDICT );
1974     FT_UInt  stackSize = cff2 ? CFF2_DEFAULT_STACK
1975                               : CFF_MAX_STACK_DEPTH;
1976 
1977 
1978     /* Note: We use default stack size for CFF2 Font DICT because        */
1979     /*       Top and Font DICTs are not allowed to have blend operators. */
1980     error = cff_parser_init( &parser,
1981                              code,
1982                              &subfont->font_dict,
1983                              font->library,
1984                              stackSize,
1985                              0,
1986                              0 );
1987     if ( error )
1988       goto Exit;
1989 
1990     /* set defaults */
1991     FT_ZERO( top );
1992 
1993     top->underline_position  = -( 100L << 16 );
1994     top->underline_thickness = 50L << 16;
1995     top->charstring_type     = 2;
1996     top->font_matrix.xx      = 0x10000L;
1997     top->font_matrix.yy      = 0x10000L;
1998     top->cid_count           = 8720;
1999 
2000     /* we use the implementation specific SID value 0xFFFF to indicate */
2001     /* missing entries                                                 */
2002     top->version             = 0xFFFFU;
2003     top->notice              = 0xFFFFU;
2004     top->copyright           = 0xFFFFU;
2005     top->full_name           = 0xFFFFU;
2006     top->family_name         = 0xFFFFU;
2007     top->weight              = 0xFFFFU;
2008     top->embedded_postscript = 0xFFFFU;
2009 
2010     top->cid_registry        = 0xFFFFU;
2011     top->cid_ordering        = 0xFFFFU;
2012     top->cid_font_name       = 0xFFFFU;
2013 
2014     /* set default stack size */
2015     top->maxstack            = cff2 ? CFF2_DEFAULT_STACK : 48;
2016 
2017     if ( idx->count )   /* count is nonzero for a real index */
2018       error = cff_index_access_element( idx, font_index, &dict, &dict_len );
2019     else
2020     {
2021       /* CFF2 has a fake top dict index;     */
2022       /* simulate `cff_index_access_element' */
2023 
2024       /* Note: macros implicitly use `stream' and set `error' */
2025       if ( FT_STREAM_SEEK( idx->data_offset )       ||
2026            FT_FRAME_EXTRACT( idx->data_size, dict ) )
2027         goto Exit;
2028 
2029       dict_len = idx->data_size;
2030     }
2031 
2032     if ( !error )
2033     {
2034       FT_TRACE4(( " top dictionary:\n" ));
2035       error = cff_parser_run( &parser, dict, dict + dict_len );
2036     }
2037 
2038     /* clean up regardless of error */
2039     if ( idx->count )
2040       cff_index_forget_element( idx, &dict );
2041     else
2042       FT_FRAME_RELEASE( dict );
2043 
2044     if ( error )
2045       goto Exit;
2046 
2047     /* if it is a CID font, we stop there */
2048     if ( top->cid_registry != 0xFFFFU )
2049       goto Exit;
2050 
2051     /* Parse the private dictionary, if any.                   */
2052     /*                                                         */
2053     /* CFF2 does not have a private dictionary in the Top DICT */
2054     /* but may have one in a Font DICT.  We need to parse      */
2055     /* the latter here in order to load any local subrs.       */
2056     error = cff_load_private_dict( font, subfont, 0, 0 );
2057     if ( error )
2058       goto Exit;
2059 
2060     if ( !cff2 )
2061     {
2062       /*
2063        * Initialize the random number generator.
2064        *
2065        * . If we have a face-specific seed, use it.
2066        *   If non-zero, update it to a positive value.
2067        *
2068        * . Otherwise, use the seed from the CFF driver.
2069        *   If non-zero, update it to a positive value.
2070        *
2071        * . If the random value is zero, use the seed given by the subfont's
2072        *   `initialRandomSeed' value.
2073        *
2074        */
2075       if ( face->root.internal->random_seed == -1 )
2076       {
2077         PS_Driver  driver = (PS_Driver)FT_FACE_DRIVER( face );
2078 
2079 
2080         subfont->random = (FT_UInt32)driver->random_seed;
2081         if ( driver->random_seed )
2082         {
2083           do
2084           {
2085             driver->random_seed =
2086               (FT_Int32)psaux->cff_random( (FT_UInt32)driver->random_seed );
2087 
2088           } while ( driver->random_seed < 0 );
2089         }
2090       }
2091       else
2092       {
2093         subfont->random = (FT_UInt32)face->root.internal->random_seed;
2094         if ( face->root.internal->random_seed )
2095         {
2096           do
2097           {
2098             face->root.internal->random_seed =
2099               (FT_Int32)psaux->cff_random(
2100                 (FT_UInt32)face->root.internal->random_seed );
2101 
2102           } while ( face->root.internal->random_seed < 0 );
2103         }
2104       }
2105 
2106       if ( !subfont->random )
2107         subfont->random = (FT_UInt32)priv->initial_random_seed;
2108     }
2109 
2110     /* read the local subrs, if any */
2111     if ( priv->local_subrs_offset )
2112     {
2113       if ( FT_STREAM_SEEK( base_offset + top->private_offset +
2114                            priv->local_subrs_offset ) )
2115         goto Exit;
2116 
2117       error = cff_index_init( &subfont->local_subrs_index, stream, 1, cff2 );
2118       if ( error )
2119         goto Exit;
2120 
2121       error = cff_index_get_pointers( &subfont->local_subrs_index,
2122                                       &subfont->local_subrs, NULL, NULL );
2123       if ( error )
2124         goto Exit;
2125     }
2126 
2127   Exit:
2128     cff_parser_done( &parser ); /* free parser stack */
2129 
2130     return error;
2131   }
2132 
2133 
2134   static void
cff_subfont_done(FT_Memory memory,CFF_SubFont subfont)2135   cff_subfont_done( FT_Memory    memory,
2136                     CFF_SubFont  subfont )
2137   {
2138     if ( subfont )
2139     {
2140       cff_index_done( &subfont->local_subrs_index );
2141       FT_FREE( subfont->local_subrs );
2142 
2143       FT_FREE( subfont->blend.lastNDV );
2144       FT_FREE( subfont->blend.BV );
2145       FT_FREE( subfont->blend_stack );
2146     }
2147   }
2148 
2149 
2150   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)2151   cff_font_load( FT_Library library,
2152                  FT_Stream  stream,
2153                  FT_Int     face_index,
2154                  CFF_Font   font,
2155                  CFF_Face   face,
2156                  FT_Bool    pure_cff,
2157                  FT_Bool    cff2 )
2158   {
2159     static const FT_Frame_Field  cff_header_fields[] =
2160     {
2161 #undef  FT_STRUCTURE
2162 #define FT_STRUCTURE  CFF_FontRec
2163 
2164       FT_FRAME_START( 3 ),
2165         FT_FRAME_BYTE( version_major ),
2166         FT_FRAME_BYTE( version_minor ),
2167         FT_FRAME_BYTE( header_size ),
2168       FT_FRAME_END
2169     };
2170 
2171     FT_Error         error;
2172     FT_Memory        memory = stream->memory;
2173     FT_ULong         base_offset;
2174     CFF_FontRecDict  dict;
2175     CFF_IndexRec     string_index;
2176     FT_UInt          subfont_index;
2177 
2178 
2179     FT_ZERO( font );
2180     FT_ZERO( &string_index );
2181 
2182     dict        = &font->top_font.font_dict;
2183     base_offset = FT_STREAM_POS();
2184 
2185     font->library     = library;
2186     font->stream      = stream;
2187     font->memory      = memory;
2188     font->cff2        = cff2;
2189     font->base_offset = base_offset;
2190 
2191     /* read CFF font header */
2192     if ( FT_STREAM_READ_FIELDS( cff_header_fields, font ) )
2193       goto Exit;
2194 
2195     if ( cff2 )
2196     {
2197       if ( font->version_major != 2 ||
2198            font->header_size < 5    )
2199       {
2200         FT_TRACE2(( "  not a CFF2 font header\n" ));
2201         error = FT_THROW( Unknown_File_Format );
2202         goto Exit;
2203       }
2204 
2205       if ( FT_READ_USHORT( font->top_dict_length ) )
2206         goto Exit;
2207     }
2208     else
2209     {
2210       FT_Byte  absolute_offset;
2211 
2212 
2213       if ( FT_READ_BYTE( absolute_offset ) )
2214         goto Exit;
2215 
2216       if ( font->version_major != 1 ||
2217            font->header_size < 4    ||
2218            absolute_offset > 4      )
2219       {
2220         FT_TRACE2(( "  not a CFF font header\n" ));
2221         error = FT_THROW( Unknown_File_Format );
2222         goto Exit;
2223       }
2224     }
2225 
2226     /* skip the rest of the header */
2227     if ( FT_STREAM_SEEK( base_offset + font->header_size ) )
2228     {
2229       /* For pure CFFs we have read only four bytes so far.  Contrary to */
2230       /* other formats like SFNT those bytes doesn't define a signature; */
2231       /* it is thus possible that the font isn't a CFF at all.           */
2232       if ( pure_cff )
2233       {
2234         FT_TRACE2(( "  not a CFF file\n" ));
2235         error = FT_THROW( Unknown_File_Format );
2236       }
2237       goto Exit;
2238     }
2239 
2240     if ( cff2 )
2241     {
2242       /* For CFF2, the top dict data immediately follow the header    */
2243       /* and the length is stored in the header `offSize' field;      */
2244       /* there is no index for it.                                    */
2245       /*                                                              */
2246       /* Use the `font_dict_index' to save the current position       */
2247       /* and length of data, but leave count at zero as an indicator. */
2248       FT_ZERO( &font->font_dict_index );
2249 
2250       font->font_dict_index.data_offset = FT_STREAM_POS();
2251       font->font_dict_index.data_size   = font->top_dict_length;
2252 
2253       /* skip the top dict data for now, we will parse it later */
2254       if ( FT_STREAM_SKIP( font->top_dict_length ) )
2255         goto Exit;
2256 
2257       /* next, read the global subrs index */
2258       if ( FT_SET_ERROR( cff_index_init( &font->global_subrs_index,
2259                                          stream, 1, cff2 ) ) )
2260         goto Exit;
2261     }
2262     else
2263     {
2264       /* for CFF, read the name, top dict, string and global subrs index */
2265       if ( FT_SET_ERROR( cff_index_init( &font->name_index,
2266                                          stream, 0, cff2 ) ) )
2267       {
2268         if ( pure_cff )
2269         {
2270           FT_TRACE2(( "  not a CFF file\n" ));
2271           error = FT_THROW( Unknown_File_Format );
2272         }
2273         goto Exit;
2274       }
2275 
2276       /* if we have an empty font name,      */
2277       /* it must be the only font in the CFF */
2278       if ( font->name_index.count > 1                          &&
2279            font->name_index.data_size < font->name_index.count )
2280       {
2281         /* for pure CFFs, we still haven't checked enough bytes */
2282         /* to be sure that it is a CFF at all                   */
2283         error = pure_cff ? FT_THROW( Unknown_File_Format )
2284                          : FT_THROW( Invalid_File_Format );
2285         goto Exit;
2286       }
2287 
2288       if ( FT_SET_ERROR( cff_index_init( &font->font_dict_index,
2289                                          stream, 0, cff2 ) )                 ||
2290            FT_SET_ERROR( cff_index_init( &string_index,
2291                                          stream, 1, cff2 ) )                 ||
2292            FT_SET_ERROR( cff_index_init( &font->global_subrs_index,
2293                                          stream, 1, cff2 ) )                 ||
2294            FT_SET_ERROR( cff_index_get_pointers( &string_index,
2295                                                  &font->strings,
2296                                                  &font->string_pool,
2297                                                  &font->string_pool_size ) ) )
2298         goto Exit;
2299 
2300       /* there must be a Top DICT index entry for each name index entry */
2301       if ( font->name_index.count > font->font_dict_index.count )
2302       {
2303         FT_ERROR(( "cff_font_load:"
2304                    " not enough entries in Top DICT index\n" ));
2305         error = FT_THROW( Invalid_File_Format );
2306         goto Exit;
2307       }
2308     }
2309 
2310     font->num_strings = string_index.count;
2311 
2312     if ( pure_cff )
2313     {
2314       /* well, we don't really forget the `disabled' fonts... */
2315       subfont_index = (FT_UInt)( face_index & 0xFFFF );
2316 
2317       if ( face_index > 0 && subfont_index >= font->name_index.count )
2318       {
2319         FT_ERROR(( "cff_font_load:"
2320                    " invalid subfont index for pure CFF font (%d)\n",
2321                    subfont_index ));
2322         error = FT_THROW( Invalid_Argument );
2323         goto Exit;
2324       }
2325 
2326       font->num_faces = font->name_index.count;
2327     }
2328     else
2329     {
2330       subfont_index = 0;
2331 
2332       if ( font->name_index.count > 1 )
2333       {
2334         FT_ERROR(( "cff_font_load:"
2335                    " invalid CFF font with multiple subfonts\n"
2336                    "              "
2337                    " in SFNT wrapper\n" ));
2338         error = FT_THROW( Invalid_File_Format );
2339         goto Exit;
2340       }
2341     }
2342 
2343     /* in case of a font format check, simply exit now */
2344     if ( face_index < 0 )
2345       goto Exit;
2346 
2347     /* now, parse the top-level font dictionary */
2348     FT_TRACE4(( "parsing top-level\n" ));
2349     error = cff_subfont_load( &font->top_font,
2350                               &font->font_dict_index,
2351                               subfont_index,
2352                               stream,
2353                               base_offset,
2354                               cff2 ? CFF2_CODE_TOPDICT : CFF_CODE_TOPDICT,
2355                               font,
2356                               face );
2357     if ( error )
2358       goto Exit;
2359 
2360     if ( FT_STREAM_SEEK( base_offset + dict->charstrings_offset ) )
2361       goto Exit;
2362 
2363     error = cff_index_init( &font->charstrings_index, stream, 0, cff2 );
2364     if ( error )
2365       goto Exit;
2366 
2367     /* now, check for a CID or CFF2 font */
2368     if ( dict->cid_registry != 0xFFFFU ||
2369          cff2                          )
2370     {
2371       CFF_IndexRec  fd_index;
2372       CFF_SubFont   sub = NULL;
2373       FT_UInt       idx;
2374 
2375 
2376       /* for CFF2, read the Variation Store if available;                 */
2377       /* this must follow the Top DICT parse and precede any Private DICT */
2378       error = cff_vstore_load( &font->vstore,
2379                                stream,
2380                                base_offset,
2381                                dict->vstore_offset );
2382       if ( error )
2383         goto Exit;
2384 
2385       /* this is a CID-keyed font, we must now allocate a table of */
2386       /* sub-fonts, then load each of them separately              */
2387       if ( FT_STREAM_SEEK( base_offset + dict->cid_fd_array_offset ) )
2388         goto Exit;
2389 
2390       error = cff_index_init( &fd_index, stream, 0, cff2 );
2391       if ( error )
2392         goto Exit;
2393 
2394       /* Font Dicts are not limited to 256 for CFF2. */
2395       /* TODO: support this for CFF2                 */
2396       if ( fd_index.count > CFF_MAX_CID_FONTS )
2397       {
2398         FT_TRACE0(( "cff_font_load: FD array too large in CID font\n" ));
2399         goto Fail_CID;
2400       }
2401 
2402       /* allocate & read each font dict independently */
2403       font->num_subfonts = fd_index.count;
2404       if ( FT_NEW_ARRAY( sub, fd_index.count ) )
2405         goto Fail_CID;
2406 
2407       /* set up pointer table */
2408       for ( idx = 0; idx < fd_index.count; idx++ )
2409         font->subfonts[idx] = sub + idx;
2410 
2411       /* now load each subfont independently */
2412       for ( idx = 0; idx < fd_index.count; idx++ )
2413       {
2414         sub = font->subfonts[idx];
2415         FT_TRACE4(( "parsing subfont %u\n", idx ));
2416         error = cff_subfont_load( sub,
2417                                   &fd_index,
2418                                   idx,
2419                                   stream,
2420                                   base_offset,
2421                                   cff2 ? CFF2_CODE_FONTDICT
2422                                        : CFF_CODE_TOPDICT,
2423                                   font,
2424                                   face );
2425         if ( error )
2426           goto Fail_CID;
2427       }
2428 
2429       /* now load the FD Select array;               */
2430       /* CFF2 omits FDSelect if there is only one FD */
2431       if ( !cff2 || fd_index.count > 1 )
2432         error = CFF_Load_FD_Select( &font->fd_select,
2433                                     font->charstrings_index.count,
2434                                     stream,
2435                                     base_offset + dict->cid_fd_select_offset );
2436 
2437     Fail_CID:
2438       cff_index_done( &fd_index );
2439 
2440       if ( error )
2441         goto Exit;
2442     }
2443     else
2444       font->num_subfonts = 0;
2445 
2446     /* read the charstrings index now */
2447     if ( dict->charstrings_offset == 0 )
2448     {
2449       FT_ERROR(( "cff_font_load: no charstrings offset\n" ));
2450       error = FT_THROW( Invalid_File_Format );
2451       goto Exit;
2452     }
2453 
2454     font->num_glyphs = font->charstrings_index.count;
2455 
2456     error = cff_index_get_pointers( &font->global_subrs_index,
2457                                     &font->global_subrs, NULL, NULL );
2458 
2459     if ( error )
2460       goto Exit;
2461 
2462     /* read the Charset and Encoding tables if available */
2463     if ( !cff2 && font->num_glyphs > 0 )
2464     {
2465       FT_Bool  invert = FT_BOOL( dict->cid_registry != 0xFFFFU && pure_cff );
2466 
2467 
2468       error = cff_charset_load( &font->charset, font->num_glyphs, stream,
2469                                 base_offset, dict->charset_offset, invert );
2470       if ( error )
2471         goto Exit;
2472 
2473       /* CID-keyed CFFs don't have an encoding */
2474       if ( dict->cid_registry == 0xFFFFU )
2475       {
2476         error = cff_encoding_load( &font->encoding,
2477                                    &font->charset,
2478                                    font->num_glyphs,
2479                                    stream,
2480                                    base_offset,
2481                                    dict->encoding_offset );
2482         if ( error )
2483           goto Exit;
2484       }
2485     }
2486 
2487     /* get the font name (/CIDFontName for CID-keyed fonts, */
2488     /* /FontName otherwise)                                 */
2489     font->font_name = cff_index_get_name( font, subfont_index );
2490 
2491   Exit:
2492     cff_index_done( &string_index );
2493 
2494     return error;
2495   }
2496 
2497 
2498   FT_LOCAL_DEF( void )
cff_font_done(CFF_Font font)2499   cff_font_done( CFF_Font  font )
2500   {
2501     FT_Memory  memory = font->memory;
2502     FT_UInt    idx;
2503 
2504 
2505     cff_index_done( &font->global_subrs_index );
2506     cff_index_done( &font->font_dict_index );
2507     cff_index_done( &font->name_index );
2508     cff_index_done( &font->charstrings_index );
2509 
2510     /* release font dictionaries, but only if working with */
2511     /* a CID keyed CFF font or a CFF2 font                 */
2512     if ( font->num_subfonts > 0 )
2513     {
2514       for ( idx = 0; idx < font->num_subfonts; idx++ )
2515         cff_subfont_done( memory, font->subfonts[idx] );
2516 
2517       /* the subfonts array has been allocated as a single block */
2518       FT_FREE( font->subfonts[0] );
2519     }
2520 
2521     cff_encoding_done( &font->encoding );
2522     cff_charset_done( &font->charset, font->stream );
2523     cff_vstore_done( &font->vstore, memory );
2524 
2525     cff_subfont_done( memory, &font->top_font );
2526 
2527     CFF_Done_FD_Select( &font->fd_select, font->stream );
2528 
2529     FT_FREE( font->font_info );
2530 
2531     FT_FREE( font->font_name );
2532     FT_FREE( font->global_subrs );
2533     FT_FREE( font->strings );
2534     FT_FREE( font->string_pool );
2535 
2536     if ( font->cf2_instance.finalizer )
2537     {
2538       font->cf2_instance.finalizer( font->cf2_instance.data );
2539       FT_FREE( font->cf2_instance.data );
2540     }
2541 
2542     FT_FREE( font->font_extra );
2543   }
2544 
2545 
2546 /* END */
2547