/****************************************************************************
 *
 * cffload.c
 *
 *   OpenType and CFF data/program tables loader (body).
 *
 * Copyright (C) 1996-2020 by
 * David Turner, Robert Wilhelm, and Werner Lemberg.
 *
 * This file is part of the FreeType project, and may only be used,
 * modified, and distributed under the terms of the FreeType project
 * license, LICENSE.TXT.  By continuing to use, modify, or distribute
 * this file you indicate that you have read the license and
 * understand and accept it fully.
 *
 */


#include <ft2build.h>
#include FT_INTERNAL_DEBUG_H
#include FT_INTERNAL_OBJECTS_H
#include FT_INTERNAL_STREAM_H
#include FT_TRUETYPE_TAGS_H
#include FT_TYPE1_TABLES_H
#include FT_INTERNAL_POSTSCRIPT_AUX_H

#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
#include FT_MULTIPLE_MASTERS_H
#include FT_SERVICE_MULTIPLE_MASTERS_H
#endif

#include "cffload.h"
#include "cffparse.h"

#include "cfferrs.h"


#define FT_FIXED_ONE  ( (FT_Fixed)0x10000 )


#if 1

  static const FT_UShort  cff_isoadobe_charset[229] =
  {
      0,   1,   2,   3,   4,   5,   6,   7,
      8,   9,  10,  11,  12,  13,  14,  15,
     16,  17,  18,  19,  20,  21,  22,  23,
     24,  25,  26,  27,  28,  29,  30,  31,
     32,  33,  34,  35,  36,  37,  38,  39,
     40,  41,  42,  43,  44,  45,  46,  47,
     48,  49,  50,  51,  52,  53,  54,  55,
     56,  57,  58,  59,  60,  61,  62,  63,
     64,  65,  66,  67,  68,  69,  70,  71,
     72,  73,  74,  75,  76,  77,  78,  79,
     80,  81,  82,  83,  84,  85,  86,  87,
     88,  89,  90,  91,  92,  93,  94,  95,
     96,  97,  98,  99, 100, 101, 102, 103,
    104, 105, 106, 107, 108, 109, 110, 111,
    112, 113, 114, 115, 116, 117, 118, 119,
    120, 121, 122, 123, 124, 125, 126, 127,
    128, 129, 130, 131, 132, 133, 134, 135,
    136, 137, 138, 139, 140, 141, 142, 143,
    144, 145, 146, 147, 148, 149, 150, 151,
    152, 153, 154, 155, 156, 157, 158, 159,
    160, 161, 162, 163, 164, 165, 166, 167,
    168, 169, 170, 171, 172, 173, 174, 175,
    176, 177, 178, 179, 180, 181, 182, 183,
    184, 185, 186, 187, 188, 189, 190, 191,
    192, 193, 194, 195, 196, 197, 198, 199,
    200, 201, 202, 203, 204, 205, 206, 207,
    208, 209, 210, 211, 212, 213, 214, 215,
    216, 217, 218, 219, 220, 221, 222, 223,
    224, 225, 226, 227, 228
  };

  static const FT_UShort  cff_expert_charset[166] =
  {
      0,   1, 229, 230, 231, 232, 233, 234,
    235, 236, 237, 238,  13,  14,  15,  99,
    239, 240, 241, 242, 243, 244, 245, 246,
    247, 248,  27,  28, 249, 250, 251, 252,
    253, 254, 255, 256, 257, 258, 259, 260,
    261, 262, 263, 264, 265, 266, 109, 110,
    267, 268, 269, 270, 271, 272, 273, 274,
    275, 276, 277, 278, 279, 280, 281, 282,
    283, 284, 285, 286, 287, 288, 289, 290,
    291, 292, 293, 294, 295, 296, 297, 298,
    299, 300, 301, 302, 303, 304, 305, 306,
    307, 308, 309, 310, 311, 312, 313, 314,
    315, 316, 317, 318, 158, 155, 163, 319,
    320, 321, 322, 323, 324, 325, 326, 150,
    164, 169, 327, 328, 329, 330, 331, 332,
    333, 334, 335, 336, 337, 338, 339, 340,
    341, 342, 343, 344, 345, 346, 347, 348,
    349, 350, 351, 352, 353, 354, 355, 356,
    357, 358, 359, 360, 361, 362, 363, 364,
    365, 366, 367, 368, 369, 370, 371, 372,
    373, 374, 375, 376, 377, 378
  };

  static const FT_UShort  cff_expertsubset_charset[87] =
  {
      0,   1, 231, 232, 235, 236, 237, 238,
     13,  14,  15,  99, 239, 240, 241, 242,
    243, 244, 245, 246, 247, 248,  27,  28,
    249, 250, 251, 253, 254, 255, 256, 257,
    258, 259, 260, 261, 262, 263, 264, 265,
    266, 109, 110, 267, 268, 269, 270, 272,
    300, 301, 302, 305, 314, 315, 158, 155,
    163, 320, 321, 322, 323, 324, 325, 326,
    150, 164, 169, 327, 328, 329, 330, 331,
    332, 333, 334, 335, 336, 337, 338, 339,
    340, 341, 342, 343, 344, 345, 346
  };

  static const FT_UShort  cff_standard_encoding[256] =
  {
      0,   0,   0,   0,   0,   0,   0,   0,
      0,   0,   0,   0,   0,   0,   0,   0,
      0,   0,   0,   0,   0,   0,   0,   0,
      0,   0,   0,   0,   0,   0,   0,   0,
      1,   2,   3,   4,   5,   6,   7,   8,
      9,  10,  11,  12,  13,  14,  15,  16,
     17,  18,  19,  20,  21,  22,  23,  24,
     25,  26,  27,  28,  29,  30,  31,  32,
     33,  34,  35,  36,  37,  38,  39,  40,
     41,  42,  43,  44,  45,  46,  47,  48,
     49,  50,  51,  52,  53,  54,  55,  56,
     57,  58,  59,  60,  61,  62,  63,  64,
     65,  66,  67,  68,  69,  70,  71,  72,
     73,  74,  75,  76,  77,  78,  79,  80,
     81,  82,  83,  84,  85,  86,  87,  88,
     89,  90,  91,  92,  93,  94,  95,   0,
      0,   0,   0,   0,   0,   0,   0,   0,
      0,   0,   0,   0,   0,   0,   0,   0,
      0,   0,   0,   0,   0,   0,   0,   0,
      0,   0,   0,   0,   0,   0,   0,   0,
      0,  96,  97,  98,  99, 100, 101, 102,
    103, 104, 105, 106, 107, 108, 109, 110,
      0, 111, 112, 113, 114,   0, 115, 116,
    117, 118, 119, 120, 121, 122,   0, 123,
      0, 124, 125, 126, 127, 128, 129, 130,
    131,   0, 132, 133,   0, 134, 135, 136,
    137,   0,   0,   0,   0,   0,   0,   0,
      0,   0,   0,   0,   0,   0,   0,   0,
      0, 138,   0, 139,   0,   0,   0,   0,
    140, 141, 142, 143,   0,   0,   0,   0,
      0, 144,   0,   0,   0, 145,   0,   0,
    146, 147, 148, 149,   0,   0,   0,   0
  };

  static const FT_UShort  cff_expert_encoding[256] =
  {
      0,   0,   0,   0,   0,   0,   0,   0,
      0,   0,   0,   0,   0,   0,   0,   0,
      0,   0,   0,   0,   0,   0,   0,   0,
      0,   0,   0,   0,   0,   0,   0,   0,
      1, 229, 230,   0, 231, 232, 233, 234,
    235, 236, 237, 238,  13,  14,  15,  99,
    239, 240, 241, 242, 243, 244, 245, 246,
    247, 248,  27,  28, 249, 250, 251, 252,
      0, 253, 254, 255, 256, 257,   0,   0,
      0, 258,   0,   0, 259, 260, 261, 262,
      0,   0, 263, 264, 265,   0, 266, 109,
    110, 267, 268, 269,   0, 270, 271, 272,
    273, 274, 275, 276, 277, 278, 279, 280,
    281, 282, 283, 284, 285, 286, 287, 288,
    289, 290, 291, 292, 293, 294, 295, 296,
    297, 298, 299, 300, 301, 302, 303,   0,
      0,   0,   0,   0,   0,   0,   0,   0,
      0,   0,   0,   0,   0,   0,   0,   0,
      0,   0,   0,   0,   0,   0,   0,   0,
      0,   0,   0,   0,   0,   0,   0,   0,
      0, 304, 305, 306,   0,   0, 307, 308,
    309, 310, 311,   0, 312,   0,   0, 312,
      0,   0, 314, 315,   0,   0, 316, 317,
    318,   0,   0,   0, 158, 155, 163, 319,
    320, 321, 322, 323, 324, 325,   0,   0,
    326, 150, 164, 169, 327, 328, 329, 330,
    331, 332, 333, 334, 335, 336, 337, 338,
    339, 340, 341, 342, 343, 344, 345, 346,
    347, 348, 349, 350, 351, 352, 353, 354,
    355, 356, 357, 358, 359, 360, 361, 362,
    363, 364, 365, 366, 367, 368, 369, 370,
    371, 372, 373, 374, 375, 376, 377, 378
  };

#endif /* 1 */


  FT_LOCAL_DEF( FT_UShort )
  cff_get_standard_encoding( FT_UInt  charcode )
  {
    return (FT_UShort)( charcode < 256 ? cff_standard_encoding[charcode]
                                       : 0 );
  }


  /**************************************************************************
   *
   * The macro FT_COMPONENT is used in trace mode.  It is an implicit
   * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log
   * messages during execution.
   */
