/****************************************************************************
 *
 * 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 <freetype/internal/ftdebug.h>
#include <freetype/internal/ftobjs.h>
#include <freetype/internal/ftstream.h>
#include <freetype/tttags.h>
#include <freetype/t1tables.h>
#include <freetype/internal/psaux.h>

#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
#include <freetype/ftmm.h>
#include <freetype/internal/services/svmm.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:
    if ( error && new_bytes )
      FT_FREE( new_bytes );
    if ( error && t )
      FT_FREE( t );
    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 */
