PageRenderTime 109ms CodeModel.GetById 30ms app.highlight 69ms RepoModel.GetById 1ms app.codeStats 0ms

/src/compiler/android-ndk/jni/freetype/src/cff/cffload.c

http://ftk.googlecode.com/
C | 1638 lines | 1148 code | 323 blank | 167 comment | 189 complexity | ee487f44a6a570579a23b67776d24860 MD5 | raw file
   1/***************************************************************************/
   2/*                                                                         */
   3/*  cffload.c                                                              */
   4/*                                                                         */
   5/*    OpenType and CFF data/program tables loader (body).                  */
   6/*                                                                         */
   7/*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */
   8/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
   9/*                                                                         */
  10/*  This file is part of the FreeType project, and may only be used,       */
  11/*  modified, and distributed under the terms of the FreeType project      */
  12/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
  13/*  this file you indicate that you have read the license and              */
  14/*  understand and accept it fully.                                        */
  15/*                                                                         */
  16/***************************************************************************/
  17
  18
  19#include <ft2build.h>
  20#include FT_INTERNAL_DEBUG_H
  21#include FT_INTERNAL_OBJECTS_H
  22#include FT_INTERNAL_STREAM_H
  23#include FT_SERVICE_POSTSCRIPT_CMAPS_H
  24#include FT_TRUETYPE_TAGS_H
  25#include FT_TYPE1_TABLES_H
  26
  27#include "cffload.h"
  28#include "cffparse.h"
  29
  30#include "cfferrs.h"
  31
  32
  33#if 1
  34
  35  static const FT_UShort  cff_isoadobe_charset[229] =
  36  {
  37      0,   1,   2,   3,   4,   5,   6,   7,
  38      8,   9,  10,  11,  12,  13,  14,  15,
  39     16,  17,  18,  19,  20,  21,  22,  23,
  40     24,  25,  26,  27,  28,  29,  30,  31,
  41     32,  33,  34,  35,  36,  37,  38,  39,
  42     40,  41,  42,  43,  44,  45,  46,  47,
  43     48,  49,  50,  51,  52,  53,  54,  55,
  44     56,  57,  58,  59,  60,  61,  62,  63,
  45     64,  65,  66,  67,  68,  69,  70,  71,
  46     72,  73,  74,  75,  76,  77,  78,  79,
  47     80,  81,  82,  83,  84,  85,  86,  87,
  48     88,  89,  90,  91,  92,  93,  94,  95,
  49     96,  97,  98,  99, 100, 101, 102, 103,
  50    104, 105, 106, 107, 108, 109, 110, 111,
  51    112, 113, 114, 115, 116, 117, 118, 119,
  52    120, 121, 122, 123, 124, 125, 126, 127,
  53    128, 129, 130, 131, 132, 133, 134, 135,
  54    136, 137, 138, 139, 140, 141, 142, 143,
  55    144, 145, 146, 147, 148, 149, 150, 151,
  56    152, 153, 154, 155, 156, 157, 158, 159,
  57    160, 161, 162, 163, 164, 165, 166, 167,
  58    168, 169, 170, 171, 172, 173, 174, 175,
  59    176, 177, 178, 179, 180, 181, 182, 183,
  60    184, 185, 186, 187, 188, 189, 190, 191,
  61    192, 193, 194, 195, 196, 197, 198, 199,
  62    200, 201, 202, 203, 204, 205, 206, 207,
  63    208, 209, 210, 211, 212, 213, 214, 215,
  64    216, 217, 218, 219, 220, 221, 222, 223,
  65    224, 225, 226, 227, 228
  66  };
  67
  68  static const FT_UShort  cff_expert_charset[166] =
  69  {
  70      0,   1, 229, 230, 231, 232, 233, 234,
  71    235, 236, 237, 238,  13,  14,  15,  99,
  72    239, 240, 241, 242, 243, 244, 245, 246,
  73    247, 248,  27,  28, 249, 250, 251, 252,
  74    253, 254, 255, 256, 257, 258, 259, 260,
  75    261, 262, 263, 264, 265, 266, 109, 110,
  76    267, 268, 269, 270, 271, 272, 273, 274,
  77    275, 276, 277, 278, 279, 280, 281, 282,
  78    283, 284, 285, 286, 287, 288, 289, 290,
  79    291, 292, 293, 294, 295, 296, 297, 298,
  80    299, 300, 301, 302, 303, 304, 305, 306,
  81    307, 308, 309, 310, 311, 312, 313, 314,
  82    315, 316, 317, 318, 158, 155, 163, 319,
  83    320, 321, 322, 323, 324, 325, 326, 150,
  84    164, 169, 327, 328, 329, 330, 331, 332,
  85    333, 334, 335, 336, 337, 338, 339, 340,
  86    341, 342, 343, 344, 345, 346, 347, 348,
  87    349, 350, 351, 352, 353, 354, 355, 356,
  88    357, 358, 359, 360, 361, 362, 363, 364,
  89    365, 366, 367, 368, 369, 370, 371, 372,
  90    373, 374, 375, 376, 377, 378
  91  };
  92
  93  static const FT_UShort  cff_expertsubset_charset[87] =
  94  {
  95      0,   1, 231, 232, 235, 236, 237, 238,
  96     13,  14,  15,  99, 239, 240, 241, 242,
  97    243, 244, 245, 246, 247, 248,  27,  28,
  98    249, 250, 251, 253, 254, 255, 256, 257,
  99    258, 259, 260, 261, 262, 263, 264, 265,
 100    266, 109, 110, 267, 268, 269, 270, 272,
 101    300, 301, 302, 305, 314, 315, 158, 155,
 102    163, 320, 321, 322, 323, 324, 325, 326,
 103    150, 164, 169, 327, 328, 329, 330, 331,
 104    332, 333, 334, 335, 336, 337, 338, 339,
 105    340, 341, 342, 343, 344, 345, 346
 106  };
 107
 108  static const FT_UShort  cff_standard_encoding[256] =
 109  {
 110      0,   0,   0,   0,   0,   0,   0,   0,
 111      0,   0,   0,   0,   0,   0,   0,   0,
 112      0,   0,   0,   0,   0,   0,   0,   0,
 113      0,   0,   0,   0,   0,   0,   0,   0,
 114      1,   2,   3,   4,   5,   6,   7,   8,
 115      9,  10,  11,  12,  13,  14,  15,  16,
 116     17,  18,  19,  20,  21,  22,  23,  24,
 117     25,  26,  27,  28,  29,  30,  31,  32,
 118     33,  34,  35,  36,  37,  38,  39,  40,
 119     41,  42,  43,  44,  45,  46,  47,  48,
 120     49,  50,  51,  52,  53,  54,  55,  56,
 121     57,  58,  59,  60,  61,  62,  63,  64,
 122     65,  66,  67,  68,  69,  70,  71,  72,
 123     73,  74,  75,  76,  77,  78,  79,  80,
 124     81,  82,  83,  84,  85,  86,  87,  88,
 125     89,  90,  91,  92,  93,  94,  95,   0,
 126      0,   0,   0,   0,   0,   0,   0,   0,
 127      0,   0,   0,   0,   0,   0,   0,   0,
 128      0,   0,   0,   0,   0,   0,   0,   0,
 129      0,   0,   0,   0,   0,   0,   0,   0,
 130      0,  96,  97,  98,  99, 100, 101, 102,
 131    103, 104, 105, 106, 107, 108, 109, 110,
 132      0, 111, 112, 113, 114,   0, 115, 116,
 133    117, 118, 119, 120, 121, 122,   0, 123,
 134      0, 124, 125, 126, 127, 128, 129, 130,
 135    131,   0, 132, 133,   0, 134, 135, 136,
 136    137,   0,   0,   0,   0,   0,   0,   0,
 137      0,   0,   0,   0,   0,   0,   0,   0,
 138      0, 138,   0, 139,   0,   0,   0,   0,
 139    140, 141, 142, 143,   0,   0,   0,   0,
 140      0, 144,   0,   0,   0, 145,   0,   0,
 141    146, 147, 148, 149,   0,   0,   0,   0
 142  };
 143
 144  static const FT_UShort  cff_expert_encoding[256] =
 145  {
 146      0,   0,   0,   0,   0,   0,   0,   0,
 147      0,   0,   0,   0,   0,   0,   0,   0,
 148      0,   0,   0,   0,   0,   0,   0,   0,
 149      0,   0,   0,   0,   0,   0,   0,   0,
 150      1, 229, 230,   0, 231, 232, 233, 234,
 151    235, 236, 237, 238,  13,  14,  15,  99,
 152    239, 240, 241, 242, 243, 244, 245, 246,
 153    247, 248,  27,  28, 249, 250, 251, 252,
 154      0, 253, 254, 255, 256, 257,   0,   0,
 155      0, 258,   0,   0, 259, 260, 261, 262,
 156      0,   0, 263, 264, 265,   0, 266, 109,
 157    110, 267, 268, 269,   0, 270, 271, 272,
 158    273, 274, 275, 276, 277, 278, 279, 280,
 159    281, 282, 283, 284, 285, 286, 287, 288,
 160    289, 290, 291, 292, 293, 294, 295, 296,
 161    297, 298, 299, 300, 301, 302, 303,   0,
 162      0,   0,   0,   0,   0,   0,   0,   0,
 163      0,   0,   0,   0,   0,   0,   0,   0,
 164      0,   0,   0,   0,   0,   0,   0,   0,
 165      0,   0,   0,   0,   0,   0,   0,   0,
 166      0, 304, 305, 306,   0,   0, 307, 308,
 167    309, 310, 311,   0, 312,   0,   0, 312,
 168      0,   0, 314, 315,   0,   0, 316, 317,
 169    318,   0,   0,   0, 158, 155, 163, 319,
 170    320, 321, 322, 323, 324, 325,   0,   0,
 171    326, 150, 164, 169, 327, 328, 329, 330,
 172    331, 332, 333, 334, 335, 336, 337, 338,
 173    339, 340, 341, 342, 343, 344, 345, 346,
 174    347, 348, 349, 350, 351, 352, 353, 354,
 175    355, 356, 357, 358, 359, 360, 361, 362,
 176    363, 364, 365, 366, 367, 368, 369, 370,
 177    371, 372, 373, 374, 375, 376, 377, 378
 178  };
 179
 180#endif /* 1 */
 181
 182
 183  FT_LOCAL_DEF( FT_UShort )
 184  cff_get_standard_encoding( FT_UInt  charcode )
 185  {
 186    return (FT_UShort)( charcode < 256 ? cff_standard_encoding[charcode]
 187                                       : 0 );
 188  }
 189
 190
 191  /*************************************************************************/
 192  /*                                                                       */
 193  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
 194  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
 195  /* messages during execution.                                            */
 196  /*                                                                       */
 197#undef  FT_COMPONENT
 198#define FT_COMPONENT  trace_cffload
 199
 200
 201  /* read an offset from the index's stream current position */
 202  static FT_ULong
 203  cff_index_read_offset( CFF_Index  idx,
 204                         FT_Error  *errorp )
 205  {
 206    FT_Error   error;
 207    FT_Stream  stream = idx->stream;
 208    FT_Byte    tmp[4];
 209    FT_ULong   result = 0;
 210
 211
 212    if ( !FT_STREAM_READ( tmp, idx->off_size ) )
 213    {
 214      FT_Int  nn;
 215
 216
 217      for ( nn = 0; nn < idx->off_size; nn++ )
 218        result = ( result << 8 ) | tmp[nn];
 219    }
 220
 221    *errorp = error;
 222    return result;
 223  }
 224
 225
 226  static FT_Error
 227  cff_index_init( CFF_Index  idx,
 228                  FT_Stream  stream,
 229                  FT_Bool    load )
 230  {
 231    FT_Error   error;
 232    FT_Memory  memory = stream->memory;
 233    FT_UShort  count;
 234
 235
 236    FT_MEM_ZERO( idx, sizeof ( *idx ) );
 237
 238    idx->stream = stream;
 239    idx->start  = FT_STREAM_POS();
 240    if ( !FT_READ_USHORT( count ) &&
 241         count > 0                )
 242    {
 243      FT_Byte   offsize;
 244      FT_ULong  size;
 245
 246
 247      /* there is at least one element; read the offset size,           */
 248      /* then access the offset table to compute the index's total size */
 249      if ( FT_READ_BYTE( offsize ) )
 250        goto Exit;
 251
 252      if ( offsize < 1 || offsize > 4 )
 253      {
 254        error = FT_Err_Invalid_Table;
 255        goto Exit;
 256      }
 257
 258      idx->count    = count;
 259      idx->off_size = offsize;
 260      size          = (FT_ULong)( count + 1 ) * offsize;
 261
 262      idx->data_offset = idx->start + 3 + size;
 263
 264      if ( FT_STREAM_SKIP( size - offsize ) )
 265        goto Exit;
 266
 267      size = cff_index_read_offset( idx, &error );
 268      if ( error )
 269        goto Exit;
 270
 271      if ( size == 0 )
 272      {
 273        error = CFF_Err_Invalid_Table;
 274        goto Exit;
 275      }
 276
 277      idx->data_size = --size;
 278
 279      if ( load )
 280      {
 281        /* load the data */
 282        if ( FT_FRAME_EXTRACT( size, idx->bytes ) )
 283          goto Exit;
 284      }
 285      else
 286      {
 287        /* skip the data */
 288        if ( FT_STREAM_SKIP( size ) )
 289          goto Exit;
 290      }
 291    }
 292
 293  Exit:
 294    if ( error )
 295      FT_FREE( idx->offsets );
 296
 297    return error;
 298  }
 299
 300
 301  static void
 302  cff_index_done( CFF_Index  idx )
 303  {
 304    if ( idx->stream )
 305    {
 306      FT_Stream  stream = idx->stream;
 307      FT_Memory  memory = stream->memory;
 308
 309
 310      if ( idx->bytes )
 311        FT_FRAME_RELEASE( idx->bytes );
 312
 313      FT_FREE( idx->offsets );
 314      FT_MEM_ZERO( idx, sizeof ( *idx ) );
 315    }
 316  }
 317
 318
 319  static FT_Error
 320  cff_index_load_offsets( CFF_Index  idx )
 321  {
 322    FT_Error   error  = CFF_Err_Ok;
 323    FT_Stream  stream = idx->stream;
 324    FT_Memory  memory = stream->memory;
 325
 326
 327    if ( idx->count > 0 && idx->offsets == NULL )
 328    {
 329      FT_Byte    offsize = idx->off_size;
 330      FT_ULong   data_size;
 331      FT_Byte*   p;
 332      FT_Byte*   p_end;
 333      FT_ULong*  poff;
 334
 335
 336      data_size = (FT_ULong)( idx->count + 1 ) * offsize;
 337
 338      if ( FT_NEW_ARRAY( idx->offsets, idx->count + 1 ) ||
 339           FT_STREAM_SEEK( idx->start + 3 )             ||
 340           FT_FRAME_ENTER( data_size )                  )
 341        goto Exit;
 342
 343      poff   = idx->offsets;
 344      p      = (FT_Byte*)stream->cursor;
 345      p_end  = p + data_size;
 346
 347      switch ( offsize )
 348      {
 349      case 1:
 350        for ( ; p < p_end; p++, poff++ )
 351          poff[0] = p[0];
 352        break;
 353
 354      case 2:
 355        for ( ; p < p_end; p += 2, poff++ )
 356          poff[0] = FT_PEEK_USHORT( p );
 357        break;
 358
 359      case 3:
 360        for ( ; p < p_end; p += 3, poff++ )
 361          poff[0] = FT_PEEK_OFF3( p );
 362        break;
 363
 364      default:
 365        for ( ; p < p_end; p += 4, poff++ )
 366          poff[0] = FT_PEEK_ULONG( p );
 367      }
 368
 369      FT_FRAME_EXIT();
 370    }
 371
 372  Exit:
 373    if ( error )
 374      FT_FREE( idx->offsets );
 375
 376    return error;
 377  }
 378
 379
 380  /* allocate a table containing pointers to an index's elements */
 381  static FT_Error
 382  cff_index_get_pointers( CFF_Index   idx,
 383                          FT_Byte***  table )
 384  {
 385    FT_Error   error  = CFF_Err_Ok;
 386    FT_Memory  memory = idx->stream->memory;
 387    FT_ULong   n, offset, old_offset;
 388    FT_Byte**  t;
 389
 390
 391    *table = 0;
 392
 393    if ( idx->offsets == NULL )
 394    {
 395      error = cff_index_load_offsets( idx );
 396      if ( error )
 397        goto Exit;
 398    }
 399
 400    if ( idx->count > 0 && !FT_NEW_ARRAY( t, idx->count + 1 ) )
 401    {
 402      old_offset = 1;
 403      for ( n = 0; n <= idx->count; n++ )
 404      {
 405        /* at this point, `idx->offsets' can't be NULL */
 406        offset = idx->offsets[n];
 407        if ( !offset )
 408          offset = old_offset;
 409
 410        /* two sanity checks for invalid offset tables */
 411        else if ( offset < old_offset )
 412          offset = old_offset;
 413
 414        else if ( offset - 1 >= idx->data_size && n < idx->count )
 415          offset = old_offset;
 416
 417        t[n] = idx->bytes + offset - 1;
 418
 419        old_offset = offset;
 420      }
 421      *table = t;
 422    }
 423
 424  Exit:
 425    return error;
 426  }
 427
 428
 429  FT_LOCAL_DEF( FT_Error )
 430  cff_index_access_element( CFF_Index  idx,
 431                            FT_UInt    element,
 432                            FT_Byte**  pbytes,
 433                            FT_ULong*  pbyte_len )
 434  {
 435    FT_Error  error = CFF_Err_Ok;
 436
 437
 438    if ( idx && idx->count > element )
 439    {
 440      /* compute start and end offsets */
 441      FT_Stream  stream = idx->stream;
 442      FT_ULong   off1, off2 = 0;
 443
 444
 445      /* load offsets from file or the offset table */
 446      if ( !idx->offsets )
 447      {
 448        FT_ULong  pos = element * idx->off_size;
 449
 450
 451        if ( FT_STREAM_SEEK( idx->start + 3 + pos ) )
 452          goto Exit;
 453
 454        off1 = cff_index_read_offset( idx, &error );
 455        if ( error )
 456          goto Exit;
 457
 458        if ( off1 != 0 )
 459        {
 460          do
 461          {
 462            element++;
 463            off2 = cff_index_read_offset( idx, &error );
 464          }
 465          while ( off2 == 0 && element < idx->count );
 466        }
 467      }
 468      else   /* use offsets table */
 469      {
 470        off1 = idx->offsets[element];
 471        if ( off1 )
 472        {
 473          do
 474          {
 475            element++;
 476            off2 = idx->offsets[element];
 477
 478          } while ( off2 == 0 && element < idx->count );
 479        }
 480      }
 481
 482      /* access element */
 483      if ( off1 && off2 > off1 )
 484      {
 485        *pbyte_len = off2 - off1;
 486
 487        if ( idx->bytes )
 488        {
 489          /* this index was completely loaded in memory, that's easy */
 490          *pbytes = idx->bytes + off1 - 1;
 491        }
 492        else
 493        {
 494          /* this index is still on disk/file, access it through a frame */
 495          if ( FT_STREAM_SEEK( idx->data_offset + off1 - 1 ) ||
 496               FT_FRAME_EXTRACT( off2 - off1, *pbytes )      )
 497            goto Exit;
 498        }
 499      }
 500      else
 501      {
 502        /* empty index element */
 503        *pbytes    = 0;
 504        *pbyte_len = 0;
 505      }
 506    }
 507    else
 508      error = CFF_Err_Invalid_Argument;
 509
 510  Exit:
 511    return error;
 512  }
 513
 514
 515  FT_LOCAL_DEF( void )
 516  cff_index_forget_element( CFF_Index  idx,
 517                            FT_Byte**  pbytes )
 518  {
 519    if ( idx->bytes == 0 )
 520    {
 521      FT_Stream  stream = idx->stream;
 522
 523
 524      FT_FRAME_RELEASE( *pbytes );
 525    }
 526  }
 527
 528
 529  FT_LOCAL_DEF( FT_String* )
 530  cff_index_get_name( CFF_Index  idx,
 531                      FT_UInt    element )
 532  {
 533    FT_Memory   memory = idx->stream->memory;
 534    FT_Byte*    bytes;
 535    FT_ULong    byte_len;
 536    FT_Error    error;
 537    FT_String*  name = 0;
 538
 539
 540    error = cff_index_access_element( idx, element, &bytes, &byte_len );
 541    if ( error )
 542      goto Exit;
 543
 544    if ( !FT_ALLOC( name, byte_len + 1 ) )
 545    {
 546      FT_MEM_COPY( name, bytes, byte_len );
 547      name[byte_len] = 0;
 548    }
 549    cff_index_forget_element( idx, &bytes );
 550
 551  Exit:
 552    return name;
 553  }
 554
 555
 556  FT_LOCAL_DEF( FT_String* )
 557  cff_index_get_sid_string( CFF_Index           idx,
 558                            FT_UInt             sid,
 559                            FT_Service_PsCMaps  psnames )
 560  {
 561    /* value 0xFFFFU indicates a missing dictionary entry */
 562    if ( sid == 0xFFFFU )
 563      return 0;
 564
 565    /* if it is not a standard string, return it */
 566    if ( sid > 390 )
 567      return cff_index_get_name( idx, sid - 391 );
 568
 569    /* CID-keyed CFF fonts don't have glyph names */
 570    if ( !psnames )
 571      return 0;
 572
 573    /* that's a standard string, fetch a copy from the PSName module */
 574    {
 575      FT_String*   name       = 0;
 576      const char*  adobe_name = psnames->adobe_std_strings( sid );
 577
 578
 579      if ( adobe_name )
 580      {
 581        FT_Memory  memory = idx->stream->memory;
 582        FT_Error   error;
 583
 584
 585        (void)FT_STRDUP( name, adobe_name );
 586
 587        FT_UNUSED( error );
 588      }
 589
 590      return name;
 591    }
 592  }
 593
 594
 595  /*************************************************************************/
 596  /*************************************************************************/
 597  /***                                                                   ***/
 598  /***   FD Select table support                                         ***/
 599  /***                                                                   ***/
 600  /*************************************************************************/
 601  /*************************************************************************/
 602
 603
 604  static void
 605  CFF_Done_FD_Select( CFF_FDSelect  fdselect,
 606                      FT_Stream     stream )
 607  {
 608    if ( fdselect->data )
 609      FT_FRAME_RELEASE( fdselect->data );
 610
 611    fdselect->data_size   = 0;
 612    fdselect->format      = 0;
 613    fdselect->range_count = 0;
 614  }
 615
 616
 617  static FT_Error
 618  CFF_Load_FD_Select( CFF_FDSelect  fdselect,
 619                      FT_UInt       num_glyphs,
 620                      FT_Stream     stream,
 621                      FT_ULong      offset )
 622  {
 623    FT_Error  error;
 624    FT_Byte   format;
 625    FT_UInt   num_ranges;
 626
 627
 628    /* read format */
 629    if ( FT_STREAM_SEEK( offset ) || FT_READ_BYTE( format ) )
 630      goto Exit;
 631
 632    fdselect->format      = format;
 633    fdselect->cache_count = 0;   /* clear cache */
 634
 635    switch ( format )
 636    {
 637    case 0:     /* format 0, that's simple */
 638      fdselect->data_size = num_glyphs;
 639      goto Load_Data;
 640
 641    case 3:     /* format 3, a tad more complex */
 642      if ( FT_READ_USHORT( num_ranges ) )
 643        goto Exit;
 644
 645      fdselect->data_size = num_ranges * 3 + 2;
 646
 647    Load_Data:
 648      if ( FT_FRAME_EXTRACT( fdselect->data_size, fdselect->data ) )
 649        goto Exit;
 650      break;
 651
 652    default:    /* hmm... that's wrong */
 653      error = CFF_Err_Invalid_File_Format;
 654    }
 655
 656  Exit:
 657    return error;
 658  }
 659
 660
 661  FT_LOCAL_DEF( FT_Byte )
 662  cff_fd_select_get( CFF_FDSelect  fdselect,
 663                     FT_UInt       glyph_index )
 664  {
 665    FT_Byte  fd = 0;
 666
 667
 668    switch ( fdselect->format )
 669    {
 670    case 0:
 671      fd = fdselect->data[glyph_index];
 672      break;
 673
 674    case 3:
 675      /* first, compare to cache */
 676      if ( (FT_UInt)( glyph_index - fdselect->cache_first ) <
 677                        fdselect->cache_count )
 678      {
 679        fd = fdselect->cache_fd;
 680        break;
 681      }
 682
 683      /* then, lookup the ranges array */
 684      {
 685        FT_Byte*  p       = fdselect->data;
 686        FT_Byte*  p_limit = p + fdselect->data_size;
 687        FT_Byte   fd2;
 688        FT_UInt   first, limit;
 689
 690
 691        first = FT_NEXT_USHORT( p );
 692        do
 693        {
 694          if ( glyph_index < first )
 695            break;
 696
 697          fd2   = *p++;
 698          limit = FT_NEXT_USHORT( p );
 699
 700          if ( glyph_index < limit )
 701          {
 702            fd = fd2;
 703
 704            /* update cache */
 705            fdselect->cache_first = first;
 706            fdselect->cache_count = limit-first;
 707            fdselect->cache_fd    = fd2;
 708            break;
 709          }
 710          first = limit;
 711
 712        } while ( p < p_limit );
 713      }
 714      break;
 715
 716    default:
 717      ;
 718    }
 719
 720    return fd;
 721  }
 722
 723
 724  /*************************************************************************/
 725  /*************************************************************************/
 726  /***                                                                   ***/
 727  /***   CFF font support                                                ***/
 728  /***                                                                   ***/
 729  /*************************************************************************/
 730  /*************************************************************************/
 731
 732  static FT_Error
 733  cff_charset_compute_cids( CFF_Charset  charset,
 734                            FT_UInt      num_glyphs,
 735                            FT_Memory    memory )
 736  {
 737    FT_Error   error   = FT_Err_Ok;
 738    FT_UInt    i;
 739    FT_Long    j;
 740    FT_UShort  max_cid = 0;
 741
 742
 743    if ( charset->max_cid > 0 )
 744      goto Exit;
 745
 746    for ( i = 0; i < num_glyphs; i++ )
 747      if ( charset->sids[i] > max_cid )
 748        max_cid = charset->sids[i];
 749    max_cid++;
 750
 751    if ( FT_NEW_ARRAY( charset->cids, max_cid ) )
 752      goto Exit;
 753
 754    /* When multiple GIDs map to the same CID, we choose the lowest */
 755    /* GID.  This is not described in any spec, but it matches the  */
 756    /* behaviour of recent Acroread versions.                       */
 757    for ( j = num_glyphs - 1; j >= 0 ; j-- )
 758      charset->cids[charset->sids[j]] = (FT_UShort)j;
 759
 760    charset->max_cid    = max_cid;
 761    charset->num_glyphs = num_glyphs;
 762
 763  Exit:
 764    return error;
 765  }
 766
 767
 768  FT_LOCAL_DEF( FT_UInt )
 769  cff_charset_cid_to_gindex( CFF_Charset  charset,
 770                             FT_UInt      cid )
 771  {
 772    FT_UInt  result = 0;
 773
 774
 775    if ( cid < charset->max_cid )
 776      result = charset->cids[cid];
 777
 778    return result;
 779  }
 780
 781
 782  static void
 783  cff_charset_free_cids( CFF_Charset  charset,
 784                         FT_Memory    memory )
 785  {
 786    FT_FREE( charset->cids );
 787    charset->max_cid = 0;
 788  }
 789
 790
 791  static void
 792  cff_charset_done( CFF_Charset  charset,
 793                    FT_Stream    stream )
 794  {
 795    FT_Memory  memory = stream->memory;
 796
 797
 798    cff_charset_free_cids( charset, memory );
 799
 800    FT_FREE( charset->sids );
 801    charset->format = 0;
 802    charset->offset = 0;
 803  }
 804
 805
 806  static FT_Error
 807  cff_charset_load( CFF_Charset  charset,
 808                    FT_UInt      num_glyphs,
 809                    FT_Stream    stream,
 810                    FT_ULong     base_offset,
 811                    FT_ULong     offset,
 812                    FT_Bool      invert )
 813  {
 814    FT_Memory  memory = stream->memory;
 815    FT_Error   error  = CFF_Err_Ok;
 816    FT_UShort  glyph_sid;
 817
 818
 819    /* If the the offset is greater than 2, we have to parse the */
 820    /* charset table.                                            */
 821    if ( offset > 2 )
 822    {
 823      FT_UInt  j;
 824
 825
 826      charset->offset = base_offset + offset;
 827
 828      /* Get the format of the table. */
 829      if ( FT_STREAM_SEEK( charset->offset ) ||
 830           FT_READ_BYTE( charset->format )   )
 831        goto Exit;
 832
 833      /* Allocate memory for sids. */
 834      if ( FT_NEW_ARRAY( charset->sids, num_glyphs ) )
 835        goto Exit;
 836
 837      /* assign the .notdef glyph */
 838      charset->sids[0] = 0;
 839
 840      switch ( charset->format )
 841      {
 842      case 0:
 843        if ( num_glyphs > 0 )
 844        {
 845          if ( FT_FRAME_ENTER( ( num_glyphs - 1 ) * 2 ) )
 846            goto Exit;
 847
 848          for ( j = 1; j < num_glyphs; j++ )
 849          {
 850            FT_UShort sid = FT_GET_USHORT();
 851
 852
 853            /* this constant is given in the CFF specification */
 854            if ( sid < 65000L )
 855              charset->sids[j] = sid;
 856            else
 857            {
 858              FT_TRACE0(( "cff_charset_load:"
 859                          " invalid SID value %d set to zero\n", sid ));
 860              charset->sids[j] = 0;
 861            }
 862          }
 863
 864          FT_FRAME_EXIT();
 865        }
 866        break;
 867
 868      case 1:
 869      case 2:
 870        {
 871          FT_UInt  nleft;
 872          FT_UInt  i;
 873
 874
 875          j = 1;
 876
 877          while ( j < num_glyphs )
 878          {
 879            /* Read the first glyph sid of the range. */
 880            if ( FT_READ_USHORT( glyph_sid ) )
 881              goto Exit;
 882
 883            /* Read the number of glyphs in the range.  */
 884            if ( charset->format == 2 )
 885            {
 886              if ( FT_READ_USHORT( nleft ) )
 887                goto Exit;
 888            }
 889            else
 890            {
 891              if ( FT_READ_BYTE( nleft ) )
 892                goto Exit;
 893            }
 894
 895            /* check whether the range contains at least one valid glyph; */
 896            /* the constant is given in the CFF specification             */
 897            if ( glyph_sid >= 65000L ) {
 898              FT_ERROR(( "cff_charset_load: invalid SID range\n" ));
 899              error = CFF_Err_Invalid_File_Format;
 900              goto Exit;
 901            }
 902
 903            /* try to rescue some of the SIDs if `nleft' is too large */
 904            if ( nleft > 65000L - 1L || glyph_sid >= 65000L - nleft ) {
 905              FT_ERROR(( "cff_charset_load: invalid SID range trimmed\n" ));
 906              nleft = ( FT_UInt )( 65000L - 1L - glyph_sid );
 907            }
 908
 909            /* Fill in the range of sids -- `nleft + 1' glyphs. */
 910            for ( i = 0; j < num_glyphs && i <= nleft; i++, j++, glyph_sid++ )
 911              charset->sids[j] = glyph_sid;
 912          }
 913        }
 914        break;
 915
 916      default:
 917        FT_ERROR(( "cff_charset_load: invalid table format\n" ));
 918        error = CFF_Err_Invalid_File_Format;
 919        goto Exit;
 920      }
 921    }
 922    else
 923    {
 924      /* Parse default tables corresponding to offset == 0, 1, or 2.  */
 925      /* CFF specification intimates the following:                   */
 926      /*                                                              */
 927      /* In order to use a predefined charset, the following must be  */
 928      /* true: The charset constructed for the glyphs in the font's   */
 929      /* charstrings dictionary must match the predefined charset in  */
 930      /* the first num_glyphs.                                        */
 931
 932      charset->offset = offset;  /* record charset type */
 933
 934      switch ( (FT_UInt)offset )
 935      {
 936      case 0:
 937        if ( num_glyphs > 229 )
 938        {
 939          FT_ERROR(( "cff_charset_load: implicit charset larger than\n"
 940                     "predefined charset (Adobe ISO-Latin)\n" ));
 941          error = CFF_Err_Invalid_File_Format;
 942          goto Exit;
 943        }
 944
 945        /* Allocate memory for sids. */
 946        if ( FT_NEW_ARRAY( charset->sids, num_glyphs ) )
 947          goto Exit;
 948
 949        /* Copy the predefined charset into the allocated memory. */
 950        FT_ARRAY_COPY( charset->sids, cff_isoadobe_charset, num_glyphs );
 951
 952        break;
 953
 954      case 1:
 955        if ( num_glyphs > 166 )
 956        {
 957          FT_ERROR(( "cff_charset_load: implicit charset larger than\n"
 958                     "predefined charset (Adobe Expert)\n" ));
 959          error = CFF_Err_Invalid_File_Format;
 960          goto Exit;
 961        }
 962
 963        /* Allocate memory for sids. */
 964        if ( FT_NEW_ARRAY( charset->sids, num_glyphs ) )
 965          goto Exit;
 966
 967        /* Copy the predefined charset into the allocated memory.     */
 968        FT_ARRAY_COPY( charset->sids, cff_expert_charset, num_glyphs );
 969
 970        break;
 971
 972      case 2:
 973        if ( num_glyphs > 87 )
 974        {
 975          FT_ERROR(( "cff_charset_load: implicit charset larger than\n"
 976                     "predefined charset (Adobe Expert Subset)\n" ));
 977          error = CFF_Err_Invalid_File_Format;
 978          goto Exit;
 979        }
 980
 981        /* Allocate memory for sids. */
 982        if ( FT_NEW_ARRAY( charset->sids, num_glyphs ) )
 983          goto Exit;
 984
 985        /* Copy the predefined charset into the allocated memory.     */
 986        FT_ARRAY_COPY( charset->sids, cff_expertsubset_charset, num_glyphs );
 987
 988        break;
 989
 990      default:
 991        error = CFF_Err_Invalid_File_Format;
 992        goto Exit;
 993      }
 994    }
 995
 996    /* we have to invert the `sids' array for subsetted CID-keyed fonts */
 997    if ( invert )
 998      error = cff_charset_compute_cids( charset, num_glyphs, memory );
 999
1000  Exit:
1001    /* Clean up if there was an error. */
1002    if ( error )
1003    {
1004      FT_FREE( charset->sids );
1005      FT_FREE( charset->cids );
1006      charset->format = 0;
1007      charset->offset = 0;
1008      charset->sids   = 0;
1009    }
1010
1011    return error;
1012  }
1013
1014
1015  static void
1016  cff_encoding_done( CFF_Encoding  encoding )
1017  {
1018    encoding->format = 0;
1019    encoding->offset = 0;
1020    encoding->count  = 0;
1021  }
1022
1023
1024  static FT_Error
1025  cff_encoding_load( CFF_Encoding  encoding,
1026                     CFF_Charset   charset,
1027                     FT_UInt       num_glyphs,
1028                     FT_Stream     stream,
1029                     FT_ULong      base_offset,
1030                     FT_ULong      offset )
1031  {
1032    FT_Error   error = CFF_Err_Ok;
1033    FT_UInt    count;
1034    FT_UInt    j;
1035    FT_UShort  glyph_sid;
1036    FT_UInt    glyph_code;
1037
1038
1039    /* Check for charset->sids.  If we do not have this, we fail. */
1040    if ( !charset->sids )
1041    {
1042      error = CFF_Err_Invalid_File_Format;
1043      goto Exit;
1044    }
1045
1046    /* Zero out the code to gid/sid mappings. */
1047    for ( j = 0; j < 256; j++ )
1048    {
1049      encoding->sids [j] = 0;
1050      encoding->codes[j] = 0;
1051    }
1052
1053    /* Note: The encoding table in a CFF font is indexed by glyph index;  */
1054    /* the first encoded glyph index is 1.  Hence, we read the character  */
1055    /* code (`glyph_code') at index j and make the assignment:            */
1056    /*                                                                    */
1057    /*    encoding->codes[glyph_code] = j + 1                             */
1058    /*                                                                    */
1059    /* We also make the assignment:                                       */
1060    /*                                                                    */
1061    /*    encoding->sids[glyph_code] = charset->sids[j + 1]               */
1062    /*                                                                    */
1063    /* This gives us both a code to GID and a code to SID mapping.        */
1064
1065    if ( offset > 1 )
1066    {
1067      encoding->offset = base_offset + offset;
1068
1069      /* we need to parse the table to determine its size */
1070      if ( FT_STREAM_SEEK( encoding->offset ) ||
1071           FT_READ_BYTE( encoding->format )   ||
1072           FT_READ_BYTE( count )              )
1073        goto Exit;
1074
1075      switch ( encoding->format & 0x7F )
1076      {
1077      case 0:
1078        {
1079          FT_Byte*  p;
1080
1081
1082          /* By convention, GID 0 is always ".notdef" and is never */
1083          /* coded in the font.  Hence, the number of codes found  */
1084          /* in the table is `count+1'.                            */
1085          /*                                                       */
1086          encoding->count = count + 1;
1087
1088          if ( FT_FRAME_ENTER( count ) )
1089            goto Exit;
1090
1091          p = (FT_Byte*)stream->cursor;
1092
1093          for ( j = 1; j <= count; j++ )
1094          {
1095            glyph_code = *p++;
1096
1097            /* Make sure j is not too big. */
1098            if ( j < num_glyphs )
1099            {
1100              /* Assign code to GID mapping. */
1101              encoding->codes[glyph_code] = (FT_UShort)j;
1102
1103              /* Assign code to SID mapping. */
1104              encoding->sids[glyph_code] = charset->sids[j];
1105            }
1106          }
1107
1108          FT_FRAME_EXIT();
1109        }
1110        break;
1111
1112      case 1:
1113        {
1114          FT_UInt  nleft;
1115          FT_UInt  i = 1;
1116          FT_UInt  k;
1117
1118
1119          encoding->count = 0;
1120
1121          /* Parse the Format1 ranges. */
1122          for ( j = 0;  j < count; j++, i += nleft )
1123          {
1124            /* Read the first glyph code of the range. */
1125            if ( FT_READ_BYTE( glyph_code ) )
1126              goto Exit;
1127
1128            /* Read the number of codes in the range. */
1129            if ( FT_READ_BYTE( nleft ) )
1130              goto Exit;
1131
1132            /* Increment nleft, so we read `nleft + 1' codes/sids. */
1133            nleft++;
1134
1135            /* compute max number of character codes */
1136            if ( (FT_UInt)nleft > encoding->count )
1137              encoding->count = nleft;
1138
1139            /* Fill in the range of codes/sids. */
1140            for ( k = i; k < nleft + i; k++, glyph_code++ )
1141            {
1142              /* Make sure k is not too big. */
1143              if ( k < num_glyphs && glyph_code < 256 )
1144              {
1145                /* Assign code to GID mapping. */
1146                encoding->codes[glyph_code] = (FT_UShort)k;
1147
1148                /* Assign code to SID mapping. */
1149                encoding->sids[glyph_code] = charset->sids[k];
1150              }
1151            }
1152          }
1153
1154          /* simple check; one never knows what can be found in a font */
1155          if ( encoding->count > 256 )
1156            encoding->count = 256;
1157        }
1158        break;
1159
1160      default:
1161        FT_ERROR(( "cff_encoding_load: invalid table format\n" ));
1162        error = CFF_Err_Invalid_File_Format;
1163        goto Exit;
1164      }
1165
1166      /* Parse supplemental encodings, if any. */
1167      if ( encoding->format & 0x80 )
1168      {
1169        FT_UInt  gindex;
1170
1171
1172        /* count supplements */
1173        if ( FT_READ_BYTE( count ) )
1174          goto Exit;
1175
1176        for ( j = 0; j < count; j++ )
1177        {
1178          /* Read supplemental glyph code. */
1179          if ( FT_READ_BYTE( glyph_code ) )
1180            goto Exit;
1181
1182          /* Read the SID associated with this glyph code. */
1183          if ( FT_READ_USHORT( glyph_sid ) )
1184            goto Exit;
1185
1186          /* Assign code to SID mapping. */
1187          encoding->sids[glyph_code] = glyph_sid;
1188
1189          /* First, look up GID which has been assigned to */
1190          /* SID glyph_sid.                                */
1191          for ( gindex = 0; gindex < num_glyphs; gindex++ )
1192          {
1193            if ( charset->sids[gindex] == glyph_sid )
1194            {
1195              encoding->codes[glyph_code] = (FT_UShort)gindex;
1196              break;
1197            }
1198          }
1199        }
1200      }
1201    }
1202    else
1203    {
1204      /* We take into account the fact a CFF font can use a predefined */
1205      /* encoding without containing all of the glyphs encoded by this */
1206      /* encoding (see the note at the end of section 12 in the CFF    */
1207      /* specification).                                               */
1208
1209      switch ( (FT_UInt)offset )
1210      {
1211      case 0:
1212        /* First, copy the code to SID mapping. */
1213        FT_ARRAY_COPY( encoding->sids, cff_standard_encoding, 256 );
1214        goto Populate;
1215
1216      case 1:
1217        /* First, copy the code to SID mapping. */
1218        FT_ARRAY_COPY( encoding->sids, cff_expert_encoding, 256 );
1219
1220      Populate:
1221        /* Construct code to GID mapping from code to SID mapping */
1222        /* and charset.                                           */
1223
1224        encoding->count = 0;
1225
1226        error = cff_charset_compute_cids( charset, num_glyphs,
1227                                          stream->memory );
1228        if ( error )
1229          goto Exit;
1230
1231        for ( j = 0; j < 256; j++ )
1232        {
1233          FT_UInt  sid = encoding->sids[j];
1234          FT_UInt  gid = 0;
1235
1236
1237          if ( sid )
1238            gid = cff_charset_cid_to_gindex( charset, sid );
1239
1240          if ( gid != 0 )
1241          {
1242            encoding->codes[j] = (FT_UShort)gid;
1243
1244            if ( encoding->count < j + 1 )
1245              encoding->count = j + 1;
1246          }
1247          else
1248          {
1249            encoding->codes[j] = 0;
1250            encoding->sids [j] = 0;
1251          }
1252        }
1253        break;
1254
1255      default:
1256        FT_ERROR(( "cff_encoding_load: invalid table format\n" ));
1257        error = CFF_Err_Invalid_File_Format;
1258        goto Exit;
1259      }
1260    }
1261
1262  Exit:
1263
1264    /* Clean up if there was an error. */
1265    return error;
1266  }
1267
1268
1269  static FT_Error
1270  cff_subfont_load( CFF_SubFont  font,
1271                    CFF_Index    idx,
1272                    FT_UInt      font_index,
1273                    FT_Stream    stream,
1274                    FT_ULong     base_offset,
1275                    FT_Library   library )
1276  {
1277    FT_Error         error;
1278    CFF_ParserRec    parser;
1279    FT_Byte*         dict = NULL;
1280    FT_ULong         dict_len;
1281    CFF_FontRecDict  top  = &font->font_dict;
1282    CFF_Private      priv = &font->private_dict;
1283
1284
1285    cff_parser_init( &parser, CFF_CODE_TOPDICT, &font->font_dict, library );
1286
1287    /* set defaults */
1288    FT_MEM_ZERO( top, sizeof ( *top ) );
1289
1290    top->underline_position  = -100L << 16;
1291    top->underline_thickness = 50L << 16;
1292    top->charstring_type     = 2;
1293    top->font_matrix.xx      = 0x10000L;
1294    top->font_matrix.yy      = 0x10000L;
1295    top->cid_count           = 8720;
1296
1297    /* we use the implementation specific SID value 0xFFFF to indicate */
1298    /* missing entries                                                 */
1299    top->version             = 0xFFFFU;
1300    top->notice              = 0xFFFFU;
1301    top->copyright           = 0xFFFFU;
1302    top->full_name           = 0xFFFFU;
1303    top->family_name         = 0xFFFFU;
1304    top->weight              = 0xFFFFU;
1305    top->embedded_postscript = 0xFFFFU;
1306
1307    top->cid_registry        = 0xFFFFU;
1308    top->cid_ordering        = 0xFFFFU;
1309    top->cid_font_name       = 0xFFFFU;
1310
1311    error = cff_index_access_element( idx, font_index, &dict, &dict_len );
1312    if ( !error )
1313      error = cff_parser_run( &parser, dict, dict + dict_len );
1314
1315    cff_index_forget_element( idx, &dict );
1316
1317    if ( error )
1318      goto Exit;
1319
1320    /* if it is a CID font, we stop there */
1321    if ( top->cid_registry != 0xFFFFU )
1322      goto Exit;
1323
1324    /* parse the private dictionary, if any */
1325    if ( top->private_offset && top->private_size )
1326    {
1327      /* set defaults */
1328      FT_MEM_ZERO( priv, sizeof ( *priv ) );
1329
1330      priv->blue_shift       = 7;
1331      priv->blue_fuzz        = 1;
1332      priv->lenIV            = -1;
1333      priv->expansion_factor = (FT_Fixed)( 0.06 * 0x10000L );
1334      priv->blue_scale       = (FT_Fixed)( 0.039625 * 0x10000L * 1000 );
1335
1336      cff_parser_init( &parser, CFF_CODE_PRIVATE, priv, library );
1337
1338      if ( FT_STREAM_SEEK( base_offset + font->font_dict.private_offset ) ||
1339           FT_FRAME_ENTER( font->font_dict.private_size )                 )
1340        goto Exit;
1341
1342      error = cff_parser_run( &parser,
1343                              (FT_Byte*)stream->cursor,
1344                              (FT_Byte*)stream->limit );
1345      FT_FRAME_EXIT();
1346      if ( error )
1347        goto Exit;
1348
1349      /* ensure that `num_blue_values' is even */
1350      priv->num_blue_values &= ~1;
1351    }
1352
1353    /* read the local subrs, if any */
1354    if ( priv->local_subrs_offset )
1355    {
1356      if ( FT_STREAM_SEEK( base_offset + top->private_offset +
1357                           priv->local_subrs_offset ) )
1358        goto Exit;
1359
1360      error = cff_index_init( &font->local_subrs_index, stream, 1 );
1361      if ( error )
1362        goto Exit;
1363
1364      font->num_local_subrs = font->local_subrs_index.count;
1365      error = cff_index_get_pointers( &font->local_subrs_index,
1366                                      &font->local_subrs );
1367      if ( error )
1368        goto Exit;
1369    }
1370
1371  Exit:
1372    return error;
1373  }
1374
1375
1376  static void
1377  cff_subfont_done( FT_Memory    memory,
1378                    CFF_SubFont  subfont )
1379  {
1380    if ( subfont )
1381    {
1382      cff_index_done( &subfont->local_subrs_index );
1383      FT_FREE( subfont->local_subrs );
1384    }
1385  }
1386
1387
1388  FT_LOCAL_DEF( FT_Error )
1389  cff_font_load( FT_Library library,
1390                 FT_Stream  stream,
1391                 FT_Int     face_index,
1392                 CFF_Font   font,
1393                 FT_Bool    pure_cff )
1394  {
1395    static const FT_Frame_Field  cff_header_fields[] =
1396    {
1397#undef  FT_STRUCTURE
1398#define FT_STRUCTURE  CFF_FontRec
1399
1400      FT_FRAME_START( 4 ),
1401        FT_FRAME_BYTE( version_major ),
1402        FT_FRAME_BYTE( version_minor ),
1403        FT_FRAME_BYTE( header_size ),
1404        FT_FRAME_BYTE( absolute_offsize ),
1405      FT_FRAME_END
1406    };
1407
1408    FT_Error         error;
1409    FT_Memory        memory = stream->memory;
1410    FT_ULong         base_offset;
1411    CFF_FontRecDict  dict;
1412
1413
1414    FT_ZERO( font );
1415
1416    font->stream = stream;
1417    font->memory = memory;
1418    dict         = &font->top_font.font_dict;
1419    base_offset  = FT_STREAM_POS();
1420
1421    /* read CFF font header */
1422    if ( FT_STREAM_READ_FIELDS( cff_header_fields, font ) )
1423      goto Exit;
1424
1425    /* check format */
1426    if ( font->version_major   != 1 ||
1427         font->header_size      < 4 ||
1428         font->absolute_offsize > 4 )
1429    {
1430      FT_TRACE2(( "[not a CFF font header]\n" ));
1431      error = CFF_Err_Unknown_File_Format;
1432      goto Exit;
1433    }
1434
1435    /* skip the rest of the header */
1436    if ( FT_STREAM_SKIP( font->header_size - 4 ) )
1437      goto Exit;
1438
1439    /* read the name, top dict, string and global subrs index */
1440    if ( FT_SET_ERROR( cff_index_init( &font->name_index,
1441                                       stream, 0 ) )              ||
1442         FT_SET_ERROR( cff_index_init( &font->font_dict_index,
1443                                       stream, 0 ) )              ||
1444         FT_SET_ERROR( cff_index_init( &font->string_index,
1445                                       stream, 0 ) )              ||
1446         FT_SET_ERROR( cff_index_init( &font->global_subrs_index,
1447                                       stream, 1 ) )              )
1448      goto Exit;
1449
1450    /* well, we don't really forget the `disabled' fonts... */
1451    font->num_faces = font->name_index.count;
1452    if ( face_index >= (FT_Int)font->num_faces )
1453    {
1454      FT_ERROR(( "cff_font_load: incorrect face index = %d\n",
1455                 face_index ));
1456      error = CFF_Err_Invalid_Argument;
1457    }
1458
1459    /* in case of a font format check, simply exit now */
1460    if ( face_index < 0 )
1461      goto Exit;
1462
1463    /* now, parse the top-level font dictionary */
1464    error = cff_subfont_load( &font->top_font,
1465                              &font->font_dict_index,
1466                              face_index,
1467                              stream,
1468                              base_offset,
1469                              library );
1470    if ( error )
1471      goto Exit;
1472
1473    if ( FT_STREAM_SEEK( base_offset + dict->charstrings_offset ) )
1474      goto Exit;
1475
1476    error = cff_index_init( &font->charstrings_index, stream, 0 );
1477    if ( error )
1478      goto Exit;
1479
1480    /* now, check for a CID font */
1481    if ( dict->cid_registry != 0xFFFFU )
1482    {
1483      CFF_IndexRec  fd_index;
1484      CFF_SubFont   sub;
1485      FT_UInt       idx;
1486
1487
1488      /* this is a CID-keyed font, we must now allocate a table of */
1489      /* sub-fonts, then load each of them separately              */
1490      if ( FT_STREAM_SEEK( base_offset + dict->cid_fd_array_offset ) )
1491        goto Exit;
1492
1493      error = cff_index_init( &fd_index, stream, 0 );
1494      if ( error )
1495        goto Exit;
1496
1497      if ( fd_index.count > CFF_MAX_CID_FONTS )
1498      {
1499        FT_TRACE0(( "cff_font_load: FD array too large in CID font\n" ));
1500        goto Fail_CID;
1501      }
1502
1503      /* allocate & read each font dict independently */
1504      font->num_subfonts = fd_index.count;
1505      if ( FT_NEW_ARRAY( sub, fd_index.count ) )
1506        goto Fail_CID;
1507
1508      /* set up pointer table */
1509      for ( idx = 0; idx < fd_index.count; idx++ )
1510        font->subfonts[idx] = sub + idx;
1511
1512      /* now load each subfont independently */
1513      for ( idx = 0; idx < fd_index.count; idx++ )
1514      {
1515        sub = font->subfonts[idx];
1516        error = cff_subfont_load( sub, &fd_index, idx,
1517                                  stream, base_offset, library );
1518        if ( error )
1519          goto Fail_CID;
1520      }
1521
1522      /* now load the FD Select array */
1523      error = CFF_Load_FD_Select( &font->fd_select,
1524                                  font->charstrings_index.count,
1525                                  stream,
1526                                  base_offset + dict->cid_fd_select_offset );
1527
1528    Fail_CID:
1529      cff_index_done( &fd_index );
1530
1531      if ( error )
1532        goto Exit;
1533    }
1534    else
1535      font->num_subfonts = 0;
1536
1537    /* read the charstrings index now */
1538    if ( dict->charstrings_offset == 0 )
1539    {
1540      FT_ERROR(( "cff_font_load: no charstrings offset\n" ));
1541      error = CFF_Err_Unknown_File_Format;
1542      goto Exit;
1543    }
1544
1545    /* explicit the global subrs */
1546    font->num_global_subrs = font->global_subrs_index.count;
1547    font->num_glyphs       = font->charstrings_index.count;
1548
1549    error = cff_index_get_pointers( &font->global_subrs_index,
1550                                    &font->global_subrs ) ;
1551
1552    if ( error )
1553      goto Exit;
1554
1555    /* read the Charset and Encoding tables if available */
1556    if ( font->num_glyphs > 0 )
1557    {
1558      FT_Bool  invert = FT_BOOL( dict->cid_registry != 0xFFFFU && pure_cff );
1559
1560
1561      error = cff_charset_load( &font->charset, font->num_glyphs, stream,
1562                                base_offset, dict->charset_offset, invert );
1563      if ( error )
1564        goto Exit;
1565
1566      /* CID-keyed CFFs don't have an encoding */
1567      if ( dict->cid_registry == 0xFFFFU )
1568      {
1569        error = cff_encoding_load( &font->encoding,
1570                                   &font->charset,
1571                                   font->num_glyphs,
1572                                   stream,
1573                                   base_offset,
1574                                   dict->encoding_offset );
1575        if ( error )
1576          goto Exit;
1577      }
1578    }
1579
1580    /* get the font name (/CIDFontName for CID-keyed fonts, */
1581    /* /FontName otherwise)                                 */
1582    font->font_name = cff_index_get_name( &font->name_index, face_index );
1583
1584  Exit:
1585    return error;
1586  }
1587
1588
1589  FT_LOCAL_DEF( void )
1590  cff_font_done( CFF_Font  font )
1591  {
1592    FT_Memory  memory = font->memory;
1593    FT_UInt    idx;
1594
1595
1596    cff_index_done( &font->global_subrs_index );
1597    cff_index_done( &font->string_index );
1598    cff_index_done( &font->font_dict_index );
1599    cff_index_done( &font->name_index );
1600    cff_index_done( &font->charstrings_index );
1601
1602    /* release font dictionaries, but only if working with */
1603    /* a CID keyed CFF font                                */
1604    if ( font->num_subfonts > 0 )
1605    {
1606      for ( idx = 0; idx < font->num_subfonts; idx++ )
1607        cff_subfont_done( memory, font->subfonts[idx] );
1608
1609      /* the subfonts array has been allocated as a single block */
1610      FT_FREE( font->subfonts[0] );
1611    }
1612
1613    cff_encoding_done( &font->encoding );
1614    cff_charset_done( &font->charset, font->stream );
1615
1616    cff_subfont_done( memory, &font->top_font );
1617
1618    CFF_Done_FD_Select( &font->fd_select, font->stream );
1619
1620    if (font->font_info != NULL)
1621    {
1622      FT_FREE( font->font_info->version );
1623      FT_FREE( font->font_info->notice );
1624      FT_FREE( font->font_info->full_name );
1625      FT_FREE( font->font_info->family_name );
1626      FT_FREE( font->font_info->weight );
1627      FT_FREE( font->font_info );
1628    }
1629
1630    FT_FREE( font->registry );
1631    FT_FREE( font->ordering );
1632
1633    FT_FREE( font->global_subrs );
1634    FT_FREE( font->font_name );
1635  }
1636
1637
1638/* END */