#undef  FT_COMPONENT
#define FT_COMPONENT  cffload


  /* read an offset from the index's stream current position */
  static FT_ULong
  cff_index_read_offset( CFF_Index  idx,
                         FT_Error  *errorp )
  {
    FT_Error   error;
    FT_Stream  stream = idx->stream;
    FT_Byte    tmp[4];
    FT_ULong   result = 0;


    if ( !FT_STREAM_READ( tmp, idx->off_size ) )
    {
      FT_Int  nn;


      for ( nn = 0; nn < idx->off_size; nn++ )
        result = ( result << 8 ) | tmp[nn];
    }

    *errorp = error;
    return result;
  }


  static FT_Error
  cff_index_init( CFF_Index  idx,
                  FT_Stream  stream,
                  FT_Bool    load,
                  FT_Bool    cff2 )
  {
    FT_Error   error;
    FT_Memory  memory = stream->memory;
    FT_UInt    count;


    FT_ZERO( idx );

    idx->stream = stream;
    idx->start  = FT_STREAM_POS();

    if ( cff2 )
    {
      if ( FT_READ_ULONG( count ) )
        goto Exit;
      idx->hdr_size = 5;
    }
    else
    {
      if ( FT_READ_USHORT( count ) )
        goto Exit;
      idx->hdr_size = 3;
    }

    if ( count > 0 )
    {
      FT_Byte   offsize;
      FT_ULong  size;


      /* there is at least one element; read the offset size,           */
      /* then access the offset table to compute the index's total size */
      if ( FT_READ_BYTE( offsize ) )
        goto Exit;

      if ( offsize < 1 || offsize > 4 )
      {
        error = FT_THROW( Invalid_Table );
        goto Exit;
      }

      idx->count    = count;
      idx->off_size = offsize;
      size          = (FT_ULong)( count + 1 ) * offsize;

      idx->data_offset = idx->start + idx->hdr_size + size;

      if ( FT_STREAM_SKIP( size - offsize ) )
        goto Exit;

      size = cff_index_read_offset( idx, &error );
      if ( error )
        goto Exit;

      if ( size == 0 )
      {
        error = FT_THROW( Invalid_Table );
        goto Exit;
      }

      idx->data_size = --size;

      if ( load )
      {
        /* load the data */
        if ( FT_FRAME_EXTRACT( size, idx->bytes ) )
          goto Exit;
      }
      else
      {
        /* skip the data */
        if ( FT_STREAM_SKIP( size ) )
          goto Exit;
      }
    }

  Exit:
    if ( error )
      FT_FREE( idx->offsets );

    return error;
  }


  static void
  cff_index_done( CFF_Index  idx )
  {
    if ( idx->stream )
    {
      FT_Stream  stream = idx->stream;
      FT_Memory  memory = stream->memory;


      if ( idx->bytes )
        FT_FRAME_RELEASE( idx->bytes );

      FT_FREE( idx->offsets );
      FT_ZERO( idx );
    }
  }


  static FT_Error
  cff_index_load_offsets( CFF_Index  idx )
  {
    FT_Error   error  = FT_Err_Ok;
    FT_Stream  stream = idx->stream;
    FT_Memory  memory = stream->memory;


    if ( idx->count > 0 && !idx->offsets )
    {
      FT_Byte    offsize = idx->off_size;
      FT_ULong   data_size;
      FT_Byte*   p;
      FT_Byte*   p_end;
      FT_ULong*  poff;


      data_size = (FT_ULong)( idx->count + 1 ) * offsize;

      if ( FT_NEW_ARRAY( idx->offsets, idx->count + 1 ) ||
           FT_STREAM_SEEK( idx->start + idx->hdr_size ) ||
           FT_FRAME_ENTER( data_size )                  )
        goto Exit;

      poff   = idx->offsets;
      p      = (FT_Byte*)stream->cursor;
      p_end  = p + data_size;

      switch ( offsize )
      {
      case 1:
        for ( ; p < p_end; p++, poff++ )
          poff[0] = p[0];
        break;

      case 2:
        for ( ; p < p_end; p += 2, poff++ )
          poff[0] = FT_PEEK_USHORT( p );
        break;

      case 3:
        for ( ; p < p_end; p += 3, poff++ )
          poff[0] = FT_PEEK_UOFF3( p );
        break;

      default:
        for ( ; p < p_end; p += 4, poff++ )
          poff[0] = FT_PEEK_ULONG( p );
      }

      FT_FRAME_EXIT();
    }

  Exit:
    if ( error )
      FT_FREE( idx->offsets );

    return error;
  }


  /* Allocate a table containing pointers to an index's elements. */
  /* The `pool' argument makes this function convert the index    */
  /* entries to C-style strings (this is, NULL-terminated).       */
  static FT_Error
  cff_index_get_pointers( CFF_Index   idx,
                          FT_Byte***  table,
                          FT_Byte**   pool,
                          FT_ULong*   pool_size )
  {
    FT_Error   error     = FT_Err_Ok;
    FT_Memory  memory    = idx->stream->memory;

    FT_Byte**  t         = NULL;
    FT_Byte*   new_bytes = NULL;
    FT_ULong   new_size;


    *table = NULL;

    if ( !idx->offsets )
    {
      error = cff_index_load_offsets( idx );
      if ( error )
        goto Exit;
    }

    new_size = idx->data_size + idx->count;

    if ( idx->count > 0                                &&
         !FT_NEW_ARRAY( t, idx->count + 1 )            &&
         ( !pool || !FT_ALLOC( new_bytes, new_size ) ) )
    {
      FT_ULong  n, cur_offset;
      FT_ULong  extra = 0;
      FT_Byte*  org_bytes = idx->bytes;


      /* at this point, `idx->offsets' can't be NULL */
      cur_offset = idx->offsets[0] - 1;

      /* sanity check */
      if ( cur_offset != 0 )
      {
        FT_TRACE0(( "cff_index_get_pointers:"
                    " invalid first offset value %d set to zero\n",
                    cur_offset ));
        cur_offset = 0;
      }

      if ( !pool )
        t[0] = org_bytes + cur_offset;
      else
        t[0] = new_bytes + cur_offset;

      for ( n = 1; n <= idx->count; n++ )
      {
        FT_ULong  next_offset = idx->offsets[n] - 1;


        /* two sanity checks for invalid offset tables */
        if ( next_offset < cur_offset )
          next_offset = cur_offset;
        else if ( next_offset > idx->data_size )
          next_offset = idx->data_size;

        if ( !pool )
          t[n] = org_bytes + next_offset;
        else
        {
          t[n] = new_bytes + next_offset + extra;

          if ( next_offset != cur_offset )
          {
            FT_MEM_COPY( t[n - 1], org_bytes + cur_offset, t[n] - t[n - 1] );
            t[n][0] = '\0';
            t[n]   += 1;
            extra++;
          }
        }

        cur_offset = next_offset;
      }
      *table = t;

      if ( pool )
        *pool = new_bytes;
      if ( pool_size )
        *pool_size = new_size;
    }

  Exit:
    return error;
  }


  FT_LOCAL_DEF( FT_Error )
  cff_index_access_element( CFF_Index  idx,
                            FT_UInt    element,
                            FT_Byte**  pbytes,
                            FT_ULong*  pbyte_len )
  {
    FT_Error  error = FT_Err_Ok;


    if ( idx && idx->count > element )
    {
      /* compute start and end offsets */
      FT_Stream  stream = idx->stream;
      FT_ULong   off1, off2 = 0;


      /* load offsets from file or the offset table */
      if ( !idx->offsets )
      {
        FT_ULong  pos = element * idx->off_size;


        if ( FT_STREAM_SEEK( idx->start + idx->hdr_size + pos ) )
          goto Exit;

        off1 = cff_index_read_offset( idx, &error );
        if ( error )
          goto Exit;

        if ( off1 != 0 )
        {
          do
          {
            element++;
            off2 = cff_index_read_offset( idx, &error );

          } while ( off2 == 0 && element < idx->count );
        }
      }
      else   /* use offsets table */
      {
        off1 = idx->offsets[element];
        if ( off1 )
        {
          do
          {
            element++;
            off2 = idx->offsets[element];

          } while ( off2 == 0 && element < idx->count );
        }
      }

      /* XXX: should check off2 does not exceed the end of this entry; */
      /*      at present, only truncate off2 at the end of this stream */
      if ( off2 > stream->size + 1                    ||
           idx->data_offset > stream->size - off2 + 1 )
      {
        FT_ERROR(( "cff_index_access_element:"
                   " offset to next entry (%d)"
                   " exceeds the end of stream (%d)\n",
                   off2, stream->size - idx->data_offset + 1 ));
        off2 = stream->size - idx->data_offset + 1;
      }

      /* access element */
      if ( off1 && off2 > off1 )
      {
        *pbyte_len = off2 - off1;

        if ( idx->bytes )
        {
          /* this index was completely loaded in memory, that's easy */
          *pbytes = idx->bytes + off1 - 1;
        }
        else
        {
          /* this index is still on disk/file, access it through a frame */
          if ( FT_STREAM_SEEK( idx->data_offset + off1 - 1 ) ||
               FT_FRAME_EXTRACT( off2 - off1, *pbytes )      )
            goto Exit;
        }
      }
      else
      {
        /* empty index element */
        *pbytes    = 0;
        *pbyte_len = 0;
      }
    }
    else
      error = FT_THROW( Invalid_Argument );

  Exit:
    return error;
  }


  FT_LOCAL_DEF( void )
  cff_index_forget_element( CFF_Index  idx,
                            FT_Byte**  pbytes )
  {
    if ( idx->bytes == 0 )
    {
      FT_Stream  stream = idx->stream;


      FT_FRAME_RELEASE( *pbytes );
    }
  }


  /* get an entry from Name INDEX */
  FT_LOCAL_DEF( FT_String* )
  cff_index_get_name( CFF_Font  font,
                      FT_UInt   element )
  {
    CFF_Index   idx = &font->name_index;
    FT_Memory   memory;
    FT_Byte*    bytes;
    FT_ULong    byte_len;
    FT_Error    error;
    FT_String*  name = 0;


    if ( !idx->stream )  /* CFF2 does not include a name index */
      goto Exit;

    memory = idx->stream->memory;

    error = cff_index_access_element( idx, element, &bytes, &byte_len );
    if ( error )
      goto Exit;

    if ( !FT_ALLOC( name, byte_len + 1 ) )
    {
      if ( byte_len )
        FT_MEM_COPY( name, bytes, byte_len );
      name[byte_len] = 0;
    }
    cff_index_forget_element( idx, &bytes );

  Exit:
    return name;
  }


  /* get an entry from String INDEX */
  FT_LOCAL_DEF( FT_String* )
  cff_index_get_string( CFF_Font  font,
                        FT_UInt   element )
  {
    return ( element < font->num_strings )
             ? (FT_String*)font->strings[element]
             : NULL;
  }


  FT_LOCAL_DEF( FT_String* )
  cff_index_get_sid_string( CFF_Font  font,
                            FT_UInt   sid )
  {
    /* value 0xFFFFU indicates a missing dictionary entry */
    if ( sid == 0xFFFFU )
      return NULL;

    /* if it is not a standard string, return it */
    if ( sid > 390 )
      return cff_index_get_string( font, sid - 391 );

    /* CID-keyed CFF fonts don't have glyph names */
    if ( !font->psnames )
      return NULL;

    /* this is a standard string */
    return (FT_String *)font->psnames->adobe_std_strings( sid );
  }


  /*************************************************************************/
  /*************************************************************************/
  /***                                                                   ***/
  /***   FD Select table support                                         ***/
  /***                                                                   ***/
  /*************************************************************************/
  /*************************************************************************/


  static void
  CFF_Done_FD_Select( CFF_FDSelect  fdselect,
                      FT_Stream     stream )
  {
    if ( fdselect->data )
      FT_FRAME_RELEASE( fdselect->data );

    fdselect->data_size   = 0;
    fdselect->format      = 0;
    fdselect->range_count = 0;
  }


  static FT_Error
  CFF_Load_FD_Select( CFF_FDSelect  fdselect,
                      FT_UInt       num_glyphs,
                      FT_Stream     stream,
                      FT_ULong      offset )
  {
    FT_Error  error;
    FT_Byte   format;
    FT_UInt   num_ranges;


    /* read format */
    if ( FT_STREAM_SEEK( offset ) || FT_READ_BYTE( format ) )
      goto Exit;

    fdselect->format      = format;
    fdselect->cache_count = 0;   /* clear cache */

    switch ( format )
    {
    case 0:     /* format 0, that's simple */
      fdselect->data_size = num_glyphs;
      goto Load_Data;

    case 3:     /* format 3, a tad more complex */
      if ( FT_READ_USHORT( num_ranges ) )
        goto Exit;

      if ( !num_ranges )
      {
        FT_TRACE0(( "CFF_Load_FD_Select: empty FDSelect array\n" ));
        error = FT_THROW( Invalid_File_Format );
        goto Exit;
      }

      fdselect->data_size = num_ranges * 3 + 2;

    Load_Data:
      if ( FT_FRAME_EXTRACT( fdselect->data_size, fdselect->data ) )
        goto Exit;
      break;

    default:    /* hmm... that's wrong */
      error = FT_THROW( Invalid_File_Format );
    }

  Exit:
    return error;
  }


  FT_LOCAL_DEF( FT_Byte )
  cff_fd_select_get( CFF_FDSelect  fdselect,
                     FT_UInt       glyph_index )
  {
    FT_Byte  fd = 0;


    /* if there is no FDSelect, return zero               */
    /* Note: CFF2 with just one Font Dict has no FDSelect */
    if ( !fdselect->data )
      goto Exit;

    switch ( fdselect->format )
    {
    case 0:
      fd = fdselect->data[glyph_index];
      break;

    case 3:
      /* first, compare to the cache */
      if ( (FT_UInt)( glyph_index - fdselect->cache_first ) <
                        fdselect->cache_count )
      {
        fd = fdselect->cache_fd;
        break;
      }

      /* then, look up the ranges array */
      {
        FT_Byte*  p       = fdselect->data;
        FT_Byte*  p_limit = p + fdselect->data_size;
        FT_Byte   fd2;
        FT_UInt   first, limit;


        first = FT_NEXT_USHORT( p );
        do
        {
          if ( glyph_index < first )
            break;

          fd2   = *p++;
          limit = FT_NEXT_USHORT( p );

          if ( glyph_index < limit )
          {
            fd = fd2;

            /* update cache */
            fdselect->cache_first = first;
            fdselect->cache_count = limit - first;
            fdselect->cache_fd    = fd2;
            break;
          }
          first = limit;

        } while ( p < p_limit );
      }
      break;

    default:
      ;
    }

  Exit:
    return fd;
  }


  /*************************************************************************/
  /*************************************************************************/
  /***                                                                   ***/
  /***   CFF font support                                                ***/
  /***                                                                   ***/
  /*************************************************************************/
  /*************************************************************************/

  static FT_Error
  cff_charset_compute_cids( CFF_Charset  charset,
                            FT_UInt      num_glyphs,
                            FT_Memory    memory )
  {
    FT_Error   error   = FT_Err_Ok;
    FT_UInt    i;
    FT_Long    j;
    FT_UShort  max_cid = 0;


    if ( charset->max_cid > 0 )
      goto Exit;

    for ( i = 0; i < num_glyphs; i++ )
    {
      if ( charset->sids[i] > max_cid )
        max_cid = charset->sids[i];
    }

    if ( FT_NEW_ARRAY( charset->cids, (FT_ULong)max_cid + 1 ) )
      goto Exit;

    /* When multiple GIDs map to the same CID, we choose the lowest */
    /* GID.  This is not described in any spec, but it matches the  */
    /* behaviour of recent Acroread versions.                       */
    for ( j = (FT_Long)num_glyphs - 1; j >= 0; j-- )
      charset->cids[charset->sids[j]] = (FT_UShort)j;

    charset->max_cid    = max_cid;
    charset->num_glyphs = num_glyphs;

  Exit:
    return error;
  }


  FT_LOCAL_DEF( FT_UInt )
  cff_charset_cid_to_gindex( CFF_Charset  charset,
                             FT_UInt      cid )
  {
    FT_UInt  result = 0;


    if ( cid <= charset->max_cid )
      result = charset->cids[cid];

    return result;
  }


  static void
  cff_charset_free_cids( CFF_Charset  charset,
                         FT_Memory    memory )
  {
    FT_FREE( charset->cids );
    charset->max_cid = 0;
  }


  static void
  cff_charset_done( CFF_Charset  charset,
                    FT_Stream    stream )
  {
    FT_Memory  memory = stream->memory;


    cff_charset_free_cids( charset, memory );

    FT_FREE( charset->sids );
    charset->format = 0;
    charset->offset = 0;
  }


  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 )
  {
    FT_Memory  memory = stream->memory;
    FT_Error   error  = FT_Err_Ok;
    FT_UShort  glyph_sid;


    /* If the offset is greater than 2, we have to parse the charset */
    /* table.                                                        */
    if ( offset > 2 )
    {
      FT_UInt  j;


      charset->offset = base_offset + offset;

      /* Get the format of the table. */
      if ( FT_STREAM_SEEK( charset->offset ) ||
           FT_READ_BYTE( charset->format )   )
        goto Exit;

      /* Allocate memory for sids. */
      if ( FT_NEW_ARRAY( charset->sids, num_glyphs ) )
        goto Exit;

      /* assign the .notdef glyph */
      charset->sids[0] = 0;

      switch ( charset->format )
      {
      case 0:
        if ( num_glyphs > 0 )
        {
          if ( FT_FRAME_ENTER( ( num_glyphs - 1 ) * 2 ) )
            goto Exit;

          for ( j = 1; j < num_glyphs; j++ )
            charset->sids[j] = FT_GET_USHORT();

          FT_FRAME_EXIT();
        }
        break;

      case 1:
      case 2:
        {
          FT_UInt  nleft;
          FT_UInt  i;


          j = 1;

          while ( j < num_glyphs )
          {
            /* Read the first glyph sid of the range. */
            if ( FT_READ_USHORT( glyph_sid ) )
              goto Exit;

            /* Read the number of glyphs in the range.  */
            if ( charset->format == 2 )
            {
              if ( FT_READ_USHORT( nleft ) )
                goto Exit;
            }
            else
            {
              if ( FT_READ_BYTE( nleft ) )
                goto Exit;
            }

            /* try to rescue some of the SIDs if `nleft' is too large */
            if ( glyph_sid > 0xFFFFL - nleft )
            {
              FT_ERROR(( "cff_charset_load: invalid SID range trimmed"
                         " nleft=%d -> %d\n", nleft, 0xFFFFL - glyph_sid ));
              nleft = ( FT_UInt )( 0xFFFFL - glyph_sid );
            }

            /* Fill in the range of sids -- `nleft + 1' glyphs. */
            for ( i = 0; j < num_glyphs && i <= nleft; i++, j++, glyph_sid++ )
              charset->sids[j] = glyph_sid;
          }
        }
        break;

      default:
        FT_ERROR(( "cff_charset_load: invalid table format\n" ));
        error = FT_THROW( Invalid_File_Format );
        goto Exit;
      }
    }
    else
    {
      /* Parse default tables corresponding to offset == 0, 1, or 2.  */
      /* CFF specification intimates the following:                   */
      /*                                                              */
      /* In order to use a predefined charset, the following must be  */
      /* true: The charset constructed for the glyphs in the font's   */
      /* charstrings dictionary must match the predefined charset in  */
      /* the first num_glyphs.                                        */

      charset->offset = offset;  /* record charset type */

      switch ( (FT_UInt)offset )
      {
      case 0:
        if ( num_glyphs > 229 )
        {
          FT_ERROR(( "cff_charset_load: implicit charset larger than\n"
                     "predefined charset (Adobe ISO-Latin)\n" ));
          error = FT_THROW( Invalid_File_Format );
          goto Exit;
        }

        /* Allocate memory for sids. */
        if ( FT_NEW_ARRAY( charset->sids, num_glyphs ) )
          goto Exit;

        /* Copy the predefined charset into the allocated memory. */
        FT_ARRAY_COPY( charset->sids, cff_isoadobe_charset, num_glyphs );

        break;

      case 1:
        if ( num_glyphs > 166 )
        {
          FT_ERROR(( "cff_charset_load: implicit charset larger than\n"
                     "predefined charset (Adobe Expert)\n" ));
          error = FT_THROW( Invalid_File_Format );
          goto Exit;
        }

        /* Allocate memory for sids. */
        if ( FT_NEW_ARRAY( charset->sids, num_glyphs ) )
          goto Exit;

        /* Copy the predefined charset into the allocated memory.     */
        FT_ARRAY_COPY( charset->sids, cff_expert_charset, num_glyphs );

        break;

      case 2:
        if ( num_glyphs > 87 )
        {
          FT_ERROR(( "cff_charset_load: implicit charset larger than\n"
                     "predefined charset (Adobe Expert Subset)\n" ));
          error = FT_THROW( Invalid_File_Format );
          goto Exit;
        }

        /* Allocate memory for sids. */
        if ( FT_NEW_ARRAY( charset->sids, num_glyphs ) )
          goto Exit;

        /* Copy the predefined charset into the allocated memory.     */
        FT_ARRAY_COPY( charset->sids, cff_expertsubset_charset, num_glyphs );

        break;

      default:
        error = FT_THROW( Invalid_File_Format );
        goto Exit;
      }
    }

    /* we have to invert the `sids' array for subsetted CID-keyed fonts */
    if ( invert )
      error = cff_charset_compute_cids( charset, num_glyphs, memory );

  Exit:
    /* Clean up if there was an error. */
    if ( error )
    {
      FT_FREE( charset->sids );
      FT_FREE( charset->cids );
      charset->format = 0;
      charset->offset = 0;
      charset->sids   = 0;
    }

    return error;
  }


  static void
  cff_vstore_done( CFF_VStoreRec*  vstore,
                   FT_Memory       memory )
  {
    FT_UInt  i;


    /* free regionList and axisLists */
    if ( vstore->varRegionList )
    {
      for ( i = 0; i < vstore->regionCount; i++ )
        FT_FREE( vstore->varRegionList[i].axisList );
    }
    FT_FREE( vstore->varRegionList );

    /* free varData and indices */
    if ( vstore->varData )
    {
      for ( i = 0; i < vstore->dataCount; i++ )
        FT_FREE( vstore->varData[i].regionIndices );
    }
    FT_FREE( vstore->varData );
  }


  /* convert 2.14 to Fixed */
  #define FT_fdot14ToFixed( x )  ( (FT_Fixed)( (FT_ULong)(x) << 2 ) )


  static FT_Error
  cff_vstore_load( CFF_VStoreRec*  vstore,
                   FT_Stream       stream,
                   FT_ULong        base_offset,
                   FT_ULong        offset )
  {
    FT_Memory  memory = stream->memory;
    FT_Error   error  = FT_ERR( Invalid_File_Format );

    FT_ULong*  dataOffsetArray = NULL;
    FT_UInt    i, j;


    /* no offset means no vstore to parse */
    if ( offset )
    {
      FT_UInt   vsOffset;
      FT_UInt   format;
      FT_ULong  regionListOffset;


      /* we need to parse the table to determine its size; */
      /* skip table length                                 */
      if ( FT_STREAM_SEEK( base_offset + offset ) ||
           FT_STREAM_SKIP( 2 )                    )
        goto Exit;

      /* actual variation store begins after the length */
      vsOffset = FT_STREAM_POS();

      /* check the header */
      if ( FT_READ_USHORT( format ) )
        goto Exit;
      if ( format != 1 )
      {
        error = FT_THROW( Invalid_File_Format );
        goto Exit;
      }

      /* read top level fields */
      if ( FT_READ_ULONG( regionListOffset )   ||
           FT_READ_USHORT( vstore->dataCount ) )
        goto Exit;

      /* make temporary copy of item variation data offsets; */
      /* we'll parse region list first, then come back       */
      if ( FT_NEW_ARRAY( dataOffsetArray, vstore->dataCount ) )
        goto Exit;

      for ( i = 0; i < vstore->dataCount; i++ )
      {
        if ( FT_READ_ULONG( dataOffsetArray[i] ) )
          goto Exit;
      }

      /* parse regionList and axisLists */
      if ( FT_STREAM_SEEK( vsOffset + regionListOffset ) ||
           FT_READ_USHORT( vstore->axisCount )           ||
           FT_READ_USHORT( vstore->regionCount )         )
        goto Exit;

      if ( FT_NEW_ARRAY( vstore->varRegionList, vstore->regionCount ) )
        goto Exit;

      for ( i = 0; i < vstore->regionCount; i++ )
      {
        CFF_VarRegion*  region = &vstore->varRegionList[i];


        if ( FT_NEW_ARRAY( region->axisList, vstore->axisCount ) )
          goto Exit;

        for ( j = 0; j < vstore->axisCount; j++ )
        {
          CFF_AxisCoords*  axis = &region->axisList[j];

          FT_Int16  start14, peak14, end14;


          if ( FT_READ_SHORT( start14 ) ||
               FT_READ_SHORT( peak14 )  ||
               FT_READ_SHORT( end14 )   )
            goto Exit;

          axis->startCoord = FT_fdot14ToFixed( start14 );
          axis->peakCoord  = FT_fdot14ToFixed( peak14 );
          axis->endCoord   = FT_fdot14ToFixed( end14 );
        }
      }

      /* use dataOffsetArray now to parse varData items */
      if ( FT_NEW_ARRAY( vstore->varData, vstore->dataCount ) )
        goto Exit;

      for ( i = 0; i < vstore->dataCount; i++ )
      {
        CFF_VarData*  data = &vstore->varData[i];


        if ( FT_STREAM_SEEK( vsOffset + dataOffsetArray[i] ) )
          goto Exit;

        /* ignore `itemCount' and `shortDeltaCount' */
        /* because CFF2 has no delta sets           */
        if ( FT_STREAM_SKIP( 4 ) )
          goto Exit;

        /* Note: just record values; consistency is checked later    */
        /*       by cff_blend_build_vector when it consumes `vstore' */

        if ( FT_READ_USHORT( data->regionIdxCount ) )
          goto Exit;

        if ( FT_NEW_ARRAY( data->regionIndices, data->regionIdxCount ) )
          goto Exit;

        for ( j = 0; j < data->regionIdxCount; j++ )
        {
          if ( FT_READ_USHORT( data->regionIndices[j] ) )
            goto Exit;
        }
      }
    }

    error = FT_Err_Ok;

  Exit:
    FT_FREE( dataOffsetArray );
    if ( error )
      cff_vstore_done( vstore, memory );

    return error;
  }


  /* Clear blend stack (after blend values are consumed). */
  /*                                                      */
  /* TODO: Should do this in cff_run_parse, but subFont   */
  /*       ref is not available there.                    */
  /*                                                      */
  /* Allocation is not changed when stack is cleared.     */
  FT_LOCAL_DEF( void )
  cff_blend_clear( CFF_SubFont  subFont )
  {
    subFont->blend_top  = subFont->blend_stack;
    subFont->blend_used = 0;
  }


  /* Blend numOperands on the stack,                       */
  /* store results into the first numBlends values,        */
  /* then pop remaining arguments.                         */
  /*                                                       */
  /* This is comparable to `cf2_doBlend' but               */
  /* the cffparse stack is different and can't be written. */
  /* Blended values are written to a different buffer,     */
  /* using reserved operator 255.                          */
  /*                                                       */
  /* Blend calculation is done in 16.16 fixed point.       */
  FT_LOCAL_DEF( FT_Error )
  cff_blend_doBlend( CFF_SubFont  subFont,
                     CFF_Parser   parser,
                     FT_UInt      numBlends )
  {
    FT_UInt  delta;
    FT_UInt  base;
    FT_UInt  i, j;
    FT_UInt  size;

    CFF_Blend  blend = &subFont->blend;

    FT_Memory  memory = subFont->blend.font->memory; /* for FT_REALLOC */
    FT_Error   error  = FT_Err_Ok;                   /* for FT_REALLOC */

    /* compute expected number of operands for this blend */
    FT_UInt  numOperands = (FT_UInt)( numBlends * blend->lenBV );
    FT_UInt  count       = (FT_UInt)( parser->top - 1 - parser->stack );


    if ( numOperands > count )
    {
      FT_TRACE4(( " cff_blend_doBlend: Stack underflow %d argument%s\n",
                  count,
                  count == 1 ? "" : "s" ));

      error = FT_THROW( Stack_Underflow );
      goto Exit;
    }

    /* check whether we have room for `numBlends' values at `blend_top' */
    size = 5 * numBlends;           /* add 5 bytes per entry    */
    if ( subFont->blend_used + size > subFont->blend_alloc )
    {
      FT_Byte*  blend_stack_old = subFont->blend_stack;
      FT_Byte*  blend_top_old   = subFont->blend_top;


      /* increase or allocate `blend_stack' and reset `blend_top'; */
      /* prepare to append `numBlends' values to the buffer        */
      if ( FT_REALLOC( subFont->blend_stack,
                       subFont->blend_alloc,
                       subFont->blend_alloc + size ) )
        goto Exit;

      subFont->blend_top    = subFont->blend_stack + subFont->blend_used;
      subFont->blend_alloc += size;

      /* iterate over the parser stack and adjust pointers */
      /* if the reallocated buffer has a different address */
      if ( blend_stack_old                         &&
           subFont->blend_stack != blend_stack_old )
      {
        FT_PtrDist  offset = subFont->blend_stack - blend_stack_old;
        FT_Byte**   p;


        for ( p = parser->stack; p < parser->top; p++ )
        {
          if ( *p >= blend_stack_old && *p < blend_top_old )
            *p += offset;
        }
      }
    }
    subFont->blend_used += size;

    base  = count - numOperands;     /* index of first blend arg */
    delta = base + numBlends;        /* index of first delta arg */

    for ( i = 0; i < numBlends; i++ )
    {
      const FT_Int32*  weight = &blend->BV[1];
      FT_UInt32        sum;


      /* convert inputs to 16.16 fixed point */
      sum = cff_parse_num( parser, &parser->stack[i + base] ) * 0x10000;

      for ( j = 1; j < blend->lenBV; j++ )
        sum += cff_parse_num( parser, &parser->stack[delta++] ) * *weight++;

      /* point parser stack to new value on blend_stack */
      parser->stack[i + base] = subFont->blend_top;

      /* Push blended result as Type 2 5-byte fixed point number.  This */
      /* will not conflict with actual DICTs because 255 is a reserved  */
      /* opcode in both CFF and CFF2 DICTs.  See `cff_parse_num' for    */
      /* decode of this, which rounds to an integer.                    */
      *subFont->blend_top++ = 255;
      *subFont->blend_top++ = (FT_Byte)( sum >> 24 );
      *subFont->blend_top++ = (FT_Byte)( sum >> 16 );
      *subFont->blend_top++ = (FT_Byte)( sum >>  8 );
      *subFont->blend_top++ = (FT_Byte)sum;
    }

    /* leave only numBlends results on parser stack */
    parser->top = &parser->stack[base + numBlends];

  Exit:
    return error;
  }


  /* Compute a blend vector from variation store index and normalized  */
  /* vector based on pseudo-code in OpenType Font Variations Overview. */
  /*                                                                   */
  /* Note: lenNDV == 0 produces a default blend vector, (1,0,0,...).   */
  FT_LOCAL_DEF( FT_Error )
  cff_blend_build_vector( CFF_Blend  blend,
                          FT_UInt    vsindex,
                          FT_UInt    lenNDV,
                          FT_Fixed*  NDV )
  {
    FT_Error   error  = FT_Err_Ok;            /* for FT_REALLOC */
    FT_Memory  memory = blend->font->memory;  /* for FT_REALLOC */

    FT_UInt       len;
    CFF_VStore    vs;
    CFF_VarData*  varData;
    FT_UInt       master;


    /* protect against malformed fonts */
    if ( !( lenNDV == 0 || NDV ) )
    {
      FT_TRACE4(( " cff_blend_build_vector:"
                  " Malformed Normalize Design Vector data\n" ));
      error = FT_THROW( Invalid_File_Format );
      goto Exit;
    }

    blend->builtBV = FALSE;

    vs = &blend->font->vstore;

    /* VStore and fvar must be consistent */
    if ( lenNDV != 0 && lenNDV != vs->axisCount )
    {
      FT_TRACE4(( " cff_blend_build_vector: Axis count mismatch\n" ));
      error = FT_THROW( Invalid_File_Format );
      goto Exit;
    }

    if ( vsindex >= vs->dataCount )
    {
      FT_TRACE4(( " cff_blend_build_vector: vsindex out of range\n" ));
      error = FT_THROW( Invalid_File_Format );
      goto Exit;
    }

    /* select the item variation data structure */
    varData = &vs->varData[vsindex];

    /* prepare buffer for the blend vector */
    len = varData->regionIdxCount + 1;    /* add 1 for default component */
    if ( FT_REALLOC( blend->BV,
                     blend->lenBV * sizeof( *blend->BV ),
                     len * sizeof( *blend->BV ) ) )
      goto Exit;

    blend->lenBV = len;

    /* outer loop steps through master designs to be blended */
    for ( master = 0; master < len; master++ )
    {
      FT_UInt         j;
      FT_UInt         idx;
      CFF_VarRegion*  varRegion;


      /* default factor is always one */
      if ( master == 0 )
      {
        blend->BV[master] = FT_FIXED_ONE;
        FT_TRACE4(( "   build blend vector len %d\n"
                    "   [ %f ",
                    len,
                    blend->BV[master] / 65536.0 ));
        continue;
      }

      /* VStore array does not include default master, so subtract one */
      idx       = varData->regionIndices[master - 1];
      varRegion = &vs->varRegionList[idx];

      if ( idx >= vs->regionCount )
      {
        FT_TRACE4(( " cff_blend_build_vector:"
                    " region index out of range\n" ));
        error = FT_THROW( Invalid_File_Format );
        goto Exit;
      }

      /* Note: `lenNDV' could be zero.                              */
      /*       In that case, build default blend vector (1,0,0...). */
      if ( !lenNDV )
      {
        blend->BV[master] = 0;
        continue;
      }

      /* In the normal case, initialize each component to 1 */
      /* before inner loop.                                 */
      blend->BV[master] = FT_FIXED_ONE; /* default */

      /* inner loop steps through axes in this region */
      for ( j = 0; j < lenNDV; j++ )
      {
        CFF_AxisCoords*  axis = &varRegion->axisList[j];
        FT_Fixed         axisScalar;


        /* compute the scalar contribution of this axis; */
        /* ignore invalid ranges                         */
        if ( axis->startCoord > axis->peakCoord ||
             axis->peakCoord > axis->endCoord   )
          axisScalar = FT_FIXED_ONE;

        else if ( axis->startCoord < 0 &&
                  axis->endCoord > 0   &&
                  axis->peakCoord != 0 )
          axisScalar = FT_FIXED_ONE;

        /* peak of 0 means ignore this axis */
        else if ( axis->peakCoord == 0 )
          axisScalar = FT_FIXED_ONE;

        /* ignore this region if coords are out of range */
        else if ( NDV[j] < axis->startCoord ||
                  NDV[j] > axis->endCoord   )
          axisScalar = 0;

        /* calculate a proportional factor */
        else
        {
          if ( NDV[j] == axis->peakCoord )
            axisScalar = FT_FIXED_ONE;
          else if ( NDV[j] < axis->peakCoord )
            axisScalar = FT_DivFix( NDV[j] - axis->startCoord,
                                    axis->peakCoord - axis->startCoord );
          else
            axisScalar = FT_DivFix( axis->endCoord - NDV[j],
                                    axis->endCoord - axis->peakCoord );
        }

        /* take product of all the axis scalars */
        blend->BV[master] = FT_MulFix( blend->BV[master], axisScalar );
      }

      FT_TRACE4(( ", %f ",
                  blend->BV[master] / 65536.0 ));
    }

    FT_TRACE4(( "]\n" ));

    /* record the parameters used to build the blend vector */
    blend->lastVsindex = vsindex;

    if ( lenNDV != 0 )
    {
      /* user has set a normalized vector */
      if ( FT_REALLOC( blend->lastNDV,
                       blend->lenNDV * sizeof ( *NDV ),
                       lenNDV * sizeof ( *NDV ) ) )
        goto Exit;

      FT_MEM_COPY( blend->lastNDV,
                   NDV,
                   lenNDV * sizeof ( *NDV ) );
    }

    blend->lenNDV  = lenNDV;
    blend->builtBV = TRUE;

  Exit:
    return error;
  }


  /* `lenNDV' is zero for default vector;           */
  /* return TRUE if blend vector needs to be built. */
  FT_LOCAL_DEF( FT_Bool )
  cff_blend_check_vector( CFF_Blend  blend,
                          FT_UInt    vsindex,
                          FT_UInt    lenNDV,
                          FT_Fixed*  NDV )
  {
    if ( !blend->builtBV                                ||
         blend->lastVsindex != vsindex                  ||
         blend->lenNDV != lenNDV                        ||
         ( lenNDV                                     &&
           ft_memcmp( NDV,
                      blend->lastNDV,
                      lenNDV * sizeof ( *NDV ) ) != 0 ) )
    {
      /* need to build blend vector */
      return TRUE;
    }

    return FALSE;
  }


