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