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