#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT

  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 )
  {
    FT_Service_MultiMasters  mm = (FT_Service_MultiMasters)face->mm;


    return mm->get_var_blend( FT_FACE( face ),
                              num_coords,
                              coords,
                              normalizedcoords,
                              mm_var );
  }


  FT_LOCAL_DEF( void )
  cff_done_blend( CFF_Face  face )
  {
    FT_Service_MultiMasters  mm = (FT_Service_MultiMasters)face->mm;


    if (mm)
      mm->done_blend( FT_FACE( face ) );
  }

#endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */


  static void
  cff_encoding_done( CFF_Encoding  encoding )
  {
    encoding->format = 0;
    encoding->offset = 0;
    encoding->count  = 0;
  }


  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 )
  {
    FT_Error   error = FT_Err_Ok;
    FT_UInt    count;
    FT_UInt    j;
    FT_UShort  glyph_sid;
    FT_UInt    glyph_code;


    /* Check for charset->sids.  If we do not have this, we fail. */
    if ( !charset->sids )
    {
      error = FT_THROW( Invalid_File_Format );
      goto Exit;
    }

    /* Zero out the code to gid/sid mappings. */
    for ( j = 0; j < 256; j++ )
    {
      encoding->sids [j] = 0;
      encoding->codes[j] = 0;
    }

    /* Note: The encoding table in a CFF font is indexed by glyph index;  */
    /* the first encoded glyph index is 1.  Hence, we read the character  */
    /* code (`glyph_code') at index j and make the assignment:            */
    /*                                                                    */
    /*    encoding->codes[glyph_code] = j + 1                             */
    /*                                                                    */
    /* We also make the assignment:                                       */
    /*                                                                    */
    /*    encoding->sids[glyph_code] = charset->sids[j + 1]               */
    /*                                                                    */
    /* This gives us both a code to GID and a code to SID mapping.        */

    if ( offset > 1 )
    {
      encoding->offset = base_offset + offset;

      /* we need to parse the table to determine its size */
      if ( FT_STREAM_SEEK( encoding->offset ) ||
           FT_READ_BYTE( encoding->format )   ||
           FT_READ_BYTE( count )              )
        goto Exit;

      switch ( encoding->format & 0x7F )
      {
      case 0:
        {
          FT_Byte*  p;


          /* By convention, GID 0 is always ".notdef" and is never */
          /* coded in the font.  Hence, the number of codes found  */
          /* in the table is `count+1'.                            */
          /*                                                       */
          encoding->count = count + 1;

          if ( FT_FRAME_ENTER( count ) )
            goto Exit;

          p = (FT_Byte*)stream->cursor;

          for ( j = 1; j <= count; j++ )
          {
            glyph_code = *p++;

            /* Make sure j is not too big. */
            if ( j < num_glyphs )
            {
              /* Assign code to GID mapping. */
              encoding->codes[glyph_code] = (FT_UShort)j;

              /* Assign code to SID mapping. */
              encoding->sids[glyph_code] = charset->sids[j];
            }
          }

          FT_FRAME_EXIT();
        }
        break;

      case 1:
        {
          FT_UInt  nleft;
          FT_UInt  i = 1;
          FT_UInt  k;


          encoding->count = 0;

          /* Parse the Format1 ranges. */
          for ( j = 0;  j < count; j++, i += nleft )
          {
            /* Read the first glyph code of the range. */
            if ( FT_READ_BYTE( glyph_code ) )
              goto Exit;

            /* Read the number of codes in the range. */
            if ( FT_READ_BYTE( nleft ) )
              goto Exit;

            /* Increment nleft, so we read `nleft + 1' codes/sids. */
            nleft++;

            /* compute max number of character codes */
            if ( (FT_UInt)nleft > encoding->count )
              encoding->count = nleft;

            /* Fill in the range of codes/sids. */
            for ( k = i; k < nleft + i; k++, glyph_code++ )
            {
              /* Make sure k is not too big. */
              if ( k < num_glyphs && glyph_code < 256 )
              {
                /* Assign code to GID mapping. */
                encoding->codes[glyph_code] = (FT_UShort)k;

                /* Assign code to SID mapping. */
                encoding->sids[glyph_code] = charset->sids[k];
              }
            }
          }

          /* simple check; one never knows what can be found in a font */
          if ( encoding->count > 256 )
            encoding->count = 256;
        }
        break;

      default:
        FT_ERROR(( "cff_encoding_load: invalid table format\n" ));
        error = FT_THROW( Invalid_File_Format );
        goto Exit;
      }

      /* Parse supplemental encodings, if any. */
      if ( encoding->format & 0x80 )
      {
        FT_UInt  gindex;


        /* count supplements */
        if ( FT_READ_BYTE( count ) )
          goto Exit;

        for ( j = 0; j < count; j++ )
        {
          /* Read supplemental glyph code. */
          if ( FT_READ_BYTE( glyph_code ) )
            goto Exit;

          /* Read the SID associated with this glyph code. */
          if ( FT_READ_USHORT( glyph_sid ) )
            goto Exit;

          /* Assign code to SID mapping. */
          encoding->sids[glyph_code] = glyph_sid;

          /* First, look up GID which has been assigned to */
          /* SID glyph_sid.                                */
          for ( gindex = 0; gindex < num_glyphs; gindex++ )
          {
            if ( charset->sids[gindex] == glyph_sid )
            {
              encoding->codes[glyph_code] = (FT_UShort)gindex;
              break;
            }
          }
        }
      }
    }
    else
    {
      /* We take into account the fact a CFF font can use a predefined */
      /* encoding without containing all of the glyphs encoded by this */
      /* encoding (see the note at the end of section 12 in the CFF    */
      /* specification).                                               */

      switch ( (FT_UInt)offset )
      {
      case 0:
        /* First, copy the code to SID mapping. */
        FT_ARRAY_COPY( encoding->sids, cff_standard_encoding, 256 );
        goto Populate;

      case 1:
        /* First, copy the code to SID mapping. */
        FT_ARRAY_COPY( encoding->sids, cff_expert_encoding, 256 );

      Populate:
        /* Construct code to GID mapping from code to SID mapping */
        /* and charset.                                           */

        encoding->count = 0;

        error = cff_charset_compute_cids( charset, num_glyphs,
                                          stream->memory );
        if ( error )
          goto Exit;

        for ( j = 0; j < 256; j++ )
        {
          FT_UInt  sid = encoding->sids[j];
          FT_UInt  gid = 0;


          if ( sid )
            gid = cff_charset_cid_to_gindex( charset, sid );

          if ( gid != 0 )
          {
            encoding->codes[j] = (FT_UShort)gid;
            encoding->count    = j + 1;
          }
          else
          {
            encoding->codes[j] = 0;
            encoding->sids [j] = 0;
          }
        }
        break;

      default:
        FT_ERROR(( "cff_encoding_load: invalid table format\n" ));
        error = FT_THROW( Invalid_File_Format );
        goto Exit;
      }
    }

  Exit:

    /* Clean up if there was an error. */
    return error;
  }


  /* Parse private dictionary; first call is always from `cff_face_init', */
  /* so NDV has not been set for CFF2 variation.                          */
  /*                                                                      */
  /* `cff_slot_load' must call this function each time NDV changes.       */
  FT_LOCAL_DEF( FT_Error )
  cff_load_private_dict( CFF_Font     font,
                         CFF_SubFont  subfont,
                         FT_UInt      lenNDV,
                         FT_Fixed*    NDV )
  {
    FT_Error         error  = FT_Err_Ok;
    CFF_ParserRec    parser;
    CFF_FontRecDict  top    = &subfont->font_dict;
    CFF_Private      priv   = &subfont->private_dict;
    FT_Stream        stream = font->stream;
    FT_UInt          stackSize;


    /* store handle needed to access memory, vstore for blend;    */
    /* we need this for clean-up even if there is no private DICT */
    subfont->blend.font   = font;
    subfont->blend.usedBV = FALSE;  /* clear state */

    if ( !top->private_offset || !top->private_size )
      goto Exit2;       /* no private DICT, do nothing */

    /* set defaults */
    FT_ZERO( priv );

    priv->blue_shift       = 7;
    priv->blue_fuzz        = 1;
    priv->lenIV            = -1;
    priv->expansion_factor = (FT_Fixed)( 0.06 * 0x10000L );
    priv->blue_scale       = (FT_Fixed)( 0.039625 * 0x10000L * 1000 );

    /* provide inputs for blend calculations */
    priv->subfont   = subfont;
    subfont->lenNDV = lenNDV;
    subfont->NDV    = NDV;

    /* add 1 for the operator */
    stackSize = font->cff2 ? font->top_font.font_dict.maxstack + 1
                           : CFF_MAX_STACK_DEPTH + 1;

    if ( cff_parser_init( &parser,
                          font->cff2 ? CFF2_CODE_PRIVATE : CFF_CODE_PRIVATE,
                          priv,
                          font->library,
                          stackSize,
                          top->num_designs,
                          top->num_axes ) )
      goto Exit;

    if ( FT_STREAM_SEEK( font->base_offset + top->private_offset ) ||
         FT_FRAME_ENTER( top->private_size )                       )
      goto Exit;

    FT_TRACE4(( " private dictionary:\n" ));
    error = cff_parser_run( &parser,
                            (FT_Byte*)stream->cursor,
                            (FT_Byte*)stream->limit );
    FT_FRAME_EXIT();

    if ( error )
      goto Exit;

    /* ensure that `num_blue_values' is even */
    priv->num_blue_values &= ~1;

    /* sanitize `initialRandomSeed' to be a positive value, if necessary;  */
    /* this is not mandated by the specification but by our implementation */
    if ( priv->initial_random_seed < 0 )
      priv->initial_random_seed = -priv->initial_random_seed;
    else if ( priv->initial_random_seed == 0 )
      priv->initial_random_seed = 987654321;

    /* some sanitizing to avoid overflows later on; */
    /* the upper limits are ad-hoc values           */
    if ( priv->blue_shift > 1000 || priv->blue_shift < 0 )
    {
      FT_TRACE2(( "cff_load_private_dict:"
                  " setting unlikely BlueShift value %d to default (7)\n",
                  priv->blue_shift ));
      priv->blue_shift = 7;
    }

    if ( priv->blue_fuzz > 1000 || priv->blue_fuzz < 0 )
    {
      FT_TRACE2(( "cff_load_private_dict:"
                  " setting unlikely BlueFuzz value %d to default (1)\n",
                  priv->blue_fuzz ));
      priv->blue_fuzz = 1;
    }

  Exit:
    /* clean up */
    cff_blend_clear( subfont ); /* clear blend stack */
    cff_parser_done( &parser ); /* free parser stack */

  Exit2:
    /* no clean up (parser not initialized) */
    return error;
  }


  /* There are 3 ways to call this function, distinguished by code.  */
  /*                                                                 */
  /* . CFF_CODE_TOPDICT for either a CFF Top DICT or a CFF Font DICT */
  /* . CFF2_CODE_TOPDICT for CFF2 Top DICT                           */
  /* . CFF2_CODE_FONTDICT for CFF2 Font DICT                         */

  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 )
  {
    FT_Error         error;
    CFF_ParserRec    parser;
    FT_Byte*         dict = NULL;
    FT_ULong         dict_len;
    CFF_FontRecDict  top  = &subfont->font_dict;
    CFF_Private      priv = &subfont->private_dict;

    PSAux_Service  psaux = (PSAux_Service)face->psaux;

    FT_Bool  cff2      = FT_BOOL( code == CFF2_CODE_TOPDICT  ||
                                  code == CFF2_CODE_FONTDICT );
    FT_UInt  stackSize = cff2 ? CFF2_DEFAULT_STACK
                              : CFF_MAX_STACK_DEPTH;


    /* Note: We use default stack size for CFF2 Font DICT because        */
    /*       Top and Font DICTs are not allowed to have blend operators. */
    error = cff_parser_init( &parser,
                             code,
                             &subfont->font_dict,
                             font->library,
                             stackSize,
                             0,
                             0 );
    if ( error )
      goto Exit;

    /* set defaults */
    FT_ZERO( top );

    top->underline_position  = -( 100L << 16 );
    top->underline_thickness = 50L << 16;
    top->charstring_type     = 2;
    top->font_matrix.xx      = 0x10000L;
    top->font_matrix.yy      = 0x10000L;
    top->cid_count           = 8720;

    /* we use the implementation specific SID value 0xFFFF to indicate */
    /* missing entries                                                 */
    top->version             = 0xFFFFU;
    top->notice              = 0xFFFFU;
    top->copyright           = 0xFFFFU;
    top->full_name           = 0xFFFFU;
    top->family_name         = 0xFFFFU;
    top->weight              = 0xFFFFU;
    top->embedded_postscript = 0xFFFFU;

    top->cid_registry        = 0xFFFFU;
    top->cid_ordering        = 0xFFFFU;
    top->cid_font_name       = 0xFFFFU;

    /* set default stack size */
    top->maxstack            = cff2 ? CFF2_DEFAULT_STACK : 48;

    if ( idx->count )   /* count is nonzero for a real index */
      error = cff_index_access_element( idx, font_index, &dict, &dict_len );
    else
    {
      /* CFF2 has a fake top dict index;     */
      /* simulate `cff_index_access_element' */

      /* Note: macros implicitly use `stream' and set `error' */
      if ( FT_STREAM_SEEK( idx->data_offset )       ||
           FT_FRAME_EXTRACT( idx->data_size, dict ) )
        goto Exit;

      dict_len = idx->data_size;
    }

    if ( !error )
    {
      FT_TRACE4(( " top dictionary:\n" ));
      error = cff_parser_run( &parser, dict, FT_OFFSET( dict, dict_len ) );
    }

    /* clean up regardless of error */
    if ( idx->count )
      cff_index_forget_element( idx, &dict );
    else
      FT_FRAME_RELEASE( dict );

    if ( error )
      goto Exit;

    /* if it is a CID font, we stop there */
    if ( top->cid_registry != 0xFFFFU )
      goto Exit;

    /* Parse the private dictionary, if any.                   */
    /*                                                         */
    /* CFF2 does not have a private dictionary in the Top DICT */
    /* but may have one in a Font DICT.  We need to parse      */
    /* the latter here in order to load any local subrs.       */
    error = cff_load_private_dict( font, subfont, 0, 0 );
    if ( error )
      goto Exit;

    if ( !cff2 )
    {
      /*
       * Initialize the random number generator.
       *
       * - If we have a face-specific seed, use it.
       *   If non-zero, update it to a positive value.
       *
       * - Otherwise, use the seed from the CFF driver.
       *   If non-zero, update it to a positive value.
       *
       * - If the random value is zero, use the seed given by the subfont's
       *   `initialRandomSeed' value.
       *
       */
      if ( face->root.internal->random_seed == -1 )
      {
        PS_Driver  driver = (PS_Driver)FT_FACE_DRIVER( face );


        subfont->random = (FT_UInt32)driver->random_seed;
        if ( driver->random_seed )
        {
          do
          {
            driver->random_seed =
              (FT_Int32)psaux->cff_random( (FT_UInt32)driver->random_seed );

          } while ( driver->random_seed < 0 );
        }
      }
      else
      {
        subfont->random = (FT_UInt32)face->root.internal->random_seed;
        if ( face->root.internal->random_seed )
        {
          do
          {
            face->root.internal->random_seed =
              (FT_Int32)psaux->cff_random(
                (FT_UInt32)face->root.internal->random_seed );

          } while ( face->root.internal->random_seed < 0 );
        }
      }

      if ( !subfont->random )
        subfont->random = (FT_UInt32)priv->initial_random_seed;
    }

    /* read the local subrs, if any */
    if ( priv->local_subrs_offset )
    {
      if ( FT_STREAM_SEEK( base_offset + top->private_offset +
                           priv->local_subrs_offset ) )
        goto Exit;

      error = cff_index_init( &subfont->local_subrs_index, stream, 1, cff2 );
      if ( error )
        goto Exit;

      error = cff_index_get_pointers( &subfont->local_subrs_index,
                                      &subfont->local_subrs, NULL, NULL );
      if ( error )
        goto Exit;
    }

  Exit:
    cff_parser_done( &parser ); /* free parser stack */

    return error;
  }


  static void
  cff_subfont_done( FT_Memory    memory,
                    CFF_SubFont  subfont )
  {
    if ( subfont )
    {
      cff_index_done( &subfont->local_subrs_index );
      FT_FREE( subfont->local_subrs );

      FT_FREE( subfont->blend.lastNDV );
      FT_FREE( subfont->blend.BV );
      FT_FREE( subfont->blend_stack );
    }
  }


  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 )
  {
    static const FT_Frame_Field  cff_header_fields[] =
    {
#undef  FT_STRUCTURE
#define FT_STRUCTURE  CFF_FontRec

      FT_FRAME_START( 3 ),
        FT_FRAME_BYTE( version_major ),
        FT_FRAME_BYTE( version_minor ),
        FT_FRAME_BYTE( header_size ),
      FT_FRAME_END
    };

    FT_Error         error;
    FT_Memory        memory = stream->memory;
    FT_ULong         base_offset;
    CFF_FontRecDict  dict;
    CFF_IndexRec     string_index;
    FT_UInt          subfont_index;


    FT_ZERO( font );
    FT_ZERO( &string_index );

    dict        = &font->top_font.font_dict;
    base_offset = FT_STREAM_POS();

    font->library     = library;
    font->stream      = stream;
    font->memory      = memory;
    font->cff2        = cff2;
    font->base_offset = base_offset;

    /* read CFF font header */
    if ( FT_STREAM_READ_FIELDS( cff_header_fields, font ) )
      goto Exit;

    if ( cff2 )
    {
      if ( font->version_major != 2 ||
           font->header_size < 5    )
      {
        FT_TRACE2(( "  not a CFF2 font header\n" ));
        error = FT_THROW( Unknown_File_Format );
        goto Exit;
      }

      if ( FT_READ_USHORT( font->top_dict_length ) )
        goto Exit;
    }
    else
    {
      FT_Byte  absolute_offset;


      if ( FT_READ_BYTE( absolute_offset ) )
        goto Exit;

      if ( font->version_major != 1 ||
           font->header_size < 4    ||
           absolute_offset > 4      )
      {
        FT_TRACE2(( "  not a CFF font header\n" ));
        error = FT_THROW( Unknown_File_Format );
        goto Exit;
      }
    }

    /* skip the rest of the header */
    if ( FT_STREAM_SEEK( base_offset + font->header_size ) )
    {
      /* For pure CFFs we have read only four bytes so far.  Contrary to */
      /* other formats like SFNT those bytes doesn't define a signature; */
      /* it is thus possible that the font isn't a CFF at all.           */
      if ( pure_cff )
      {
        FT_TRACE2(( "  not a CFF file\n" ));
        error = FT_THROW( Unknown_File_Format );
      }
      goto Exit;
    }

    if ( cff2 )
    {
      /* For CFF2, the top dict data immediately follow the header    */
      /* and the length is stored in the header `offSize' field;      */
      /* there is no index for it.                                    */
      /*                                                              */
      /* Use the `font_dict_index' to save the current position       */
      /* and length of data, but leave count at zero as an indicator. */
      FT_ZERO( &font->font_dict_index );

      font->font_dict_index.data_offset = FT_STREAM_POS();
      font->font_dict_index.data_size   = font->top_dict_length;

      /* skip the top dict data for now, we will parse it later */
      if ( FT_STREAM_SKIP( font->top_dict_length ) )
        goto Exit;

      /* next, read the global subrs index */
      if ( FT_SET_ERROR( cff_index_init( &font->global_subrs_index,
                                         stream, 1, cff2 ) ) )
        goto Exit;
    }
    else
    {
      /* for CFF, read the name, top dict, string and global subrs index */
      if ( FT_SET_ERROR( cff_index_init( &font->name_index,
                                         stream, 0, cff2 ) ) )
      {
        if ( pure_cff )
        {
          FT_TRACE2(( "  not a CFF file\n" ));
          error = FT_THROW( Unknown_File_Format );
        }
        goto Exit;
      }

      /* if we have an empty font name,      */
      /* it must be the only font in the CFF */
      if ( font->name_index.count > 1                          &&
           font->name_index.data_size < font->name_index.count )
      {
        /* for pure CFFs, we still haven't checked enough bytes */
        /* to be sure that it is a CFF at all                   */
        error = pure_cff ? FT_THROW( Unknown_File_Format )
                         : FT_THROW( Invalid_File_Format );
        goto Exit;
      }

      if ( FT_SET_ERROR( cff_index_init( &font->font_dict_index,
                                         stream, 0, cff2 ) )                 ||
           FT_SET_ERROR( cff_index_init( &string_index,
                                         stream, 1, cff2 ) )                 ||
           FT_SET_ERROR( cff_index_init( &font->global_subrs_index,
                                         stream, 1, cff2 ) )                 ||
           FT_SET_ERROR( cff_index_get_pointers( &string_index,
                                                 &font->strings,
                                                 &font->string_pool,
                                                 &font->string_pool_size ) ) )
        goto Exit;

      /* there must be a Top DICT index entry for each name index entry */
      if ( font->name_index.count > font->font_dict_index.count )
      {
        FT_ERROR(( "cff_font_load:"
                   " not enough entries in Top DICT index\n" ));
        error = FT_THROW( Invalid_File_Format );
        goto Exit;
      }
    }

    font->num_strings = string_index.count;

    if ( pure_cff )
    {
      /* well, we don't really forget the `disabled' fonts... */
      subfont_index = (FT_UInt)( face_index & 0xFFFF );

      if ( face_index > 0 && subfont_index >= font->name_index.count )
      {
        FT_ERROR(( "cff_font_load:"
                   " invalid subfont index for pure CFF font (%d)\n",
                   subfont_index ));
        error = FT_THROW( Invalid_Argument );
        goto Exit;
      }

      font->num_faces = font->name_index.count;
    }
    else
    {
      subfont_index = 0;

      if ( font->name_index.count > 1 )
      {
        FT_ERROR(( "cff_font_load:"
                   " invalid CFF font with multiple subfonts\n"
                   "              "
                   " in SFNT wrapper\n" ));
        error = FT_THROW( Invalid_File_Format );
        goto Exit;
      }
    }

    /* in case of a font format check, simply exit now */
    if ( face_index < 0 )
      goto Exit;

    /* now, parse the top-level font dictionary */
    FT_TRACE4(( "parsing top-level\n" ));
    error = cff_subfont_load( &font->top_font,
                              &font->font_dict_index,
                              subfont_index,
                              stream,
                              base_offset,
                              cff2 ? CFF2_CODE_TOPDICT : CFF_CODE_TOPDICT,
                              font,
                              face );
    if ( error )
      goto Exit;

    if ( FT_STREAM_SEEK( base_offset + dict->charstrings_offset ) )
      goto Exit;

    error = cff_index_init( &font->charstrings_index, stream, 0, cff2 );
    if ( error )
      goto Exit;

    /* now, check for a CID or CFF2 font */
    if ( dict->cid_registry != 0xFFFFU ||
         cff2                          )
    {
      CFF_IndexRec  fd_index;
      CFF_SubFont   sub = NULL;
      FT_UInt       idx;


      /* for CFF2, read the Variation Store if available;                 */
      /* this must follow the Top DICT parse and precede any Private DICT */
      error = cff_vstore_load( &font->vstore,
                               stream,
                               base_offset,
                               dict->vstore_offset );
      if ( error )
        goto Exit;

      /* this is a CID-keyed font, we must now allocate a table of */
      /* sub-fonts, then load each of them separately              */
      if ( FT_STREAM_SEEK( base_offset + dict->cid_fd_array_offset ) )
        goto Exit;

      error = cff_index_init( &fd_index, stream, 0, cff2 );
      if ( error )
        goto Exit;

      /* Font Dicts are not limited to 256 for CFF2. */
      /* TODO: support this for CFF2                 */
      if ( fd_index.count > CFF_MAX_CID_FONTS )
      {
        FT_TRACE0(( "cff_font_load: FD array too large in CID font\n" ));
        goto Fail_CID;
      }

      /* allocate & read each font dict independently */
      font->num_subfonts = fd_index.count;
      if ( FT_NEW_ARRAY( sub, fd_index.count ) )
        goto Fail_CID;

      /* set up pointer table */
      for ( idx = 0; idx < fd_index.count; idx++ )
        font->subfonts[idx] = sub + idx;

      /* now load each subfont independently */
      for ( idx = 0; idx < fd_index.count; idx++ )
      {
        sub = font->subfonts[idx];
        FT_TRACE4(( "parsing subfont %u\n", idx ));
        error = cff_subfont_load( sub,
                                  &fd_index,
                                  idx,
                                  stream,
                                  base_offset,
                                  cff2 ? CFF2_CODE_FONTDICT
                                       : CFF_CODE_TOPDICT,
                                  font,
                                  face );
        if ( error )
          goto Fail_CID;
      }

      /* now load the FD Select array;               */
      /* CFF2 omits FDSelect if there is only one FD */
      if ( !cff2 || fd_index.count > 1 )
        error = CFF_Load_FD_Select( &font->fd_select,
                                    font->charstrings_index.count,
                                    stream,
                                    base_offset + dict->cid_fd_select_offset );

    Fail_CID:
      cff_index_done( &fd_index );

      if ( error )
        goto Exit;
    }
    else
      font->num_subfonts = 0;

    /* read the charstrings index now */
    if ( dict->charstrings_offset == 0 )
    {
      FT_ERROR(( "cff_font_load: no charstrings offset\n" ));
      error = FT_THROW( Invalid_File_Format );
      goto Exit;
    }

    font->num_glyphs = font->charstrings_index.count;

    error = cff_index_get_pointers( &font->global_subrs_index,
                                    &font->global_subrs, NULL, NULL );

    if ( error )
      goto Exit;

    /* read the Charset and Encoding tables if available */
    if ( !cff2 && font->num_glyphs > 0 )
    {
      FT_Bool  invert = FT_BOOL( dict->cid_registry != 0xFFFFU && pure_cff );


      error = cff_charset_load( &font->charset, font->num_glyphs, stream,
                                base_offset, dict->charset_offset, invert );
      if ( error )
        goto Exit;

      /* CID-keyed CFFs don't have an encoding */
      if ( dict->cid_registry == 0xFFFFU )
      {
        error = cff_encoding_load( &font->encoding,
                                   &font->charset,
                                   font->num_glyphs,
                                   stream,
                                   base_offset,
                                   dict->encoding_offset );
        if ( error )
          goto Exit;
      }
    }

    /* get the font name (/CIDFontName for CID-keyed fonts, */
    /* /FontName otherwise)                                 */
    font->font_name = cff_index_get_name( font, subfont_index );

  Exit:
    cff_index_done( &string_index );

    return error;
  }


  FT_LOCAL_DEF( void )
  cff_font_done( CFF_Font  font )
  {
    FT_Memory  memory = font->memory;
    FT_UInt    idx;


    cff_index_done( &font->global_subrs_index );
    cff_index_done( &font->font_dict_index );
    cff_index_done( &font->name_index );
    cff_index_done( &font->charstrings_index );

    /* release font dictionaries, but only if working with */
    /* a CID keyed CFF font or a CFF2 font                 */
    if ( font->num_subfonts > 0 )
    {
      for ( idx = 0; idx < font->num_subfonts; idx++ )
        cff_subfont_done( memory, font->subfonts[idx] );

      /* the subfonts array has been allocated as a single block */
      FT_FREE( font->subfonts[0] );
    }

    cff_encoding_done( &font->encoding );
    cff_charset_done( &font->charset, font->stream );
    cff_vstore_done( &font->vstore, memory );

    cff_subfont_done( memory, &font->top_font );

    CFF_Done_FD_Select( &font->fd_select, font->stream );

    FT_FREE( font->font_info );

    FT_FREE( font->font_name );
    FT_FREE( font->global_subrs );
    FT_FREE( font->strings );
    FT_FREE( font->string_pool );

    if ( font->cf2_instance.finalizer )
    {
      font->cf2_instance.finalizer( font->cf2_instance.data );
      FT_FREE( font->cf2_instance.data );
    }

    FT_FREE( font->font_extra );
  }


/* END */
