1 /****************************************************************************
   2  *
   3  * ttcmap.c
   4  *
   5  *   TrueType character mapping table (cmap) support (body).
   6  *
   7  * Copyright (C) 2002-2019 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 
  22 #include "sferrors.h"           /* must come before FT_INTERNAL_VALIDATE_H */
  23 
  24 #include FT_INTERNAL_VALIDATE_H
  25 #include FT_INTERNAL_STREAM_H
  26 #include FT_SERVICE_POSTSCRIPT_CMAPS_H
  27 #include "ttload.h"
  28 #include "ttcmap.h"
  29 #include "ttpost.h"
  30 
  31 
  32   /**************************************************************************
  33    *
  34    * The macro FT_COMPONENT is used in trace mode.  It is an implicit
  35    * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log
  36    * messages during execution.
  37    */
  38 #undef  FT_COMPONENT
  39 #define FT_COMPONENT  ttcmap
  40 
  41 
  42 #define TT_PEEK_SHORT   FT_PEEK_SHORT
  43 #define TT_PEEK_USHORT  FT_PEEK_USHORT
  44 #define TT_PEEK_UINT24  FT_PEEK_UOFF3
  45 #define TT_PEEK_LONG    FT_PEEK_LONG
  46 #define TT_PEEK_ULONG   FT_PEEK_ULONG
  47 
  48 #define TT_NEXT_SHORT   FT_NEXT_SHORT
  49 #define TT_NEXT_USHORT  FT_NEXT_USHORT
  50 #define TT_NEXT_UINT24  FT_NEXT_UOFF3
  51 #define TT_NEXT_LONG    FT_NEXT_LONG
  52 #define TT_NEXT_ULONG   FT_NEXT_ULONG
  53 
  54 
  55   /* Too large glyph index return values are caught in `FT_Get_Char_Index' */
  56   /* and `FT_Get_Next_Char' (the latter calls the internal `next' function */
  57   /* again in this case).  To mark character code return values as invalid */
  58   /* it is sufficient to set the corresponding glyph index return value to */
  59   /* zero.                                                                 */
  60 
  61 
  62   FT_CALLBACK_DEF( FT_Error )
  63   tt_cmap_init( TT_CMap   cmap,
  64                 FT_Byte*  table )
  65   {
  66     cmap->data = table;
  67     return FT_Err_Ok;
  68   }
  69 
  70 
  71   /*************************************************************************/
  72   /*************************************************************************/
  73   /*****                                                               *****/
  74   /*****                           FORMAT 0                            *****/
  75   /*****                                                               *****/
  76   /*************************************************************************/
  77   /*************************************************************************/
  78 
  79   /**************************************************************************
  80    *
  81    * TABLE OVERVIEW
  82    * --------------
  83    *
  84    *   NAME        OFFSET         TYPE          DESCRIPTION
  85    *
  86    *   format      0              USHORT        must be 0
  87    *   length      2              USHORT        table length in bytes
  88    *   language    4              USHORT        Mac language code
  89    *   glyph_ids   6              BYTE[256]     array of glyph indices
  90    *               262
  91    */
  92 
  93 #ifdef TT_CONFIG_CMAP_FORMAT_0
  94 
  95   FT_CALLBACK_DEF( FT_Error )
  96   tt_cmap0_validate( FT_Byte*      table,
  97                      FT_Validator  valid )
  98   {
  99     FT_Byte*  p;
 100     FT_UInt   length;
 101 
 102 
 103     if ( table + 2 + 2 > valid->limit )
 104       FT_INVALID_TOO_SHORT;
 105 
 106     p      = table + 2;           /* skip format */
 107     length = TT_NEXT_USHORT( p );
 108 
 109     if ( table + length > valid->limit || length < 262 )
 110       FT_INVALID_TOO_SHORT;
 111 
 112     /* check glyph indices whenever necessary */
 113     if ( valid->level >= FT_VALIDATE_TIGHT )
 114     {
 115       FT_UInt  n, idx;
 116 
 117 
 118       p = table + 6;
 119       for ( n = 0; n < 256; n++ )
 120       {
 121         idx = *p++;
 122         if ( idx >= TT_VALID_GLYPH_COUNT( valid ) )
 123           FT_INVALID_GLYPH_ID;
 124       }
 125     }
 126 
 127     return FT_Err_Ok;
 128   }
 129 
 130 
 131   FT_CALLBACK_DEF( FT_UInt )
 132   tt_cmap0_char_index( TT_CMap    cmap,
 133                        FT_UInt32  char_code )
 134   {
 135     FT_Byte*  table = cmap->data;
 136 
 137 
 138     return char_code < 256 ? table[6 + char_code] : 0;
 139   }
 140 
 141 
 142   FT_CALLBACK_DEF( FT_UInt32 )
 143   tt_cmap0_char_next( TT_CMap     cmap,
 144                       FT_UInt32  *pchar_code )
 145   {
 146     FT_Byte*   table    = cmap->data;
 147     FT_UInt32  charcode = *pchar_code;
 148     FT_UInt32  result   = 0;
 149     FT_UInt    gindex   = 0;
 150 
 151 
 152     table += 6;  /* go to glyph IDs */
 153     while ( ++charcode < 256 )
 154     {
 155       gindex = table[charcode];
 156       if ( gindex != 0 )
 157       {
 158         result = charcode;
 159         break;
 160       }
 161     }
 162 
 163     *pchar_code = result;
 164     return gindex;
 165   }
 166 
 167 
 168   FT_CALLBACK_DEF( FT_Error )
 169   tt_cmap0_get_info( TT_CMap       cmap,
 170                      TT_CMapInfo  *cmap_info )
 171   {
 172     FT_Byte*  p = cmap->data + 4;
 173 
 174 
 175     cmap_info->format   = 0;
 176     cmap_info->language = (FT_ULong)TT_PEEK_USHORT( p );
 177 
 178     return FT_Err_Ok;
 179   }
 180 
 181 
 182   FT_DEFINE_TT_CMAP(
 183     tt_cmap0_class_rec,
 184 
 185       sizeof ( TT_CMapRec ),
 186 
 187       (FT_CMap_InitFunc)     tt_cmap_init,         /* init       */
 188       (FT_CMap_DoneFunc)     NULL,                 /* done       */
 189       (FT_CMap_CharIndexFunc)tt_cmap0_char_index,  /* char_index */
 190       (FT_CMap_CharNextFunc) tt_cmap0_char_next,   /* char_next  */
 191 
 192       (FT_CMap_CharVarIndexFunc)    NULL,  /* char_var_index   */
 193       (FT_CMap_CharVarIsDefaultFunc)NULL,  /* char_var_default */
 194       (FT_CMap_VariantListFunc)     NULL,  /* variant_list     */
 195       (FT_CMap_CharVariantListFunc) NULL,  /* charvariant_list */
 196       (FT_CMap_VariantCharListFunc) NULL,  /* variantchar_list */
 197 
 198     0,
 199     (TT_CMap_ValidateFunc)tt_cmap0_validate,  /* validate      */
 200     (TT_CMap_Info_GetFunc)tt_cmap0_get_info   /* get_cmap_info */
 201   )
 202 
 203 #endif /* TT_CONFIG_CMAP_FORMAT_0 */
 204 
 205 
 206   /*************************************************************************/
 207   /*************************************************************************/
 208   /*****                                                               *****/
 209   /*****                          FORMAT 2                             *****/
 210   /*****                                                               *****/
 211   /***** This is used for certain CJK encodings that encode text in a  *****/
 212   /***** mixed 8/16 bits encoding along the following lines.           *****/
 213   /*****                                                               *****/
 214   /***** * Certain byte values correspond to an 8-bit character code   *****/
 215   /*****   (typically in the range 0..127 for ASCII compatibility).    *****/
 216   /*****                                                               *****/
 217   /***** * Certain byte values signal the first byte of a 2-byte       *****/
 218   /*****   character code (but these values are also valid as the      *****/
 219   /*****   second byte of a 2-byte character).                         *****/
 220   /*****                                                               *****/
 221   /***** The following charmap lookup and iteration functions all      *****/
 222   /***** assume that the value `charcode' fulfills the following.      *****/
 223   /*****                                                               *****/
 224   /*****   - For one-byte characters, `charcode' is simply the         *****/
 225   /*****     character code.                                           *****/
 226   /*****                                                               *****/
 227   /*****   - For two-byte characters, `charcode' is the 2-byte         *****/
 228   /*****     character code in big endian format.  More precisely:     *****/
 229   /*****                                                               *****/
 230   /*****       (charcode >> 8)    is the first byte value              *****/
 231   /*****       (charcode & 0xFF)  is the second byte value             *****/
 232   /*****                                                               *****/
 233   /***** Note that not all values of `charcode' are valid according    *****/
 234   /***** to these rules, and the function moderately checks the        *****/
 235   /***** arguments.                                                    *****/
 236   /*****                                                               *****/
 237   /*************************************************************************/
 238   /*************************************************************************/
 239 
 240   /**************************************************************************
 241    *
 242    * TABLE OVERVIEW
 243    * --------------
 244    *
 245    *   NAME        OFFSET         TYPE            DESCRIPTION
 246    *
 247    *   format      0              USHORT          must be 2
 248    *   length      2              USHORT          table length in bytes
 249    *   language    4              USHORT          Mac language code
 250    *   keys        6              USHORT[256]     sub-header keys
 251    *   subs        518            SUBHEAD[NSUBS]  sub-headers array
 252    *   glyph_ids   518+NSUB*8     USHORT[]        glyph ID array
 253    *
 254    * The `keys' table is used to map charcode high bytes to sub-headers.
 255    * The value of `NSUBS' is the number of sub-headers defined in the
 256    * table and is computed by finding the maximum of the `keys' table.
 257    *
 258    * Note that for any `n', `keys[n]' is a byte offset within the `subs'
 259    * table, i.e., it is the corresponding sub-header index multiplied
 260    * by 8.
 261    *
 262    * Each sub-header has the following format.
 263    *
 264    *   NAME        OFFSET      TYPE            DESCRIPTION
 265    *
 266    *   first       0           USHORT          first valid low-byte
 267    *   count       2           USHORT          number of valid low-bytes
 268    *   delta       4           SHORT           see below
 269    *   offset      6           USHORT          see below
 270    *
 271    * A sub-header defines, for each high byte, the range of valid
 272    * low bytes within the charmap.  Note that the range defined by `first'
 273    * and `count' must be completely included in the interval [0..255]
 274    * according to the specification.
 275    *
 276    * If a character code is contained within a given sub-header, then
 277    * mapping it to a glyph index is done as follows.
 278    *
 279    * - The value of `offset' is read.  This is a _byte_ distance from the
 280    *   location of the `offset' field itself into a slice of the
 281    *   `glyph_ids' table.  Let's call it `slice' (it is a USHORT[], too).
 282    *
 283    * - The value `slice[char.lo - first]' is read.  If it is 0, there is
 284    *   no glyph for the charcode.  Otherwise, the value of `delta' is
 285    *   added to it (modulo 65536) to form a new glyph index.
 286    *
 287    * It is up to the validation routine to check that all offsets fall
 288    * within the glyph IDs table (and not within the `subs' table itself or
 289    * outside of the CMap).
 290    */
 291 
 292 #ifdef TT_CONFIG_CMAP_FORMAT_2
 293 
 294   FT_CALLBACK_DEF( FT_Error )
 295   tt_cmap2_validate( FT_Byte*      table,
 296                      FT_Validator  valid )
 297   {
 298     FT_Byte*  p;
 299     FT_UInt   length;
 300 
 301     FT_UInt   n, max_subs;
 302     FT_Byte*  keys;        /* keys table     */
 303     FT_Byte*  subs;        /* sub-headers    */
 304     FT_Byte*  glyph_ids;   /* glyph ID array */
 305 
 306 
 307     if ( table + 2 + 2 > valid->limit )
 308       FT_INVALID_TOO_SHORT;
 309 
 310     p      = table + 2;           /* skip format */
 311     length = TT_NEXT_USHORT( p );
 312 
 313     if ( table + length > valid->limit || length < 6 + 512 )
 314       FT_INVALID_TOO_SHORT;
 315 
 316     keys = table + 6;
 317 
 318     /* parse keys to compute sub-headers count */
 319     p        = keys;
 320     max_subs = 0;
 321     for ( n = 0; n < 256; n++ )
 322     {
 323       FT_UInt  idx = TT_NEXT_USHORT( p );
 324 
 325 
 326       /* value must be multiple of 8 */
 327       if ( valid->level >= FT_VALIDATE_PARANOID && ( idx & 7 ) != 0 )
 328         FT_INVALID_DATA;
 329 
 330       idx >>= 3;
 331 
 332       if ( idx > max_subs )
 333         max_subs = idx;
 334     }
 335 
 336     FT_ASSERT( p == table + 518 );
 337 
 338     subs      = p;
 339     glyph_ids = subs + ( max_subs + 1 ) * 8;
 340     if ( glyph_ids > valid->limit )
 341       FT_INVALID_TOO_SHORT;
 342 
 343     /* parse sub-headers */
 344     for ( n = 0; n <= max_subs; n++ )
 345     {
 346       FT_UInt  first_code, code_count, offset;
 347       FT_Int   delta;
 348 
 349 
 350       first_code = TT_NEXT_USHORT( p );
 351       code_count = TT_NEXT_USHORT( p );
 352       delta      = TT_NEXT_SHORT( p );
 353       offset     = TT_NEXT_USHORT( p );
 354 
 355       /* many Dynalab fonts have empty sub-headers */
 356       if ( code_count == 0 )
 357         continue;
 358 
 359       /* check range within 0..255 */
 360       if ( valid->level >= FT_VALIDATE_PARANOID )
 361       {
 362         if ( first_code >= 256 || code_count > 256 - first_code )
 363           FT_INVALID_DATA;
 364       }
 365 
 366       /* check offset */
 367       if ( offset != 0 )
 368       {
 369         FT_Byte*  ids;
 370 
 371 
 372         ids = p - 2 + offset;
 373         if ( ids < glyph_ids || ids + code_count * 2 > table + length )
 374           FT_INVALID_OFFSET;
 375 
 376         /* check glyph IDs */
 377         if ( valid->level >= FT_VALIDATE_TIGHT )
 378         {
 379           FT_Byte*  limit = p + code_count * 2;
 380           FT_UInt   idx;
 381 
 382 
 383           for ( ; p < limit; )
 384           {
 385             idx = TT_NEXT_USHORT( p );
 386             if ( idx != 0 )
 387             {
 388               idx = (FT_UInt)( (FT_Int)idx + delta ) & 0xFFFFU;
 389               if ( idx >= TT_VALID_GLYPH_COUNT( valid ) )
 390                 FT_INVALID_GLYPH_ID;
 391             }
 392           }
 393         }
 394       }
 395     }
 396 
 397     return FT_Err_Ok;
 398   }
 399 
 400 
 401   /* return sub header corresponding to a given character code */
 402   /* NULL on invalid charcode                                  */
 403   static FT_Byte*
 404   tt_cmap2_get_subheader( FT_Byte*   table,
 405                           FT_UInt32  char_code )
 406   {
 407     FT_Byte*  result = NULL;
 408 
 409 
 410     if ( char_code < 0x10000UL )
 411     {
 412       FT_UInt   char_lo = (FT_UInt)( char_code & 0xFF );
 413       FT_UInt   char_hi = (FT_UInt)( char_code >> 8 );
 414       FT_Byte*  p       = table + 6;    /* keys table       */
 415       FT_Byte*  subs    = table + 518;  /* subheaders table */
 416       FT_Byte*  sub;
 417 
 418 
 419       if ( char_hi == 0 )
 420       {
 421         /* an 8-bit character code -- we use subHeader 0 in this case */
 422         /* to test whether the character code is in the charmap       */
 423         /*                                                            */
 424         sub = subs;  /* jump to first sub-header */
 425 
 426         /* check that the sub-header for this byte is 0, which */
 427         /* indicates that it is really a valid one-byte value; */
 428         /* otherwise, return 0                                 */
 429         /*                                                     */
 430         p += char_lo * 2;
 431         if ( TT_PEEK_USHORT( p ) != 0 )
 432           goto Exit;
 433       }
 434       else
 435       {
 436         /* a 16-bit character code */
 437 
 438         /* jump to key entry  */
 439         p  += char_hi * 2;
 440         /* jump to sub-header */
 441         sub = subs + ( FT_PAD_FLOOR( TT_PEEK_USHORT( p ), 8 ) );
 442 
 443         /* check that the high byte isn't a valid one-byte value */
 444         if ( sub == subs )
 445           goto Exit;
 446       }
 447 
 448       result = sub;
 449     }
 450 
 451   Exit:
 452     return result;
 453   }
 454 
 455 
 456   FT_CALLBACK_DEF( FT_UInt )
 457   tt_cmap2_char_index( TT_CMap    cmap,
 458                        FT_UInt32  char_code )
 459   {
 460     FT_Byte*  table   = cmap->data;
 461     FT_UInt   result  = 0;
 462     FT_Byte*  subheader;
 463 
 464 
 465     subheader = tt_cmap2_get_subheader( table, char_code );
 466     if ( subheader )
 467     {
 468       FT_Byte*  p   = subheader;
 469       FT_UInt   idx = (FT_UInt)(char_code & 0xFF);
 470       FT_UInt   start, count;
 471       FT_Int    delta;
 472       FT_UInt   offset;
 473 
 474 
 475       start  = TT_NEXT_USHORT( p );
 476       count  = TT_NEXT_USHORT( p );
 477       delta  = TT_NEXT_SHORT ( p );
 478       offset = TT_PEEK_USHORT( p );
 479 
 480       idx -= start;
 481       if ( idx < count && offset != 0 )
 482       {
 483         p  += offset + 2 * idx;
 484         idx = TT_PEEK_USHORT( p );
 485 
 486         if ( idx != 0 )
 487           result = (FT_UInt)( (FT_Int)idx + delta ) & 0xFFFFU;
 488       }
 489     }
 490 
 491     return result;
 492   }
 493 
 494 
 495   FT_CALLBACK_DEF( FT_UInt32 )
 496   tt_cmap2_char_next( TT_CMap     cmap,
 497                       FT_UInt32  *pcharcode )
 498   {
 499     FT_Byte*   table    = cmap->data;
 500     FT_UInt    gindex   = 0;
 501     FT_UInt32  result   = 0;
 502     FT_UInt32  charcode = *pcharcode + 1;
 503     FT_Byte*   subheader;
 504 
 505 
 506     while ( charcode < 0x10000UL )
 507     {
 508       subheader = tt_cmap2_get_subheader( table, charcode );
 509       if ( subheader )
 510       {
 511         FT_Byte*  p       = subheader;
 512         FT_UInt   start   = TT_NEXT_USHORT( p );
 513         FT_UInt   count   = TT_NEXT_USHORT( p );
 514         FT_Int    delta   = TT_NEXT_SHORT ( p );
 515         FT_UInt   offset  = TT_PEEK_USHORT( p );
 516         FT_UInt   char_lo = (FT_UInt)( charcode & 0xFF );
 517         FT_UInt   pos, idx;
 518 
 519 
 520         if ( char_lo >= start + count && charcode <= 0xFF )
 521         {
 522           /* this happens only for a malformed cmap */
 523           charcode = 0x100;
 524           continue;
 525         }
 526 
 527         if ( offset == 0 )
 528         {
 529           if ( charcode == 0x100 )
 530             goto Exit; /* this happens only for a malformed cmap */
 531           goto Next_SubHeader;
 532         }
 533 
 534         if ( char_lo < start )
 535         {
 536           char_lo = start;
 537           pos     = 0;
 538         }
 539         else
 540           pos = (FT_UInt)( char_lo - start );
 541 
 542         p       += offset + pos * 2;
 543         charcode = FT_PAD_FLOOR( charcode, 256 ) + char_lo;
 544 
 545         for ( ; pos < count; pos++, charcode++ )
 546         {
 547           idx = TT_NEXT_USHORT( p );
 548 
 549           if ( idx != 0 )
 550           {
 551             gindex = (FT_UInt)( (FT_Int)idx + delta ) & 0xFFFFU;
 552             if ( gindex != 0 )
 553             {
 554               result = charcode;
 555               goto Exit;
 556             }
 557           }
 558         }
 559 
 560         /* if unsuccessful, avoid `charcode' leaving */
 561         /* the current 256-character block           */
 562         if ( count )
 563           charcode--;
 564       }
 565 
 566       /* If `charcode' is <= 0xFF, retry with `charcode + 1'.      */
 567       /* Otherwise jump to the next 256-character block and retry. */
 568     Next_SubHeader:
 569       if ( charcode <= 0xFF )
 570         charcode++;
 571       else
 572         charcode = FT_PAD_FLOOR( charcode, 0x100 ) + 0x100;
 573     }
 574 
 575   Exit:
 576     *pcharcode = result;
 577 
 578     return gindex;
 579   }
 580 
 581 
 582   FT_CALLBACK_DEF( FT_Error )
 583   tt_cmap2_get_info( TT_CMap       cmap,
 584                      TT_CMapInfo  *cmap_info )
 585   {
 586     FT_Byte*  p = cmap->data + 4;
 587 
 588 
 589     cmap_info->format   = 2;
 590     cmap_info->language = (FT_ULong)TT_PEEK_USHORT( p );
 591 
 592     return FT_Err_Ok;
 593   }
 594 
 595 
 596   FT_DEFINE_TT_CMAP(
 597     tt_cmap2_class_rec,
 598 
 599       sizeof ( TT_CMapRec ),
 600 
 601       (FT_CMap_InitFunc)     tt_cmap_init,         /* init       */
 602       (FT_CMap_DoneFunc)     NULL,                 /* done       */
 603       (FT_CMap_CharIndexFunc)tt_cmap2_char_index,  /* char_index */
 604       (FT_CMap_CharNextFunc) tt_cmap2_char_next,   /* char_next  */
 605 
 606       (FT_CMap_CharVarIndexFunc)    NULL,  /* char_var_index   */
 607       (FT_CMap_CharVarIsDefaultFunc)NULL,  /* char_var_default */
 608       (FT_CMap_VariantListFunc)     NULL,  /* variant_list     */
 609       (FT_CMap_CharVariantListFunc) NULL,  /* charvariant_list */
 610       (FT_CMap_VariantCharListFunc) NULL,  /* variantchar_list */
 611 
 612     2,
 613     (TT_CMap_ValidateFunc)tt_cmap2_validate,  /* validate      */
 614     (TT_CMap_Info_GetFunc)tt_cmap2_get_info   /* get_cmap_info */
 615   )
 616 
 617 #endif /* TT_CONFIG_CMAP_FORMAT_2 */
 618 
 619 
 620   /*************************************************************************/
 621   /*************************************************************************/
 622   /*****                                                               *****/
 623   /*****                           FORMAT 4                            *****/
 624   /*****                                                               *****/
 625   /*************************************************************************/
 626   /*************************************************************************/
 627 
 628   /**************************************************************************
 629    *
 630    * TABLE OVERVIEW
 631    * --------------
 632    *
 633    *   NAME          OFFSET         TYPE              DESCRIPTION
 634    *
 635    *   format        0              USHORT            must be 4
 636    *   length        2              USHORT            table length
 637    *                                                  in bytes
 638    *   language      4              USHORT            Mac language code
 639    *
 640    *   segCountX2    6              USHORT            2*NUM_SEGS
 641    *   searchRange   8              USHORT            2*(1 << LOG_SEGS)
 642    *   entrySelector 10             USHORT            LOG_SEGS
 643    *   rangeShift    12             USHORT            segCountX2 -
 644    *                                                    searchRange
 645    *
 646    *   endCount      14             USHORT[NUM_SEGS]  end charcode for
 647    *                                                  each segment; last
 648    *                                                  is 0xFFFF
 649    *
 650    *   pad           14+NUM_SEGS*2  USHORT            padding
 651    *
 652    *   startCount    16+NUM_SEGS*2  USHORT[NUM_SEGS]  first charcode for
 653    *                                                  each segment
 654    *
 655    *   idDelta       16+NUM_SEGS*4  SHORT[NUM_SEGS]   delta for each
 656    *                                                  segment
 657    *   idOffset      16+NUM_SEGS*6  SHORT[NUM_SEGS]   range offset for
 658    *                                                  each segment; can be
 659    *                                                  zero
 660    *
 661    *   glyphIds      16+NUM_SEGS*8  USHORT[]          array of glyph ID
 662    *                                                  ranges
 663    *
 664    * Character codes are modelled by a series of ordered (increasing)
 665    * intervals called segments.  Each segment has start and end codes,
 666    * provided by the `startCount' and `endCount' arrays.  Segments must
 667    * not overlap, and the last segment should always contain the value
 668    * 0xFFFF for `endCount'.
 669    *
 670    * The fields `searchRange', `entrySelector' and `rangeShift' are better
 671    * ignored (they are traces of over-engineering in the TrueType
 672    * specification).
 673    *
 674    * Each segment also has a signed `delta', as well as an optional offset
 675    * within the `glyphIds' table.
 676    *
 677    * If a segment's idOffset is 0, the glyph index corresponding to any
 678    * charcode within the segment is obtained by adding the value of
 679    * `idDelta' directly to the charcode, modulo 65536.
 680    *
 681    * Otherwise, a glyph index is taken from the glyph IDs sub-array for
 682    * the segment, and the value of `idDelta' is added to it.
 683    *
 684    *
 685    * Finally, note that a lot of fonts contain an invalid last segment,
 686    * where `start' and `end' are correctly set to 0xFFFF but both `delta'
 687    * and `offset' are incorrect (e.g., `opens___.ttf' which comes with
 688    * OpenOffice.org).  We need special code to deal with them correctly.
 689    */
 690 
 691 #ifdef TT_CONFIG_CMAP_FORMAT_4
 692 
 693   typedef struct  TT_CMap4Rec_
 694   {
 695     TT_CMapRec  cmap;
 696     FT_UInt32   cur_charcode;   /* current charcode */
 697     FT_UInt     cur_gindex;     /* current glyph index */
 698 
 699     FT_UInt     num_ranges;
 700     FT_UInt     cur_range;
 701     FT_UInt     cur_start;
 702     FT_UInt     cur_end;
 703     FT_Int      cur_delta;
 704     FT_Byte*    cur_values;
 705 
 706   } TT_CMap4Rec, *TT_CMap4;
 707 
 708 
 709   FT_CALLBACK_DEF( FT_Error )
 710   tt_cmap4_init( TT_CMap4  cmap,
 711                  FT_Byte*  table )
 712   {
 713     FT_Byte*  p;
 714 
 715 
 716     cmap->cmap.data    = table;
 717 
 718     p                  = table + 6;
 719     cmap->num_ranges   = FT_PEEK_USHORT( p ) >> 1;
 720     cmap->cur_charcode = (FT_UInt32)0xFFFFFFFFUL;
 721     cmap->cur_gindex   = 0;
 722 
 723     return FT_Err_Ok;
 724   }
 725 
 726 
 727   static FT_Int
 728   tt_cmap4_set_range( TT_CMap4  cmap,
 729                       FT_UInt   range_index )
 730   {
 731     FT_Byte*  table = cmap->cmap.data;
 732     FT_Byte*  p;
 733     FT_UInt   num_ranges = cmap->num_ranges;
 734 
 735 
 736     while ( range_index < num_ranges )
 737     {
 738       FT_UInt  offset;
 739 
 740 
 741       p             = table + 14 + range_index * 2;
 742       cmap->cur_end = FT_PEEK_USHORT( p );
 743 
 744       p              += 2 + num_ranges * 2;
 745       cmap->cur_start = FT_PEEK_USHORT( p );
 746 
 747       p              += num_ranges * 2;
 748       cmap->cur_delta = FT_PEEK_SHORT( p );
 749 
 750       p     += num_ranges * 2;
 751       offset = FT_PEEK_USHORT( p );
 752 
 753       /* some fonts have an incorrect last segment; */
 754       /* we have to catch it                        */
 755       if ( range_index     >= num_ranges - 1 &&
 756            cmap->cur_start == 0xFFFFU        &&
 757            cmap->cur_end   == 0xFFFFU        )
 758       {
 759         TT_Face   face  = (TT_Face)cmap->cmap.cmap.charmap.face;
 760         FT_Byte*  limit = face->cmap_table + face->cmap_size;
 761 
 762 
 763         if ( offset && p + offset + 2 > limit )
 764         {
 765           cmap->cur_delta = 1;
 766           offset          = 0;
 767         }
 768       }
 769 
 770       if ( offset != 0xFFFFU )
 771       {
 772         cmap->cur_values = offset ? p + offset : NULL;
 773         cmap->cur_range  = range_index;
 774         return 0;
 775       }
 776 
 777       /* we skip empty segments */
 778       range_index++;
 779     }
 780 
 781     return -1;
 782   }
 783 
 784 
 785   /* search the index of the charcode next to cmap->cur_charcode; */
 786   /* caller should call tt_cmap4_set_range with proper range      */
 787   /* before calling this function                                 */
 788   /*                                                              */
 789   static void
 790   tt_cmap4_next( TT_CMap4  cmap )
 791   {
 792     TT_Face   face  = (TT_Face)cmap->cmap.cmap.charmap.face;
 793     FT_Byte*  limit = face->cmap_table + face->cmap_size;
 794 
 795     FT_UInt  charcode;
 796 
 797 
 798     if ( cmap->cur_charcode >= 0xFFFFUL )
 799       goto Fail;
 800 
 801     charcode = (FT_UInt)cmap->cur_charcode + 1;
 802 
 803     if ( charcode < cmap->cur_start )
 804       charcode = cmap->cur_start;
 805 
 806     for (;;)
 807     {
 808       FT_Byte*  values = cmap->cur_values;
 809       FT_UInt   end    = cmap->cur_end;
 810       FT_Int    delta  = cmap->cur_delta;
 811 
 812 
 813       if ( charcode <= end )
 814       {
 815         if ( values )
 816         {
 817           FT_Byte*  p = values + 2 * ( charcode - cmap->cur_start );
 818 
 819 
 820           /* if p > limit, the whole segment is invalid */
 821           if ( p > limit )
 822             goto Next_Segment;
 823 
 824           do
 825           {
 826             FT_UInt  gindex = FT_NEXT_USHORT( p );
 827 
 828 
 829             if ( gindex )
 830             {
 831               gindex = (FT_UInt)( (FT_Int)gindex + delta ) & 0xFFFFU;
 832               if ( gindex )
 833               {
 834                 cmap->cur_charcode = charcode;
 835                 cmap->cur_gindex   = gindex;
 836                 return;
 837               }
 838             }
 839           } while ( ++charcode <= end );
 840         }
 841         else
 842         {
 843           do
 844           {
 845             FT_UInt  gindex = (FT_UInt)( (FT_Int)charcode + delta ) & 0xFFFFU;
 846 
 847 
 848             if ( gindex >= (FT_UInt)face->root.num_glyphs )
 849             {
 850               /* we have an invalid glyph index; if there is an overflow, */
 851               /* we can adjust `charcode', otherwise the whole segment is */
 852               /* invalid                                                  */
 853               gindex = 0;
 854 
 855               if ( (FT_Int)charcode + delta < 0 &&
 856                    (FT_Int)end + delta >= 0     )
 857                 charcode = (FT_UInt)( -delta );
 858 
 859               else if ( (FT_Int)charcode + delta < 0x10000L &&
 860                         (FT_Int)end + delta >= 0x10000L     )
 861                 charcode = (FT_UInt)( 0x10000L - delta );
 862 
 863               else
 864                 goto Next_Segment;
 865             }
 866 
 867             if ( gindex )
 868             {
 869               cmap->cur_charcode = charcode;
 870               cmap->cur_gindex   = gindex;
 871               return;
 872             }
 873           } while ( ++charcode <= end );
 874         }
 875       }
 876 
 877     Next_Segment:
 878       /* we need to find another range */
 879       if ( tt_cmap4_set_range( cmap, cmap->cur_range + 1 ) < 0 )
 880         break;
 881 
 882       if ( charcode < cmap->cur_start )
 883         charcode = cmap->cur_start;
 884     }
 885 
 886   Fail:
 887     cmap->cur_charcode = (FT_UInt32)0xFFFFFFFFUL;
 888     cmap->cur_gindex   = 0;
 889   }
 890 
 891 
 892   FT_CALLBACK_DEF( FT_Error )
 893   tt_cmap4_validate( FT_Byte*      table,
 894                      FT_Validator  valid )
 895   {
 896     FT_Byte*  p;
 897     FT_UInt   length;
 898 
 899     FT_Byte   *ends, *starts, *offsets, *deltas, *glyph_ids;
 900     FT_UInt   num_segs;
 901     FT_Error  error = FT_Err_Ok;
 902 
 903 
 904     if ( table + 2 + 2 > valid->limit )
 905       FT_INVALID_TOO_SHORT;
 906 
 907     p      = table + 2;           /* skip format */
 908     length = TT_NEXT_USHORT( p );
 909 
 910     /* in certain fonts, the `length' field is invalid and goes */
 911     /* out of bound.  We try to correct this here...            */
 912     if ( table + length > valid->limit )
 913     {
 914       if ( valid->level >= FT_VALIDATE_TIGHT )
 915         FT_INVALID_TOO_SHORT;
 916 
 917       length = (FT_UInt)( valid->limit - table );
 918     }
 919 
 920     if ( length < 16 )
 921       FT_INVALID_TOO_SHORT;
 922 
 923     p        = table + 6;
 924     num_segs = TT_NEXT_USHORT( p );   /* read segCountX2 */
 925 
 926     if ( valid->level >= FT_VALIDATE_PARANOID )
 927     {
 928       /* check that we have an even value here */
 929       if ( num_segs & 1 )
 930         FT_INVALID_DATA;
 931     }
 932 
 933     num_segs /= 2;
 934 
 935     if ( length < 16 + num_segs * 2 * 4 )
 936       FT_INVALID_TOO_SHORT;
 937 
 938     /* check the search parameters - even though we never use them */
 939     /*                                                             */
 940     if ( valid->level >= FT_VALIDATE_PARANOID )
 941     {
 942       /* check the values of `searchRange', `entrySelector', `rangeShift' */
 943       FT_UInt  search_range   = TT_NEXT_USHORT( p );
 944       FT_UInt  entry_selector = TT_NEXT_USHORT( p );
 945       FT_UInt  range_shift    = TT_NEXT_USHORT( p );
 946 
 947 
 948       if ( ( search_range | range_shift ) & 1 )  /* must be even values */
 949         FT_INVALID_DATA;
 950 
 951       search_range /= 2;
 952       range_shift  /= 2;
 953 
 954       /* `search range' is the greatest power of 2 that is <= num_segs */
 955 
 956       if ( search_range                > num_segs                 ||
 957            search_range * 2            < num_segs                 ||
 958            search_range + range_shift != num_segs                 ||
 959            search_range               != ( 1U << entry_selector ) )
 960         FT_INVALID_DATA;
 961     }
 962 
 963     ends      = table   + 14;
 964     starts    = table   + 16 + num_segs * 2;
 965     deltas    = starts  + num_segs * 2;
 966     offsets   = deltas  + num_segs * 2;
 967     glyph_ids = offsets + num_segs * 2;
 968 
 969     /* check last segment; its end count value must be 0xFFFF */
 970     if ( valid->level >= FT_VALIDATE_PARANOID )
 971     {
 972       p = ends + ( num_segs - 1 ) * 2;
 973       if ( TT_PEEK_USHORT( p ) != 0xFFFFU )
 974         FT_INVALID_DATA;
 975     }
 976 
 977     {
 978       FT_UInt   start, end, offset, n;
 979       FT_UInt   last_start = 0, last_end = 0;
 980       FT_Int    delta;
 981       FT_Byte*  p_start   = starts;
 982       FT_Byte*  p_end     = ends;
 983       FT_Byte*  p_delta   = deltas;
 984       FT_Byte*  p_offset  = offsets;
 985 
 986 
 987       for ( n = 0; n < num_segs; n++ )
 988       {
 989         p      = p_offset;
 990         start  = TT_NEXT_USHORT( p_start );
 991         end    = TT_NEXT_USHORT( p_end );
 992         delta  = TT_NEXT_SHORT( p_delta );
 993         offset = TT_NEXT_USHORT( p_offset );
 994 
 995         if ( start > end )
 996           FT_INVALID_DATA;
 997 
 998         /* this test should be performed at default validation level; */
 999         /* unfortunately, some popular Asian fonts have overlapping   */
1000         /* ranges in their charmaps                                   */
1001         /*                                                            */
1002         if ( start <= last_end && n > 0 )
1003         {
1004           if ( valid->level >= FT_VALIDATE_TIGHT )
1005             FT_INVALID_DATA;
1006           else
1007           {
1008             /* allow overlapping segments, provided their start points */
1009             /* and end points, respectively, are in ascending order    */
1010             /*                                                         */
1011             if ( last_start > start || last_end > end )
1012               error |= TT_CMAP_FLAG_UNSORTED;
1013             else
1014               error |= TT_CMAP_FLAG_OVERLAPPING;
1015           }
1016         }
1017 
1018         if ( offset && offset != 0xFFFFU )
1019         {
1020           p += offset;  /* start of glyph ID array */
1021 
1022           /* check that we point within the glyph IDs table only */
1023           if ( valid->level >= FT_VALIDATE_TIGHT )
1024           {
1025             if ( p < glyph_ids                                ||
1026                  p + ( end - start + 1 ) * 2 > table + length )
1027               FT_INVALID_DATA;
1028           }
1029           /* Some fonts handle the last segment incorrectly.  In */
1030           /* theory, 0xFFFF might point to an ordinary glyph --  */
1031           /* a cmap 4 is versatile and could be used for any     */
1032           /* encoding, not only Unicode.  However, reality shows */
1033           /* that far too many fonts are sloppy and incorrectly  */
1034           /* set all fields but `start' and `end' for the last   */
1035           /* segment if it contains only a single character.     */
1036           /*                                                     */
1037           /* We thus omit the test here, delaying it to the      */
1038           /* routines that actually access the cmap.             */
1039           else if ( n != num_segs - 1                       ||
1040                     !( start == 0xFFFFU && end == 0xFFFFU ) )
1041           {
1042             if ( p < glyph_ids                              ||
1043                  p + ( end - start + 1 ) * 2 > valid->limit )
1044               FT_INVALID_DATA;
1045           }
1046 
1047           /* check glyph indices within the segment range */
1048           if ( valid->level >= FT_VALIDATE_TIGHT )
1049           {
1050             FT_UInt  i, idx;
1051 
1052 
1053             for ( i = start; i < end; i++ )
1054             {
1055               idx = FT_NEXT_USHORT( p );
1056               if ( idx != 0 )
1057               {
1058                 idx = (FT_UInt)( (FT_Int)idx + delta ) & 0xFFFFU;
1059 
1060                 if ( idx >= TT_VALID_GLYPH_COUNT( valid ) )
1061                   FT_INVALID_GLYPH_ID;
1062               }
1063             }
1064           }
1065         }
1066         else if ( offset == 0xFFFFU )
1067         {
1068           /* some fonts (erroneously?) use a range offset of 0xFFFF */
1069           /* to mean missing glyph in cmap table                    */
1070           /*                                                        */
1071           if ( valid->level >= FT_VALIDATE_PARANOID    ||
1072                n != num_segs - 1                       ||
1073                !( start == 0xFFFFU && end == 0xFFFFU ) )
1074             FT_INVALID_DATA;
1075         }
1076 
1077         last_start = start;
1078         last_end   = end;
1079       }
1080     }
1081 
1082     return error;
1083   }
1084 
1085 
1086   static FT_UInt
1087   tt_cmap4_char_map_linear( TT_CMap     cmap,
1088                             FT_UInt32*  pcharcode,
1089                             FT_Bool     next )
1090   {
1091     TT_Face   face  = (TT_Face)cmap->cmap.charmap.face;
1092     FT_Byte*  limit = face->cmap_table + face->cmap_size;
1093 
1094 
1095     FT_UInt    num_segs2, start, end, offset;
1096     FT_Int     delta;
1097     FT_UInt    i, num_segs;
1098     FT_UInt32  charcode = *pcharcode;
1099     FT_UInt    gindex   = 0;
1100     FT_Byte*   p;
1101     FT_Byte*   q;
1102 
1103 
1104     p = cmap->data + 6;
1105     num_segs2 = FT_PAD_FLOOR( TT_PEEK_USHORT( p ), 2 );
1106 
1107     num_segs = num_segs2 >> 1;
1108 
1109     if ( !num_segs )
1110       return 0;
1111 
1112     if ( next )
1113       charcode++;
1114 
1115     if ( charcode > 0xFFFFU )
1116       return 0;
1117 
1118     /* linear search */
1119     p = cmap->data + 14;               /* ends table   */
1120     q = cmap->data + 16 + num_segs2;   /* starts table */
1121 
1122     for ( i = 0; i < num_segs; i++ )
1123     {
1124       end   = TT_NEXT_USHORT( p );
1125       start = TT_NEXT_USHORT( q );
1126 
1127       if ( charcode < start )
1128       {
1129         if ( next )
1130           charcode = start;
1131         else
1132           break;
1133       }
1134 
1135     Again:
1136       if ( charcode <= end )
1137       {
1138         FT_Byte*  r;
1139 
1140 
1141         r       = q - 2 + num_segs2;
1142         delta   = TT_PEEK_SHORT( r );
1143         r      += num_segs2;
1144         offset  = TT_PEEK_USHORT( r );
1145 
1146         /* some fonts have an incorrect last segment; */
1147         /* we have to catch it                        */
1148         if ( i >= num_segs - 1                  &&
1149              start == 0xFFFFU && end == 0xFFFFU )
1150         {
1151           if ( offset && r + offset + 2 > limit )
1152           {
1153             delta  = 1;
1154             offset = 0;
1155           }
1156         }
1157 
1158         if ( offset == 0xFFFFU )
1159           continue;
1160 
1161         if ( offset )
1162         {
1163           r += offset + ( charcode - start ) * 2;
1164 
1165           /* if r > limit, the whole segment is invalid */
1166           if ( next && r > limit )
1167             continue;
1168 
1169           gindex = TT_PEEK_USHORT( r );
1170           if ( gindex )
1171           {
1172             gindex = (FT_UInt)( (FT_Int)gindex + delta ) & 0xFFFFU;
1173             if ( gindex >= (FT_UInt)face->root.num_glyphs )
1174               gindex = 0;
1175           }
1176         }
1177         else
1178         {
1179           gindex = (FT_UInt)( (FT_Int)charcode + delta ) & 0xFFFFU;
1180 
1181           if ( next && gindex >= (FT_UInt)face->root.num_glyphs )
1182           {
1183             /* we have an invalid glyph index; if there is an overflow, */
1184             /* we can adjust `charcode', otherwise the whole segment is */
1185             /* invalid                                                  */
1186             gindex = 0;
1187 
1188             if ( (FT_Int)charcode + delta < 0 &&
1189                  (FT_Int)end + delta >= 0     )
1190               charcode = (FT_UInt)( -delta );
1191 
1192             else if ( (FT_Int)charcode + delta < 0x10000L &&
1193                       (FT_Int)end + delta >= 0x10000L     )
1194               charcode = (FT_UInt)( 0x10000L - delta );
1195 
1196             else
1197               continue;
1198           }
1199         }
1200 
1201         if ( next && !gindex )
1202         {
1203           if ( charcode >= 0xFFFFU )
1204             break;
1205 
1206           charcode++;
1207           goto Again;
1208         }
1209 
1210         break;
1211       }
1212     }
1213 
1214     if ( next )
1215       *pcharcode = charcode;
1216 
1217     return gindex;
1218   }
1219 
1220 
1221   static FT_UInt
1222   tt_cmap4_char_map_binary( TT_CMap     cmap,
1223                             FT_UInt32*  pcharcode,
1224                             FT_Bool     next )
1225   {
1226     TT_Face   face  = (TT_Face)cmap->cmap.charmap.face;
1227     FT_Byte*  limit = face->cmap_table + face->cmap_size;
1228 
1229     FT_UInt   num_segs2, start, end, offset;
1230     FT_Int    delta;
1231     FT_UInt   max, min, mid, num_segs;
1232     FT_UInt   charcode = (FT_UInt)*pcharcode;
1233     FT_UInt   gindex   = 0;
1234     FT_Byte*  p;
1235 
1236 
1237     p = cmap->data + 6;
1238     num_segs2 = FT_PAD_FLOOR( TT_PEEK_USHORT( p ), 2 );
1239 
1240     if ( !num_segs2 )
1241       return 0;
1242 
1243     num_segs = num_segs2 >> 1;
1244 
1245     /* make compiler happy */
1246     mid = num_segs;
1247     end = 0xFFFFU;
1248 
1249     if ( next )
1250       charcode++;
1251 
1252     min = 0;
1253     max = num_segs;
1254 
1255     /* binary search */
1256     while ( min < max )
1257     {
1258       mid    = ( min + max ) >> 1;
1259       p      = cmap->data + 14 + mid * 2;
1260       end    = TT_PEEK_USHORT( p );
1261       p     += 2 + num_segs2;
1262       start  = TT_PEEK_USHORT( p );
1263 
1264       if ( charcode < start )
1265         max = mid;
1266       else if ( charcode > end )
1267         min = mid + 1;
1268       else
1269       {
1270         p     += num_segs2;
1271         delta  = TT_PEEK_SHORT( p );
1272         p     += num_segs2;
1273         offset = TT_PEEK_USHORT( p );
1274 
1275         /* some fonts have an incorrect last segment; */
1276         /* we have to catch it                        */
1277         if ( mid >= num_segs - 1                &&
1278              start == 0xFFFFU && end == 0xFFFFU )
1279         {
1280           if ( offset && p + offset + 2 > limit )
1281           {
1282             delta  = 1;
1283             offset = 0;
1284           }
1285         }
1286 
1287         /* search the first segment containing `charcode' */
1288         if ( cmap->flags & TT_CMAP_FLAG_OVERLAPPING )
1289         {
1290           FT_UInt  i;
1291 
1292 
1293           /* call the current segment `max' */
1294           max = mid;
1295 
1296           if ( offset == 0xFFFFU )
1297             mid = max + 1;
1298 
1299           /* search in segments before the current segment */
1300           for ( i = max; i > 0; i-- )
1301           {
1302             FT_UInt   prev_end;
1303             FT_Byte*  old_p;
1304 
1305 
1306             old_p    = p;
1307             p        = cmap->data + 14 + ( i - 1 ) * 2;
1308             prev_end = TT_PEEK_USHORT( p );
1309 
1310             if ( charcode > prev_end )
1311             {
1312               p = old_p;
1313               break;
1314             }
1315 
1316             end    = prev_end;
1317             p     += 2 + num_segs2;
1318             start  = TT_PEEK_USHORT( p );
1319             p     += num_segs2;
1320             delta  = TT_PEEK_SHORT( p );
1321             p     += num_segs2;
1322             offset = TT_PEEK_USHORT( p );
1323 
1324             if ( offset != 0xFFFFU )
1325               mid = i - 1;
1326           }
1327 
1328           /* no luck */
1329           if ( mid == max + 1 )
1330           {
1331             if ( i != max )
1332             {
1333               p      = cmap->data + 14 + max * 2;
1334               end    = TT_PEEK_USHORT( p );
1335               p     += 2 + num_segs2;
1336               start  = TT_PEEK_USHORT( p );
1337               p     += num_segs2;
1338               delta  = TT_PEEK_SHORT( p );
1339               p     += num_segs2;
1340               offset = TT_PEEK_USHORT( p );
1341             }
1342 
1343             mid = max;
1344 
1345             /* search in segments after the current segment */
1346             for ( i = max + 1; i < num_segs; i++ )
1347             {
1348               FT_UInt  next_end, next_start;
1349 
1350 
1351               p          = cmap->data + 14 + i * 2;
1352               next_end   = TT_PEEK_USHORT( p );
1353               p         += 2 + num_segs2;
1354               next_start = TT_PEEK_USHORT( p );
1355 
1356               if ( charcode < next_start )
1357                 break;
1358 
1359               end    = next_end;
1360               start  = next_start;
1361               p     += num_segs2;
1362               delta  = TT_PEEK_SHORT( p );
1363               p     += num_segs2;
1364               offset = TT_PEEK_USHORT( p );
1365 
1366               if ( offset != 0xFFFFU )
1367                 mid = i;
1368             }
1369             i--;
1370 
1371             /* still no luck */
1372             if ( mid == max )
1373             {
1374               mid = i;
1375 
1376               break;
1377             }
1378           }
1379 
1380           /* end, start, delta, and offset are for the i'th segment */
1381           if ( mid != i )
1382           {
1383             p      = cmap->data + 14 + mid * 2;
1384             end    = TT_PEEK_USHORT( p );
1385             p     += 2 + num_segs2;
1386             start  = TT_PEEK_USHORT( p );
1387             p     += num_segs2;
1388             delta  = TT_PEEK_SHORT( p );
1389             p     += num_segs2;
1390             offset = TT_PEEK_USHORT( p );
1391           }
1392         }
1393         else
1394         {
1395           if ( offset == 0xFFFFU )
1396             break;
1397         }
1398 
1399         if ( offset )
1400         {
1401           p += offset + ( charcode - start ) * 2;
1402 
1403           /* if p > limit, the whole segment is invalid */
1404           if ( next && p > limit )
1405             break;
1406 
1407           gindex = TT_PEEK_USHORT( p );
1408           if ( gindex )
1409           {
1410             gindex = (FT_UInt)( (FT_Int)gindex + delta ) & 0xFFFFU;
1411             if ( gindex >= (FT_UInt)face->root.num_glyphs )
1412               gindex = 0;
1413           }
1414         }
1415         else
1416         {
1417           gindex = (FT_UInt)( (FT_Int)charcode + delta ) & 0xFFFFU;
1418 
1419           if ( next && gindex >= (FT_UInt)face->root.num_glyphs )
1420           {
1421             /* we have an invalid glyph index; if there is an overflow, */
1422             /* we can adjust `charcode', otherwise the whole segment is */
1423             /* invalid                                                  */
1424             gindex = 0;
1425 
1426             if ( (FT_Int)charcode + delta < 0 &&
1427                  (FT_Int)end + delta >= 0     )
1428               charcode = (FT_UInt)( -delta );
1429 
1430             else if ( (FT_Int)charcode + delta < 0x10000L &&
1431                       (FT_Int)end + delta >= 0x10000L     )
1432               charcode = (FT_UInt)( 0x10000L - delta );
1433           }
1434         }
1435 
1436         break;
1437       }
1438     }
1439 
1440     if ( next )
1441     {
1442       TT_CMap4  cmap4 = (TT_CMap4)cmap;
1443 
1444 
1445       /* if `charcode' is not in any segment, then `mid' is */
1446       /* the segment nearest to `charcode'                  */
1447 
1448       if ( charcode > end )
1449       {
1450         mid++;
1451         if ( mid == num_segs )
1452           return 0;
1453       }
1454 
1455       if ( tt_cmap4_set_range( cmap4, mid ) )
1456       {
1457         if ( gindex )
1458           *pcharcode = charcode;
1459       }
1460       else
1461       {
1462         cmap4->cur_charcode = charcode;
1463 
1464         if ( gindex )
1465           cmap4->cur_gindex = gindex;
1466         else
1467         {
1468           cmap4->cur_charcode = charcode;
1469           tt_cmap4_next( cmap4 );
1470           gindex = cmap4->cur_gindex;
1471         }
1472 
1473         if ( gindex )
1474           *pcharcode = cmap4->cur_charcode;
1475       }
1476     }
1477 
1478     return gindex;
1479   }
1480 
1481 
1482   FT_CALLBACK_DEF( FT_UInt )
1483   tt_cmap4_char_index( TT_CMap    cmap,
1484                        FT_UInt32  char_code )
1485   {
1486     if ( char_code >= 0x10000UL )
1487       return 0;
1488 
1489     if ( cmap->flags & TT_CMAP_FLAG_UNSORTED )
1490       return tt_cmap4_char_map_linear( cmap, &char_code, 0 );
1491     else
1492       return tt_cmap4_char_map_binary( cmap, &char_code, 0 );
1493   }
1494 
1495 
1496   FT_CALLBACK_DEF( FT_UInt32 )
1497   tt_cmap4_char_next( TT_CMap     cmap,
1498                       FT_UInt32  *pchar_code )
1499   {
1500     FT_UInt  gindex;
1501 
1502 
1503     if ( *pchar_code >= 0xFFFFU )
1504       return 0;
1505 
1506     if ( cmap->flags & TT_CMAP_FLAG_UNSORTED )
1507       gindex = tt_cmap4_char_map_linear( cmap, pchar_code, 1 );
1508     else
1509     {
1510       TT_CMap4  cmap4 = (TT_CMap4)cmap;
1511 
1512 
1513       /* no need to search */
1514       if ( *pchar_code == cmap4->cur_charcode )
1515       {
1516         tt_cmap4_next( cmap4 );
1517         gindex = cmap4->cur_gindex;
1518         if ( gindex )
1519           *pchar_code = cmap4->cur_charcode;
1520       }
1521       else
1522         gindex = tt_cmap4_char_map_binary( cmap, pchar_code, 1 );
1523     }
1524 
1525     return gindex;
1526   }
1527 
1528 
1529   FT_CALLBACK_DEF( FT_Error )
1530   tt_cmap4_get_info( TT_CMap       cmap,
1531                      TT_CMapInfo  *cmap_info )
1532   {
1533     FT_Byte*  p = cmap->data + 4;
1534 
1535 
1536     cmap_info->format   = 4;
1537     cmap_info->language = (FT_ULong)TT_PEEK_USHORT( p );
1538 
1539     return FT_Err_Ok;
1540   }
1541 
1542 
1543   FT_DEFINE_TT_CMAP(
1544     tt_cmap4_class_rec,
1545 
1546       sizeof ( TT_CMap4Rec ),
1547 
1548       (FT_CMap_InitFunc)     tt_cmap4_init,        /* init       */
1549       (FT_CMap_DoneFunc)     NULL,                 /* done       */
1550       (FT_CMap_CharIndexFunc)tt_cmap4_char_index,  /* char_index */
1551       (FT_CMap_CharNextFunc) tt_cmap4_char_next,   /* char_next  */
1552 
1553       (FT_CMap_CharVarIndexFunc)    NULL,  /* char_var_index   */
1554       (FT_CMap_CharVarIsDefaultFunc)NULL,  /* char_var_default */
1555       (FT_CMap_VariantListFunc)     NULL,  /* variant_list     */
1556       (FT_CMap_CharVariantListFunc) NULL,  /* charvariant_list */
1557       (FT_CMap_VariantCharListFunc) NULL,  /* variantchar_list */
1558 
1559     4,
1560     (TT_CMap_ValidateFunc)tt_cmap4_validate,  /* validate      */
1561     (TT_CMap_Info_GetFunc)tt_cmap4_get_info   /* get_cmap_info */
1562   )
1563 
1564 #endif /* TT_CONFIG_CMAP_FORMAT_4 */
1565 
1566 
1567   /*************************************************************************/
1568   /*************************************************************************/
1569   /*****                                                               *****/
1570   /*****                          FORMAT 6                             *****/
1571   /*****                                                               *****/
1572   /*************************************************************************/
1573   /*************************************************************************/
1574 
1575   /**************************************************************************
1576    *
1577    * TABLE OVERVIEW
1578    * --------------
1579    *
1580    *   NAME        OFFSET          TYPE             DESCRIPTION
1581    *
1582    *   format       0              USHORT           must be 6
1583    *   length       2              USHORT           table length in bytes
1584    *   language     4              USHORT           Mac language code
1585    *
1586    *   first        6              USHORT           first segment code
1587    *   count        8              USHORT           segment size in chars
1588    *   glyphIds     10             USHORT[count]    glyph IDs
1589    *
1590    * A very simplified segment mapping.
1591    */
1592 
1593 #ifdef TT_CONFIG_CMAP_FORMAT_6
1594 
1595   FT_CALLBACK_DEF( FT_Error )
1596   tt_cmap6_validate( FT_Byte*      table,
1597                      FT_Validator  valid )
1598   {
1599     FT_Byte*  p;
1600     FT_UInt   length, count;
1601 
1602 
1603     if ( table + 10 > valid->limit )
1604       FT_INVALID_TOO_SHORT;
1605 
1606     p      = table + 2;
1607     length = TT_NEXT_USHORT( p );
1608 
1609     p      = table + 8;             /* skip language and start index */
1610     count  = TT_NEXT_USHORT( p );
1611 
1612     if ( table + length > valid->limit || length < 10 + count * 2 )
1613       FT_INVALID_TOO_SHORT;
1614 
1615     /* check glyph indices */
1616     if ( valid->level >= FT_VALIDATE_TIGHT )
1617     {
1618       FT_UInt  gindex;
1619 
1620 
1621       for ( ; count > 0; count-- )
1622       {
1623         gindex = TT_NEXT_USHORT( p );
1624         if ( gindex >= TT_VALID_GLYPH_COUNT( valid ) )
1625           FT_INVALID_GLYPH_ID;
1626       }
1627     }
1628 
1629     return FT_Err_Ok;
1630   }
1631 
1632 
1633   FT_CALLBACK_DEF( FT_UInt )
1634   tt_cmap6_char_index( TT_CMap    cmap,
1635                        FT_UInt32  char_code )
1636   {
1637     FT_Byte*  table  = cmap->data;
1638     FT_UInt   result = 0;
1639     FT_Byte*  p      = table + 6;
1640     FT_UInt   start  = TT_NEXT_USHORT( p );
1641     FT_UInt   count  = TT_NEXT_USHORT( p );
1642     FT_UInt   idx    = (FT_UInt)( char_code - start );
1643 
1644 
1645     if ( idx < count )
1646     {
1647       p += 2 * idx;
1648       result = TT_PEEK_USHORT( p );
1649     }
1650 
1651     return result;
1652   }
1653 
1654 
1655   FT_CALLBACK_DEF( FT_UInt32 )
1656   tt_cmap6_char_next( TT_CMap     cmap,
1657                       FT_UInt32  *pchar_code )
1658   {
1659     FT_Byte*   table     = cmap->data;
1660     FT_UInt32  result    = 0;
1661     FT_UInt32  char_code = *pchar_code + 1;
1662     FT_UInt    gindex    = 0;
1663 
1664     FT_Byte*   p         = table + 6;
1665     FT_UInt    start     = TT_NEXT_USHORT( p );
1666     FT_UInt    count     = TT_NEXT_USHORT( p );
1667     FT_UInt    idx;
1668 
1669 
1670     if ( char_code >= 0x10000UL )
1671       return 0;
1672 
1673     if ( char_code < start )
1674       char_code = start;
1675 
1676     idx = (FT_UInt)( char_code - start );
1677     p  += 2 * idx;
1678 
1679     for ( ; idx < count; idx++ )
1680     {
1681       gindex = TT_NEXT_USHORT( p );
1682       if ( gindex != 0 )
1683       {
1684         result = char_code;
1685         break;
1686       }
1687 
1688       if ( char_code >= 0xFFFFU )
1689         return 0;
1690 
1691       char_code++;
1692     }
1693 
1694     *pchar_code = result;
1695     return gindex;
1696   }
1697 
1698 
1699   FT_CALLBACK_DEF( FT_Error )
1700   tt_cmap6_get_info( TT_CMap       cmap,
1701                      TT_CMapInfo  *cmap_info )
1702   {
1703     FT_Byte*  p = cmap->data + 4;
1704 
1705 
1706     cmap_info->format   = 6;
1707     cmap_info->language = (FT_ULong)TT_PEEK_USHORT( p );
1708 
1709     return FT_Err_Ok;
1710   }
1711 
1712 
1713   FT_DEFINE_TT_CMAP(
1714     tt_cmap6_class_rec,
1715 
1716       sizeof ( TT_CMapRec ),
1717 
1718       (FT_CMap_InitFunc)     tt_cmap_init,         /* init       */
1719       (FT_CMap_DoneFunc)     NULL,                 /* done       */
1720       (FT_CMap_CharIndexFunc)tt_cmap6_char_index,  /* char_index */
1721       (FT_CMap_CharNextFunc) tt_cmap6_char_next,   /* char_next  */
1722 
1723       (FT_CMap_CharVarIndexFunc)    NULL,  /* char_var_index   */
1724       (FT_CMap_CharVarIsDefaultFunc)NULL,  /* char_var_default */
1725       (FT_CMap_VariantListFunc)     NULL,  /* variant_list     */
1726       (FT_CMap_CharVariantListFunc) NULL,  /* charvariant_list */
1727       (FT_CMap_VariantCharListFunc) NULL,  /* variantchar_list */
1728 
1729     6,
1730     (TT_CMap_ValidateFunc)tt_cmap6_validate,  /* validate      */
1731     (TT_CMap_Info_GetFunc)tt_cmap6_get_info   /* get_cmap_info */
1732   )
1733 
1734 #endif /* TT_CONFIG_CMAP_FORMAT_6 */
1735 
1736 
1737   /*************************************************************************/
1738   /*************************************************************************/
1739   /*****                                                               *****/
1740   /*****                          FORMAT 8                             *****/
1741   /*****                                                               *****/
1742   /***** It is hard to completely understand what the OpenType spec    *****/
1743   /***** says about this format, but here is my conclusion.            *****/
1744   /*****                                                               *****/
1745   /***** The purpose of this format is to easily map UTF-16 text to    *****/
1746   /***** glyph indices.  Basically, the `char_code' must be in one of  *****/
1747   /***** the following formats.                                        *****/
1748   /*****                                                               *****/
1749   /*****   - A 16-bit value that isn't part of the Unicode Surrogates  *****/
1750   /*****     Area (i.e. U+D800-U+DFFF).                                *****/
1751   /*****                                                               *****/
1752   /*****   - A 32-bit value, made of two surrogate values, i.e.. if    *****/
1753   /*****     `char_code = (char_hi << 16) | char_lo', then both        *****/
1754   /*****     `char_hi' and `char_lo' must be in the Surrogates Area.   *****/
1755   /*****      Area.                                                    *****/
1756   /*****                                                               *****/
1757   /***** The `is32' table embedded in the charmap indicates whether a  *****/
1758   /***** given 16-bit value is in the surrogates area or not.          *****/
1759   /*****                                                               *****/
1760   /***** So, for any given `char_code', we can assert the following.   *****/
1761   /*****                                                               *****/
1762   /*****   If `char_hi == 0' then we must have `is32[char_lo] == 0'.   *****/
1763   /*****                                                               *****/
1764   /*****   If `char_hi != 0' then we must have both                    *****/
1765   /*****   `is32[char_hi] != 0' and `is32[char_lo] != 0'.              *****/
1766   /*****                                                               *****/
1767   /*************************************************************************/
1768   /*************************************************************************/
1769 
1770   /**************************************************************************
1771    *
1772    * TABLE OVERVIEW
1773    * --------------
1774    *
1775    *   NAME        OFFSET         TYPE        DESCRIPTION
1776    *
1777    *   format      0              USHORT      must be 8
1778    *   reserved    2              USHORT      reserved
1779    *   length      4              ULONG       length in bytes
1780    *   language    8              ULONG       Mac language code
1781    *   is32        12             BYTE[8192]  32-bitness bitmap
1782    *   count       8204           ULONG       number of groups
1783    *
1784    * This header is followed by `count' groups of the following format:
1785    *
1786    *   start       0              ULONG       first charcode
1787    *   end         4              ULONG       last charcode
1788    *   startId     8              ULONG       start glyph ID for the group
1789    */
1790 
1791 #ifdef TT_CONFIG_CMAP_FORMAT_8
1792 
1793   FT_CALLBACK_DEF( FT_Error )
1794   tt_cmap8_validate( FT_Byte*      table,
1795                      FT_Validator  valid )
1796   {
1797     FT_Byte*   p = table + 4;
1798     FT_Byte*   is32;
1799     FT_UInt32  length;
1800     FT_UInt32  num_groups;
1801 
1802 
1803     if ( table + 16 + 8192 > valid->limit )
1804       FT_INVALID_TOO_SHORT;
1805 
1806     length = TT_NEXT_ULONG( p );
1807     if ( length > (FT_UInt32)( valid->limit - table ) || length < 8192 + 16 )
1808       FT_INVALID_TOO_SHORT;
1809 
1810     is32       = table + 12;
1811     p          = is32  + 8192;          /* skip `is32' array */
1812     num_groups = TT_NEXT_ULONG( p );
1813 
1814     /* p + num_groups * 12 > valid->limit ? */
1815     if ( num_groups > (FT_UInt32)( valid->limit - p ) / 12 )
1816       FT_INVALID_TOO_SHORT;
1817 
1818     /* check groups, they must be in increasing order */
1819     {
1820       FT_UInt32  n, start, end, start_id, count, last = 0;
1821 
1822 
1823       for ( n = 0; n < num_groups; n++ )
1824       {
1825         FT_UInt   hi, lo;
1826 
1827 
1828         start    = TT_NEXT_ULONG( p );
1829         end      = TT_NEXT_ULONG( p );
1830         start_id = TT_NEXT_ULONG( p );
1831 
1832         if ( start > end )
1833           FT_INVALID_DATA;
1834 
1835         if ( n > 0 && start <= last )
1836           FT_INVALID_DATA;
1837 
1838         if ( valid->level >= FT_VALIDATE_TIGHT )
1839         {
1840           FT_UInt32  d = end - start;
1841 
1842 
1843           /* start_id + end - start >= TT_VALID_GLYPH_COUNT( valid ) ? */
1844           if ( d > TT_VALID_GLYPH_COUNT( valid )             ||
1845                start_id >= TT_VALID_GLYPH_COUNT( valid ) - d )
1846             FT_INVALID_GLYPH_ID;
1847 
1848           count = (FT_UInt32)( end - start + 1 );
1849 
1850           if ( start & ~0xFFFFU )
1851           {
1852             /* start_hi != 0; check that is32[i] is 1 for each i in */
1853             /* the `hi' and `lo' of the range [start..end]          */
1854             for ( ; count > 0; count--, start++ )
1855             {
1856               hi = (FT_UInt)( start >> 16 );
1857               lo = (FT_UInt)( start & 0xFFFFU );
1858 
1859               if ( (is32[hi >> 3] & ( 0x80 >> ( hi & 7 ) ) ) == 0 )
1860                 FT_INVALID_DATA;
1861 
1862               if ( (is32[lo >> 3] & ( 0x80 >> ( lo & 7 ) ) ) == 0 )
1863                 FT_INVALID_DATA;
1864             }
1865           }
1866           else
1867           {
1868             /* start_hi == 0; check that is32[i] is 0 for each i in */
1869             /* the range [start..end]                               */
1870 
1871             /* end_hi cannot be != 0! */
1872             if ( end & ~0xFFFFU )
1873               FT_INVALID_DATA;
1874 
1875             for ( ; count > 0; count--, start++ )
1876             {
1877               lo = (FT_UInt)( start & 0xFFFFU );
1878 
1879               if ( (is32[lo >> 3] & ( 0x80 >> ( lo & 7 ) ) ) != 0 )
1880                 FT_INVALID_DATA;
1881             }
1882           }
1883         }
1884 
1885         last = end;
1886       }
1887     }
1888 
1889     return FT_Err_Ok;
1890   }
1891 
1892 
1893   FT_CALLBACK_DEF( FT_UInt )
1894   tt_cmap8_char_index( TT_CMap    cmap,
1895                        FT_UInt32  char_code )
1896   {
1897     FT_Byte*   table      = cmap->data;
1898     FT_UInt    result     = 0;
1899     FT_Byte*   p          = table + 8204;
1900     FT_UInt32  num_groups = TT_NEXT_ULONG( p );
1901     FT_UInt32  start, end, start_id;
1902 
1903 
1904     for ( ; num_groups > 0; num_groups-- )
1905     {
1906       start    = TT_NEXT_ULONG( p );
1907       end      = TT_NEXT_ULONG( p );
1908       start_id = TT_NEXT_ULONG( p );
1909 
1910       if ( char_code < start )
1911         break;
1912 
1913       if ( char_code <= end )
1914       {
1915         if ( start_id > 0xFFFFFFFFUL - ( char_code - start ) )
1916           return 0;
1917 
1918         result = (FT_UInt)( start_id + ( char_code - start ) );
1919         break;
1920       }
1921     }
1922     return result;
1923   }
1924 
1925 
1926   FT_CALLBACK_DEF( FT_UInt32 )
1927   tt_cmap8_char_next( TT_CMap     cmap,
1928                       FT_UInt32  *pchar_code )
1929   {
1930     FT_Face    face       = cmap->cmap.charmap.face;
1931     FT_UInt32  result     = 0;
1932     FT_UInt32  char_code;
1933     FT_UInt    gindex     = 0;
1934     FT_Byte*   table      = cmap->data;
1935     FT_Byte*   p          = table + 8204;
1936     FT_UInt32  num_groups = TT_NEXT_ULONG( p );
1937     FT_UInt32  start, end, start_id;
1938 
1939 
1940     if ( *pchar_code >= 0xFFFFFFFFUL )
1941       return 0;
1942 
1943     char_code = *pchar_code + 1;
1944 
1945     p = table + 8208;
1946 
1947     for ( ; num_groups > 0; num_groups-- )
1948     {
1949       start    = TT_NEXT_ULONG( p );
1950       end      = TT_NEXT_ULONG( p );
1951       start_id = TT_NEXT_ULONG( p );
1952 
1953       if ( char_code < start )
1954         char_code = start;
1955 
1956     Again:
1957       if ( char_code <= end )
1958       {
1959         /* ignore invalid group */
1960         if ( start_id > 0xFFFFFFFFUL - ( char_code - start ) )
1961           continue;
1962 
1963         gindex = (FT_UInt)( start_id + ( char_code - start ) );
1964 
1965         /* does first element of group point to `.notdef' glyph? */
1966         if ( gindex == 0 )
1967         {
1968           if ( char_code >= 0xFFFFFFFFUL )
1969             break;
1970 
1971           char_code++;
1972           goto Again;
1973         }
1974 
1975         /* if `gindex' is invalid, the remaining values */
1976         /* in this group are invalid, too               */
1977         if ( gindex >= (FT_UInt)face->num_glyphs )
1978         {
1979           gindex = 0;
1980           continue;
1981         }
1982 
1983         result = char_code;
1984         break;
1985       }
1986     }
1987 
1988     *pchar_code = result;
1989     return gindex;
1990   }
1991 
1992 
1993   FT_CALLBACK_DEF( FT_Error )
1994   tt_cmap8_get_info( TT_CMap       cmap,
1995                      TT_CMapInfo  *cmap_info )
1996   {
1997     FT_Byte*  p = cmap->data + 8;
1998 
1999 
2000     cmap_info->format   = 8;
2001     cmap_info->language = (FT_ULong)TT_PEEK_ULONG( p );
2002 
2003     return FT_Err_Ok;
2004   }
2005 
2006 
2007   FT_DEFINE_TT_CMAP(
2008     tt_cmap8_class_rec,
2009 
2010       sizeof ( TT_CMapRec ),
2011 
2012       (FT_CMap_InitFunc)     tt_cmap_init,         /* init       */
2013       (FT_CMap_DoneFunc)     NULL,                 /* done       */
2014       (FT_CMap_CharIndexFunc)tt_cmap8_char_index,  /* char_index */
2015       (FT_CMap_CharNextFunc) tt_cmap8_char_next,   /* char_next  */
2016 
2017       (FT_CMap_CharVarIndexFunc)    NULL,  /* char_var_index   */
2018       (FT_CMap_CharVarIsDefaultFunc)NULL,  /* char_var_default */
2019       (FT_CMap_VariantListFunc)     NULL,  /* variant_list     */
2020       (FT_CMap_CharVariantListFunc) NULL,  /* charvariant_list */
2021       (FT_CMap_VariantCharListFunc) NULL,  /* variantchar_list */
2022 
2023     8,
2024     (TT_CMap_ValidateFunc)tt_cmap8_validate,  /* validate      */
2025     (TT_CMap_Info_GetFunc)tt_cmap8_get_info   /* get_cmap_info */
2026   )
2027 
2028 #endif /* TT_CONFIG_CMAP_FORMAT_8 */
2029 
2030 
2031   /*************************************************************************/
2032   /*************************************************************************/
2033   /*****                                                               *****/
2034   /*****                          FORMAT 10                            *****/
2035   /*****                                                               *****/
2036   /*************************************************************************/
2037   /*************************************************************************/
2038 
2039   /**************************************************************************
2040    *
2041    * TABLE OVERVIEW
2042    * --------------
2043    *
2044    *   NAME      OFFSET  TYPE               DESCRIPTION
2045    *
2046    *   format     0      USHORT             must be 10
2047    *   reserved   2      USHORT             reserved
2048    *   length     4      ULONG              length in bytes
2049    *   language   8      ULONG              Mac language code
2050    *
2051    *   start     12      ULONG              first char in range
2052    *   count     16      ULONG              number of chars in range
2053    *   glyphIds  20      USHORT[count]      glyph indices covered
2054    */
2055 
2056 #ifdef TT_CONFIG_CMAP_FORMAT_10
2057 
2058   FT_CALLBACK_DEF( FT_Error )
2059   tt_cmap10_validate( FT_Byte*      table,
2060                       FT_Validator  valid )
2061   {
2062     FT_Byte*  p = table + 4;
2063     FT_ULong  length, count;
2064 
2065 
2066     if ( table + 20 > valid->limit )
2067       FT_INVALID_TOO_SHORT;
2068 
2069     length = TT_NEXT_ULONG( p );
2070     p      = table + 16;
2071     count  = TT_NEXT_ULONG( p );
2072 
2073     if ( length > (FT_ULong)( valid->limit - table ) ||
2074          /* length < 20 + count * 2 ? */
2075          length < 20                                 ||
2076          ( length - 20 ) / 2 < count                 )
2077       FT_INVALID_TOO_SHORT;
2078 
2079     /* check glyph indices */
2080     if ( valid->level >= FT_VALIDATE_TIGHT )
2081     {
2082       FT_UInt  gindex;
2083 
2084 
2085       for ( ; count > 0; count-- )
2086       {
2087         gindex = TT_NEXT_USHORT( p );
2088         if ( gindex >= TT_VALID_GLYPH_COUNT( valid ) )
2089           FT_INVALID_GLYPH_ID;
2090       }
2091     }
2092 
2093     return FT_Err_Ok;
2094   }
2095 
2096 
2097   FT_CALLBACK_DEF( FT_UInt )
2098   tt_cmap10_char_index( TT_CMap    cmap,
2099                         FT_UInt32  char_code )
2100   {
2101     FT_Byte*   table  = cmap->data;
2102     FT_UInt    result = 0;
2103     FT_Byte*   p      = table + 12;
2104     FT_UInt32  start  = TT_NEXT_ULONG( p );
2105     FT_UInt32  count  = TT_NEXT_ULONG( p );
2106     FT_UInt32  idx;
2107 
2108 
2109     if ( char_code < start )
2110       return 0;
2111 
2112     idx = char_code - start;
2113 
2114     if ( idx < count )
2115     {
2116       p     += 2 * idx;
2117       result = TT_PEEK_USHORT( p );
2118     }
2119 
2120     return result;
2121   }
2122 
2123 
2124   FT_CALLBACK_DEF( FT_UInt32 )
2125   tt_cmap10_char_next( TT_CMap     cmap,
2126                        FT_UInt32  *pchar_code )
2127   {
2128     FT_Byte*   table     = cmap->data;
2129     FT_UInt32  char_code;
2130     FT_UInt    gindex    = 0;
2131     FT_Byte*   p         = table + 12;
2132     FT_UInt32  start     = TT_NEXT_ULONG( p );
2133     FT_UInt32  count     = TT_NEXT_ULONG( p );
2134     FT_UInt32  idx;
2135 
2136 
2137     if ( *pchar_code >= 0xFFFFFFFFUL )
2138       return 0;
2139 
2140     char_code = *pchar_code + 1;
2141 
2142     if ( char_code < start )
2143       char_code = start;
2144 
2145     idx = char_code - start;
2146     p  += 2 * idx;
2147 
2148     for ( ; idx < count; idx++ )
2149     {
2150       gindex = TT_NEXT_USHORT( p );
2151       if ( gindex != 0 )
2152         break;
2153 
2154       if ( char_code >= 0xFFFFFFFFUL )
2155         return 0;
2156 
2157       char_code++;
2158     }
2159 
2160     *pchar_code = char_code;
2161     return gindex;
2162   }
2163 
2164 
2165   FT_CALLBACK_DEF( FT_Error )
2166   tt_cmap10_get_info( TT_CMap       cmap,
2167                       TT_CMapInfo  *cmap_info )
2168   {
2169     FT_Byte*  p = cmap->data + 8;
2170 
2171 
2172     cmap_info->format   = 10;
2173     cmap_info->language = (FT_ULong)TT_PEEK_ULONG( p );
2174 
2175     return FT_Err_Ok;
2176   }
2177 
2178 
2179   FT_DEFINE_TT_CMAP(
2180     tt_cmap10_class_rec,
2181 
2182       sizeof ( TT_CMapRec ),
2183 
2184       (FT_CMap_InitFunc)     tt_cmap_init,          /* init       */
2185       (FT_CMap_DoneFunc)     NULL,                  /* done       */
2186       (FT_CMap_CharIndexFunc)tt_cmap10_char_index,  /* char_index */
2187       (FT_CMap_CharNextFunc) tt_cmap10_char_next,   /* char_next  */
2188 
2189       (FT_CMap_CharVarIndexFunc)    NULL,  /* char_var_index   */
2190       (FT_CMap_CharVarIsDefaultFunc)NULL,  /* char_var_default */
2191       (FT_CMap_VariantListFunc)     NULL,  /* variant_list     */
2192       (FT_CMap_CharVariantListFunc) NULL,  /* charvariant_list */
2193       (FT_CMap_VariantCharListFunc) NULL,  /* variantchar_list */
2194 
2195     10,
2196     (TT_CMap_ValidateFunc)tt_cmap10_validate,  /* validate      */
2197     (TT_CMap_Info_GetFunc)tt_cmap10_get_info   /* get_cmap_info */
2198   )
2199 
2200 #endif /* TT_CONFIG_CMAP_FORMAT_10 */
2201 
2202 
2203   /*************************************************************************/
2204   /*************************************************************************/
2205   /*****                                                               *****/
2206   /*****                          FORMAT 12                            *****/
2207   /*****                                                               *****/
2208   /*************************************************************************/
2209   /*************************************************************************/
2210 
2211   /**************************************************************************
2212    *
2213    * TABLE OVERVIEW
2214    * --------------
2215    *
2216    *   NAME        OFFSET     TYPE       DESCRIPTION
2217    *
2218    *   format      0          USHORT     must be 12
2219    *   reserved    2          USHORT     reserved
2220    *   length      4          ULONG      length in bytes
2221    *   language    8          ULONG      Mac language code
2222    *   count       12         ULONG      number of groups
2223    *               16
2224    *
2225    * This header is followed by `count' groups of the following format:
2226    *
2227    *   start       0          ULONG      first charcode
2228    *   end         4          ULONG      last charcode
2229    *   startId     8          ULONG      start glyph ID for the group
2230    */
2231 
2232 #ifdef TT_CONFIG_CMAP_FORMAT_12
2233 
2234   typedef struct  TT_CMap12Rec_
2235   {
2236     TT_CMapRec  cmap;
2237     FT_Bool     valid;
2238     FT_ULong    cur_charcode;
2239     FT_UInt     cur_gindex;
2240     FT_ULong    cur_group;
2241     FT_ULong    num_groups;
2242 
2243   } TT_CMap12Rec, *TT_CMap12;
2244 
2245 
2246   FT_CALLBACK_DEF( FT_Error )
2247   tt_cmap12_init( TT_CMap12  cmap,
2248                   FT_Byte*   table )
2249   {
2250     cmap->cmap.data  = table;
2251 
2252     table           += 12;
2253     cmap->num_groups = FT_PEEK_ULONG( table );
2254 
2255     cmap->valid      = 0;
2256 
2257     return FT_Err_Ok;
2258   }
2259 
2260 
2261   FT_CALLBACK_DEF( FT_Error )
2262   tt_cmap12_validate( FT_Byte*      table,
2263                       FT_Validator  valid )
2264   {
2265     FT_Byte*  p;
2266     FT_ULong  length;
2267     FT_ULong  num_groups;
2268 
2269 
2270     if ( table + 16 > valid->limit )
2271       FT_INVALID_TOO_SHORT;
2272 
2273     p      = table + 4;
2274     length = TT_NEXT_ULONG( p );
2275 
2276     p          = table + 12;
2277     num_groups = TT_NEXT_ULONG( p );
2278 
2279     if ( length > (FT_ULong)( valid->limit - table ) ||
2280          /* length < 16 + 12 * num_groups ? */
2281          length < 16                                 ||
2282          ( length - 16 ) / 12 < num_groups           )
2283       FT_INVALID_TOO_SHORT;
2284 
2285     /* check groups, they must be in increasing order */
2286     {
2287       FT_ULong  n, start, end, start_id, last = 0;
2288 
2289 
2290       for ( n = 0; n < num_groups; n++ )
2291       {
2292         start    = TT_NEXT_ULONG( p );
2293         end      = TT_NEXT_ULONG( p );
2294         start_id = TT_NEXT_ULONG( p );
2295 
2296         if ( start > end )
2297           FT_INVALID_DATA;
2298 
2299         if ( n > 0 && start <= last )
2300           FT_INVALID_DATA;
2301 
2302         if ( valid->level >= FT_VALIDATE_TIGHT )
2303         {
2304           FT_UInt32  d = end - start;
2305 
2306 
2307           /* start_id + end - start >= TT_VALID_GLYPH_COUNT( valid ) ? */
2308           if ( d > TT_VALID_GLYPH_COUNT( valid )             ||
2309                start_id >= TT_VALID_GLYPH_COUNT( valid ) - d )
2310             FT_INVALID_GLYPH_ID;
2311         }
2312 
2313         last = end;
2314       }
2315     }
2316 
2317     return FT_Err_Ok;
2318   }
2319 
2320 
2321   /* search the index of the charcode next to cmap->cur_charcode */
2322   /* cmap->cur_group should be set up properly by caller         */
2323   /*                                                             */
2324   static void
2325   tt_cmap12_next( TT_CMap12  cmap )
2326   {
2327     FT_Face   face = cmap->cmap.cmap.charmap.face;
2328     FT_Byte*  p;
2329     FT_ULong  start, end, start_id, char_code;
2330     FT_ULong  n;
2331     FT_UInt   gindex;
2332 
2333 
2334     if ( cmap->cur_charcode >= 0xFFFFFFFFUL )
2335       goto Fail;
2336 
2337     char_code = cmap->cur_charcode + 1;
2338 
2339     for ( n = cmap->cur_group; n < cmap->num_groups; n++ )
2340     {
2341       p        = cmap->cmap.data + 16 + 12 * n;
2342       start    = TT_NEXT_ULONG( p );
2343       end      = TT_NEXT_ULONG( p );
2344       start_id = TT_PEEK_ULONG( p );
2345 
2346       if ( char_code < start )
2347         char_code = start;
2348 
2349     Again:
2350       if ( char_code <= end )
2351       {
2352         /* ignore invalid group */
2353         if ( start_id > 0xFFFFFFFFUL - ( char_code - start ) )
2354           continue;
2355 
2356         gindex = (FT_UInt)( start_id + ( char_code - start ) );
2357 
2358         /* does first element of group point to `.notdef' glyph? */
2359         if ( gindex == 0 )
2360         {
2361           if ( char_code >= 0xFFFFFFFFUL )
2362             goto Fail;
2363 
2364           char_code++;
2365           goto Again;
2366         }
2367 
2368         /* if `gindex' is invalid, the remaining values */
2369         /* in this group are invalid, too               */
2370         if ( gindex >= (FT_UInt)face->num_glyphs )
2371         {
2372           gindex = 0;
2373           continue;
2374         }
2375 
2376         cmap->cur_charcode = char_code;
2377         cmap->cur_gindex   = gindex;
2378         cmap->cur_group    = n;
2379 
2380         return;
2381       }
2382     }
2383 
2384   Fail:
2385     cmap->valid = 0;
2386   }
2387 
2388 
2389   static FT_UInt
2390   tt_cmap12_char_map_binary( TT_CMap     cmap,
2391                              FT_UInt32*  pchar_code,
2392                              FT_Bool     next )
2393   {
2394     FT_UInt    gindex     = 0;
2395     FT_Byte*   p          = cmap->data + 12;
2396     FT_UInt32  num_groups = TT_PEEK_ULONG( p );
2397     FT_UInt32  char_code  = *pchar_code;
2398     FT_UInt32  start, end, start_id;
2399     FT_UInt32  max, min, mid;
2400 
2401 
2402     if ( !num_groups )
2403       return 0;
2404 
2405     /* make compiler happy */
2406     mid = num_groups;
2407     end = 0xFFFFFFFFUL;
2408 
2409     if ( next )
2410     {
2411       if ( char_code >= 0xFFFFFFFFUL )
2412         return 0;
2413 
2414       char_code++;
2415     }
2416 
2417     min = 0;
2418     max = num_groups;
2419 
2420     /* binary search */
2421     while ( min < max )
2422     {
2423       mid = ( min + max ) >> 1;
2424       p   = cmap->data + 16 + 12 * mid;
2425 
2426       start = TT_NEXT_ULONG( p );
2427       end   = TT_NEXT_ULONG( p );
2428 
2429       if ( char_code < start )
2430         max = mid;
2431       else if ( char_code > end )
2432         min = mid + 1;
2433       else
2434       {
2435         start_id = TT_PEEK_ULONG( p );
2436 
2437         /* reject invalid glyph index */
2438         if ( start_id > 0xFFFFFFFFUL - ( char_code - start ) )
2439           gindex = 0;
2440         else
2441           gindex = (FT_UInt)( start_id + ( char_code - start ) );
2442         break;
2443       }
2444     }
2445 
2446     if ( next )
2447     {
2448       FT_Face    face   = cmap->cmap.charmap.face;
2449       TT_CMap12  cmap12 = (TT_CMap12)cmap;
2450 
2451 
2452       /* if `char_code' is not in any group, then `mid' is */
2453       /* the group nearest to `char_code'                  */
2454 
2455       if ( char_code > end )
2456       {
2457         mid++;
2458         if ( mid == num_groups )
2459           return 0;
2460       }
2461 
2462       cmap12->valid        = 1;
2463       cmap12->cur_charcode = char_code;
2464       cmap12->cur_group    = mid;
2465 
2466       if ( gindex >= (FT_UInt)face->num_glyphs )
2467         gindex = 0;
2468 
2469       if ( !gindex )
2470       {
2471         tt_cmap12_next( cmap12 );
2472 
2473         if ( cmap12->valid )
2474           gindex = cmap12->cur_gindex;
2475       }
2476       else
2477         cmap12->cur_gindex = gindex;
2478 
2479       *pchar_code = cmap12->cur_charcode;
2480     }
2481 
2482     return gindex;
2483   }
2484 
2485 
2486   FT_CALLBACK_DEF( FT_UInt )
2487   tt_cmap12_char_index( TT_CMap    cmap,
2488                         FT_UInt32  char_code )
2489   {
2490     return tt_cmap12_char_map_binary( cmap, &char_code, 0 );
2491   }
2492 
2493 
2494   FT_CALLBACK_DEF( FT_UInt32 )
2495   tt_cmap12_char_next( TT_CMap     cmap,
2496                        FT_UInt32  *pchar_code )
2497   {
2498     TT_CMap12  cmap12 = (TT_CMap12)cmap;
2499     FT_UInt    gindex;
2500 
2501 
2502     /* no need to search */
2503     if ( cmap12->valid && cmap12->cur_charcode == *pchar_code )
2504     {
2505       tt_cmap12_next( cmap12 );
2506       if ( cmap12->valid )
2507       {
2508         gindex      = cmap12->cur_gindex;
2509         *pchar_code = (FT_UInt32)cmap12->cur_charcode;
2510       }
2511       else
2512         gindex = 0;
2513     }
2514     else
2515       gindex = tt_cmap12_char_map_binary( cmap, pchar_code, 1 );
2516 
2517     return gindex;
2518   }
2519 
2520 
2521   FT_CALLBACK_DEF( FT_Error )
2522   tt_cmap12_get_info( TT_CMap       cmap,
2523                       TT_CMapInfo  *cmap_info )
2524   {
2525     FT_Byte*  p = cmap->data + 8;
2526 
2527 
2528     cmap_info->format   = 12;
2529     cmap_info->language = (FT_ULong)TT_PEEK_ULONG( p );
2530 
2531     return FT_Err_Ok;
2532   }
2533 
2534 
2535   FT_DEFINE_TT_CMAP(
2536     tt_cmap12_class_rec,
2537 
2538       sizeof ( TT_CMap12Rec ),
2539 
2540       (FT_CMap_InitFunc)     tt_cmap12_init,        /* init       */
2541       (FT_CMap_DoneFunc)     NULL,                  /* done       */
2542       (FT_CMap_CharIndexFunc)tt_cmap12_char_index,  /* char_index */
2543       (FT_CMap_CharNextFunc) tt_cmap12_char_next,   /* char_next  */
2544 
2545       (FT_CMap_CharVarIndexFunc)    NULL,  /* char_var_index   */
2546       (FT_CMap_CharVarIsDefaultFunc)NULL,  /* char_var_default */
2547       (FT_CMap_VariantListFunc)     NULL,  /* variant_list     */
2548       (FT_CMap_CharVariantListFunc) NULL,  /* charvariant_list */
2549       (FT_CMap_VariantCharListFunc) NULL,  /* variantchar_list */
2550 
2551     12,
2552     (TT_CMap_ValidateFunc)tt_cmap12_validate,  /* validate      */
2553     (TT_CMap_Info_GetFunc)tt_cmap12_get_info   /* get_cmap_info */
2554   )
2555 
2556 #endif /* TT_CONFIG_CMAP_FORMAT_12 */
2557 
2558 
2559   /*************************************************************************/
2560   /*************************************************************************/
2561   /*****                                                               *****/
2562   /*****                          FORMAT 13                            *****/
2563   /*****                                                               *****/
2564   /*************************************************************************/
2565   /*************************************************************************/
2566 
2567   /**************************************************************************
2568    *
2569    * TABLE OVERVIEW
2570    * --------------
2571    *
2572    *   NAME        OFFSET     TYPE       DESCRIPTION
2573    *
2574    *   format      0          USHORT     must be 13
2575    *   reserved    2          USHORT     reserved
2576    *   length      4          ULONG      length in bytes
2577    *   language    8          ULONG      Mac language code
2578    *   count       12         ULONG      number of groups
2579    *               16
2580    *
2581    * This header is followed by `count' groups of the following format:
2582    *
2583    *   start       0          ULONG      first charcode
2584    *   end         4          ULONG      last charcode
2585    *   glyphId     8          ULONG      glyph ID for the whole group
2586    */
2587 
2588 #ifdef TT_CONFIG_CMAP_FORMAT_13
2589 
2590   typedef struct  TT_CMap13Rec_
2591   {
2592     TT_CMapRec  cmap;
2593     FT_Bool     valid;
2594     FT_ULong    cur_charcode;
2595     FT_UInt     cur_gindex;
2596     FT_ULong    cur_group;
2597     FT_ULong    num_groups;
2598 
2599   } TT_CMap13Rec, *TT_CMap13;
2600 
2601 
2602   FT_CALLBACK_DEF( FT_Error )
2603   tt_cmap13_init( TT_CMap13  cmap,
2604                   FT_Byte*   table )
2605   {
2606     cmap->cmap.data  = table;
2607 
2608     table           += 12;
2609     cmap->num_groups = FT_PEEK_ULONG( table );
2610 
2611     cmap->valid      = 0;
2612 
2613     return FT_Err_Ok;
2614   }
2615 
2616 
2617   FT_CALLBACK_DEF( FT_Error )
2618   tt_cmap13_validate( FT_Byte*      table,
2619                       FT_Validator  valid )
2620   {
2621     FT_Byte*  p;
2622     FT_ULong  length;
2623     FT_ULong  num_groups;
2624 
2625 
2626     if ( table + 16 > valid->limit )
2627       FT_INVALID_TOO_SHORT;
2628 
2629     p      = table + 4;
2630     length = TT_NEXT_ULONG( p );
2631 
2632     p          = table + 12;
2633     num_groups = TT_NEXT_ULONG( p );
2634 
2635     if ( length > (FT_ULong)( valid->limit - table ) ||
2636          /* length < 16 + 12 * num_groups ? */
2637          length < 16                                 ||
2638          ( length - 16 ) / 12 < num_groups           )
2639       FT_INVALID_TOO_SHORT;
2640 
2641     /* check groups, they must be in increasing order */
2642     {
2643       FT_ULong  n, start, end, glyph_id, last = 0;
2644 
2645 
2646       for ( n = 0; n < num_groups; n++ )
2647       {
2648         start    = TT_NEXT_ULONG( p );
2649         end      = TT_NEXT_ULONG( p );
2650         glyph_id = TT_NEXT_ULONG( p );
2651 
2652         if ( start > end )
2653           FT_INVALID_DATA;
2654 
2655         if ( n > 0 && start <= last )
2656           FT_INVALID_DATA;
2657 
2658         if ( valid->level >= FT_VALIDATE_TIGHT )
2659         {
2660           if ( glyph_id >= TT_VALID_GLYPH_COUNT( valid ) )
2661             FT_INVALID_GLYPH_ID;
2662         }
2663 
2664         last = end;
2665       }
2666     }
2667 
2668     return FT_Err_Ok;
2669   }
2670 
2671 
2672   /* search the index of the charcode next to cmap->cur_charcode */
2673   /* cmap->cur_group should be set up properly by caller         */
2674   /*                                                             */
2675   static void
2676   tt_cmap13_next( TT_CMap13  cmap )
2677   {
2678     FT_Face   face = cmap->cmap.cmap.charmap.face;
2679     FT_Byte*  p;
2680     FT_ULong  start, end, glyph_id, char_code;
2681     FT_ULong  n;
2682     FT_UInt   gindex;
2683 
2684 
2685     if ( cmap->cur_charcode >= 0xFFFFFFFFUL )
2686       goto Fail;
2687 
2688     char_code = cmap->cur_charcode + 1;
2689 
2690     for ( n = cmap->cur_group; n < cmap->num_groups; n++ )
2691     {
2692       p        = cmap->cmap.data + 16 + 12 * n;
2693       start    = TT_NEXT_ULONG( p );
2694       end      = TT_NEXT_ULONG( p );
2695       glyph_id = TT_PEEK_ULONG( p );
2696 
2697       if ( char_code < start )
2698         char_code = start;
2699 
2700       if ( char_code <= end )
2701       {
2702         gindex = (FT_UInt)glyph_id;
2703 
2704         if ( gindex && gindex < (FT_UInt)face->num_glyphs )
2705         {
2706           cmap->cur_charcode = char_code;
2707           cmap->cur_gindex   = gindex;
2708           cmap->cur_group    = n;
2709 
2710           return;
2711         }
2712       }
2713     }
2714 
2715   Fail:
2716     cmap->valid = 0;
2717   }
2718 
2719 
2720   static FT_UInt
2721   tt_cmap13_char_map_binary( TT_CMap     cmap,
2722                              FT_UInt32*  pchar_code,
2723                              FT_Bool     next )
2724   {
2725     FT_UInt    gindex     = 0;
2726     FT_Byte*   p          = cmap->data + 12;
2727     FT_UInt32  num_groups = TT_PEEK_ULONG( p );
2728     FT_UInt32  char_code  = *pchar_code;
2729     FT_UInt32  start, end;
2730     FT_UInt32  max, min, mid;
2731 
2732 
2733     if ( !num_groups )
2734       return 0;
2735 
2736     /* make compiler happy */
2737     mid = num_groups;
2738     end = 0xFFFFFFFFUL;
2739 
2740     if ( next )
2741     {
2742       if ( char_code >= 0xFFFFFFFFUL )
2743         return 0;
2744 
2745       char_code++;
2746     }
2747 
2748     min = 0;
2749     max = num_groups;
2750 
2751     /* binary search */
2752     while ( min < max )
2753     {
2754       mid = ( min + max ) >> 1;
2755       p   = cmap->data + 16 + 12 * mid;
2756 
2757       start = TT_NEXT_ULONG( p );
2758       end   = TT_NEXT_ULONG( p );
2759 
2760       if ( char_code < start )
2761         max = mid;
2762       else if ( char_code > end )
2763         min = mid + 1;
2764       else
2765       {
2766         gindex = (FT_UInt)TT_PEEK_ULONG( p );
2767 
2768         break;
2769       }
2770     }
2771 
2772     if ( next )
2773     {
2774       FT_Face    face   = cmap->cmap.charmap.face;
2775       TT_CMap13  cmap13 = (TT_CMap13)cmap;
2776 
2777 
2778       /* if `char_code' is not in any group, then `mid' is */
2779       /* the group nearest to `char_code'                  */
2780 
2781       if ( char_code > end )
2782       {
2783         mid++;
2784         if ( mid == num_groups )
2785           return 0;
2786       }
2787 
2788       cmap13->valid        = 1;
2789       cmap13->cur_charcode = char_code;
2790       cmap13->cur_group    = mid;
2791 
2792       if ( gindex >= (FT_UInt)face->num_glyphs )
2793         gindex = 0;
2794 
2795       if ( !gindex )
2796       {
2797         tt_cmap13_next( cmap13 );
2798 
2799         if ( cmap13->valid )
2800           gindex = cmap13->cur_gindex;
2801       }
2802       else
2803         cmap13->cur_gindex = gindex;
2804 
2805       *pchar_code = cmap13->cur_charcode;
2806     }
2807 
2808     return gindex;
2809   }
2810 
2811 
2812   FT_CALLBACK_DEF( FT_UInt )
2813   tt_cmap13_char_index( TT_CMap    cmap,
2814                         FT_UInt32  char_code )
2815   {
2816     return tt_cmap13_char_map_binary( cmap, &char_code, 0 );
2817   }
2818 
2819 
2820   FT_CALLBACK_DEF( FT_UInt32 )
2821   tt_cmap13_char_next( TT_CMap     cmap,
2822                        FT_UInt32  *pchar_code )
2823   {
2824     TT_CMap13  cmap13 = (TT_CMap13)cmap;
2825     FT_UInt    gindex;
2826 
2827 
2828     /* no need to search */
2829     if ( cmap13->valid && cmap13->cur_charcode == *pchar_code )
2830     {
2831       tt_cmap13_next( cmap13 );
2832       if ( cmap13->valid )
2833       {
2834         gindex      = cmap13->cur_gindex;
2835         *pchar_code = cmap13->cur_charcode;
2836       }
2837       else
2838         gindex = 0;
2839     }
2840     else
2841       gindex = tt_cmap13_char_map_binary( cmap, pchar_code, 1 );
2842 
2843     return gindex;
2844   }
2845 
2846 
2847   FT_CALLBACK_DEF( FT_Error )
2848   tt_cmap13_get_info( TT_CMap       cmap,
2849                       TT_CMapInfo  *cmap_info )
2850   {
2851     FT_Byte*  p = cmap->data + 8;
2852 
2853 
2854     cmap_info->format   = 13;
2855     cmap_info->language = (FT_ULong)TT_PEEK_ULONG( p );
2856 
2857     return FT_Err_Ok;
2858   }
2859 
2860 
2861   FT_DEFINE_TT_CMAP(
2862     tt_cmap13_class_rec,
2863 
2864       sizeof ( TT_CMap13Rec ),
2865 
2866       (FT_CMap_InitFunc)     tt_cmap13_init,        /* init       */
2867       (FT_CMap_DoneFunc)     NULL,                  /* done       */
2868       (FT_CMap_CharIndexFunc)tt_cmap13_char_index,  /* char_index */
2869       (FT_CMap_CharNextFunc) tt_cmap13_char_next,   /* char_next  */
2870 
2871       (FT_CMap_CharVarIndexFunc)    NULL,  /* char_var_index   */
2872       (FT_CMap_CharVarIsDefaultFunc)NULL,  /* char_var_default */
2873       (FT_CMap_VariantListFunc)     NULL,  /* variant_list     */
2874       (FT_CMap_CharVariantListFunc) NULL,  /* charvariant_list */
2875       (FT_CMap_VariantCharListFunc) NULL,  /* variantchar_list */
2876 
2877     13,
2878     (TT_CMap_ValidateFunc)tt_cmap13_validate,  /* validate      */
2879     (TT_CMap_Info_GetFunc)tt_cmap13_get_info   /* get_cmap_info */
2880   )
2881 
2882 #endif /* TT_CONFIG_CMAP_FORMAT_13 */
2883 
2884 
2885   /*************************************************************************/
2886   /*************************************************************************/
2887   /*****                                                               *****/
2888   /*****                           FORMAT 14                           *****/
2889   /*****                                                               *****/
2890   /*************************************************************************/
2891   /*************************************************************************/
2892 
2893   /**************************************************************************
2894    *
2895    * TABLE OVERVIEW
2896    * --------------
2897    *
2898    *   NAME         OFFSET  TYPE    DESCRIPTION
2899    *
2900    *   format         0     USHORT  must be 14
2901    *   length         2     ULONG   table length in bytes
2902    *   numSelector    6     ULONG   number of variation sel. records
2903    *
2904    * Followed by numSelector records, each of which looks like
2905    *
2906    *   varSelector    0     UINT24  Unicode codepoint of sel.
2907    *   defaultOff     3     ULONG   offset to a default UVS table
2908    *                                describing any variants to be found in
2909    *                                the normal Unicode subtable.
2910    *   nonDefOff      7     ULONG   offset to a non-default UVS table
2911    *                                describing any variants not in the
2912    *                                standard cmap, with GIDs here
2913    * (either offset may be 0 NULL)
2914    *
2915    * Selectors are sorted by code point.
2916    *
2917    * A default Unicode Variation Selector (UVS) subtable is just a list of
2918    * ranges of code points which are to be found in the standard cmap.  No
2919    * glyph IDs (GIDs) here.
2920    *
2921    *   numRanges      0     ULONG   number of ranges following
2922    *
2923    * A range looks like
2924    *
2925    *   uniStart       0     UINT24  code point of the first character in
2926    *                                this range
2927    *   additionalCnt  3     UBYTE   count of additional characters in this
2928    *                                range (zero means a range of a single
2929    *                                character)
2930    *
2931    * Ranges are sorted by `uniStart'.
2932    *
2933    * A non-default Unicode Variation Selector (UVS) subtable is a list of
2934    * mappings from codepoint to GID.
2935    *
2936    *   numMappings    0     ULONG   number of mappings
2937    *
2938    * A range looks like
2939    *
2940    *   uniStart       0     UINT24  code point of the first character in
2941    *                                this range
2942    *   GID            3     USHORT  and its GID
2943    *
2944    * Ranges are sorted by `uniStart'.
2945    */
2946 
2947 #ifdef TT_CONFIG_CMAP_FORMAT_14
2948 
2949   typedef struct  TT_CMap14Rec_
2950   {
2951     TT_CMapRec  cmap;
2952     FT_ULong    num_selectors;
2953 
2954     /* This array is used to store the results of various
2955      * cmap 14 query functions.  The data is overwritten
2956      * on each call to these functions.
2957      */
2958     FT_UInt32   max_results;
2959     FT_UInt32*  results;
2960     FT_Memory   memory;
2961 
2962   } TT_CMap14Rec, *TT_CMap14;
2963 
2964 
2965   FT_CALLBACK_DEF( void )
2966   tt_cmap14_done( TT_CMap14  cmap )
2967   {
2968     FT_Memory  memory = cmap->memory;
2969 
2970 
2971     cmap->max_results = 0;
2972     if ( memory && cmap->results )
2973       FT_FREE( cmap->results );
2974   }
2975 
2976 
2977   static FT_Error
2978   tt_cmap14_ensure( TT_CMap14  cmap,
2979                     FT_UInt32  num_results,
2980                     FT_Memory  memory )
2981   {
2982     FT_UInt32  old_max = cmap->max_results;
2983     FT_Error   error   = FT_Err_Ok;
2984 
2985 
2986     if ( num_results > cmap->max_results )
2987     {
2988        cmap->memory = memory;
2989 
2990        if ( FT_QRENEW_ARRAY( cmap->results, old_max, num_results ) )
2991          return error;
2992 
2993        cmap->max_results = num_results;
2994     }
2995 
2996     return error;
2997   }
2998 
2999 
3000   FT_CALLBACK_DEF( FT_Error )
3001   tt_cmap14_init( TT_CMap14  cmap,
3002                   FT_Byte*   table )
3003   {
3004     cmap->cmap.data = table;
3005 
3006     table               += 6;
3007     cmap->num_selectors  = FT_PEEK_ULONG( table );
3008     cmap->max_results    = 0;
3009     cmap->results        = NULL;
3010 
3011     return FT_Err_Ok;
3012   }
3013 
3014 
3015   FT_CALLBACK_DEF( FT_Error )
3016   tt_cmap14_validate( FT_Byte*      table,
3017                       FT_Validator  valid )
3018   {
3019     FT_Byte*  p;
3020     FT_ULong  length;
3021     FT_ULong  num_selectors;
3022 
3023 
3024     if ( table + 2 + 4 + 4 > valid->limit )
3025       FT_INVALID_TOO_SHORT;
3026 
3027     p             = table + 2;
3028     length        = TT_NEXT_ULONG( p );
3029     num_selectors = TT_NEXT_ULONG( p );
3030 
3031     if ( length > (FT_ULong)( valid->limit - table ) ||
3032          /* length < 10 + 11 * num_selectors ? */
3033          length < 10                                 ||
3034          ( length - 10 ) / 11 < num_selectors        )
3035       FT_INVALID_TOO_SHORT;
3036 
3037     /* check selectors, they must be in increasing order */
3038     {
3039       /* we start lastVarSel at 1 because a variant selector value of 0
3040        * isn't valid.
3041        */
3042       FT_ULong  n, lastVarSel = 1;
3043 
3044 
3045       for ( n = 0; n < num_selectors; n++ )
3046       {
3047         FT_ULong  varSel    = TT_NEXT_UINT24( p );
3048         FT_ULong  defOff    = TT_NEXT_ULONG( p );
3049         FT_ULong  nondefOff = TT_NEXT_ULONG( p );
3050 
3051 
3052         if ( defOff >= length || nondefOff >= length )
3053           FT_INVALID_TOO_SHORT;
3054 
3055         if ( varSel < lastVarSel )
3056           FT_INVALID_DATA;
3057 
3058         lastVarSel = varSel + 1;
3059 
3060         /* check the default table (these glyphs should be reached     */
3061         /* through the normal Unicode cmap, no GIDs, just check order) */
3062         if ( defOff != 0 )
3063         {
3064           FT_Byte*  defp     = table + defOff;
3065           FT_ULong  numRanges;
3066           FT_ULong  i;
3067           FT_ULong  lastBase = 0;
3068 
3069 
3070           if ( defp + 4 > valid->limit )
3071             FT_INVALID_TOO_SHORT;
3072 
3073           numRanges = TT_NEXT_ULONG( defp );
3074 
3075           /* defp + numRanges * 4 > valid->limit ? */
3076           if ( numRanges > (FT_ULong)( valid->limit - defp ) / 4 )
3077             FT_INVALID_TOO_SHORT;
3078 
3079           for ( i = 0; i < numRanges; i++ )
3080           {
3081             FT_ULong  base = TT_NEXT_UINT24( defp );
3082             FT_ULong  cnt  = FT_NEXT_BYTE( defp );
3083 
3084 
3085             if ( base + cnt >= 0x110000UL )              /* end of Unicode */
3086               FT_INVALID_DATA;
3087 
3088             if ( base < lastBase )
3089               FT_INVALID_DATA;
3090 
3091             lastBase = base + cnt + 1U;
3092           }
3093         }
3094 
3095         /* and the non-default table (these glyphs are specified here) */
3096         if ( nondefOff != 0 )
3097         {
3098           FT_Byte*  ndp        = table + nondefOff;
3099           FT_ULong  numMappings;
3100           FT_ULong  i, lastUni = 0;
3101 
3102 
3103           if ( ndp + 4 > valid->limit )
3104             FT_INVALID_TOO_SHORT;
3105 
3106           numMappings = TT_NEXT_ULONG( ndp );
3107 
3108           /* numMappings * 5 > (FT_ULong)( valid->limit - ndp ) ? */
3109           if ( numMappings > ( (FT_ULong)( valid->limit - ndp ) ) / 5 )
3110             FT_INVALID_TOO_SHORT;
3111 
3112           for ( i = 0; i < numMappings; i++ )
3113           {
3114             FT_ULong  uni = TT_NEXT_UINT24( ndp );
3115             FT_ULong  gid = TT_NEXT_USHORT( ndp );
3116 
3117 
3118             if ( uni >= 0x110000UL )                     /* end of Unicode */
3119               FT_INVALID_DATA;
3120 
3121             if ( uni < lastUni )
3122               FT_INVALID_DATA;
3123 
3124             lastUni = uni + 1U;
3125 
3126             if ( valid->level >= FT_VALIDATE_TIGHT    &&
3127                  gid >= TT_VALID_GLYPH_COUNT( valid ) )
3128               FT_INVALID_GLYPH_ID;
3129           }
3130         }
3131       }
3132     }
3133 
3134     return FT_Err_Ok;
3135   }
3136 
3137 
3138   FT_CALLBACK_DEF( FT_UInt )
3139   tt_cmap14_char_index( TT_CMap    cmap,
3140                         FT_UInt32  char_code )
3141   {
3142     FT_UNUSED( cmap );
3143     FT_UNUSED( char_code );
3144 
3145     /* This can't happen */
3146     return 0;
3147   }
3148 
3149 
3150   FT_CALLBACK_DEF( FT_UInt32 )
3151   tt_cmap14_char_next( TT_CMap     cmap,
3152                        FT_UInt32  *pchar_code )
3153   {
3154     FT_UNUSED( cmap );
3155 
3156     /* This can't happen */
3157     *pchar_code = 0;
3158     return 0;
3159   }
3160 
3161 
3162   FT_CALLBACK_DEF( FT_Error )
3163   tt_cmap14_get_info( TT_CMap       cmap,
3164                       TT_CMapInfo  *cmap_info )
3165   {
3166     FT_UNUSED( cmap );
3167 
3168     cmap_info->format   = 14;
3169     /* subtable 14 does not define a language field */
3170     cmap_info->language = 0xFFFFFFFFUL;
3171 
3172     return FT_Err_Ok;
3173   }
3174 
3175 
3176   static FT_UInt
3177   tt_cmap14_char_map_def_binary( FT_Byte    *base,
3178                                  FT_UInt32   char_code )
3179   {
3180     FT_UInt32  numRanges = TT_PEEK_ULONG( base );
3181     FT_UInt32  max, min;
3182 
3183 
3184     min = 0;
3185     max = numRanges;
3186 
3187     base += 4;
3188 
3189     /* binary search */
3190     while ( min < max )
3191     {
3192       FT_UInt32  mid   = ( min + max ) >> 1;
3193       FT_Byte*   p     = base + 4 * mid;
3194       FT_ULong   start = TT_NEXT_UINT24( p );
3195       FT_UInt    cnt   = FT_NEXT_BYTE( p );
3196 
3197 
3198       if ( char_code < start )
3199         max = mid;
3200       else if ( char_code > start + cnt )
3201         min = mid + 1;
3202       else
3203         return TRUE;
3204     }
3205 
3206     return FALSE;
3207   }
3208 
3209 
3210   static FT_UInt
3211   tt_cmap14_char_map_nondef_binary( FT_Byte    *base,
3212                                     FT_UInt32   char_code )
3213   {
3214     FT_UInt32  numMappings = TT_PEEK_ULONG( base );
3215     FT_UInt32  max, min;
3216 
3217 
3218     min = 0;
3219     max = numMappings;
3220 
3221     base += 4;
3222 
3223     /* binary search */
3224     while ( min < max )
3225     {
3226       FT_UInt32  mid = ( min + max ) >> 1;
3227       FT_Byte*   p   = base + 5 * mid;
3228       FT_UInt32  uni = (FT_UInt32)TT_NEXT_UINT24( p );
3229 
3230 
3231       if ( char_code < uni )
3232         max = mid;
3233       else if ( char_code > uni )
3234         min = mid + 1;
3235       else
3236         return TT_PEEK_USHORT( p );
3237     }
3238 
3239     return 0;
3240   }
3241 
3242 
3243   static FT_Byte*
3244   tt_cmap14_find_variant( FT_Byte    *base,
3245                           FT_UInt32   variantCode )
3246   {
3247     FT_UInt32  numVar = TT_PEEK_ULONG( base );
3248     FT_UInt32  max, min;
3249 
3250 
3251     min = 0;
3252     max = numVar;
3253 
3254     base += 4;
3255 
3256     /* binary search */
3257     while ( min < max )
3258     {
3259       FT_UInt32  mid    = ( min + max ) >> 1;
3260       FT_Byte*   p      = base + 11 * mid;
3261       FT_ULong   varSel = TT_NEXT_UINT24( p );
3262 
3263 
3264       if ( variantCode < varSel )
3265         max = mid;
3266       else if ( variantCode > varSel )
3267         min = mid + 1;
3268       else
3269         return p;
3270     }
3271 
3272     return NULL;
3273   }
3274 
3275 
3276   FT_CALLBACK_DEF( FT_UInt )
3277   tt_cmap14_char_var_index( TT_CMap    cmap,
3278                             TT_CMap    ucmap,
3279                             FT_UInt32  charcode,
3280                             FT_UInt32  variantSelector )
3281   {
3282     FT_Byte*  p = tt_cmap14_find_variant( cmap->data + 6, variantSelector );
3283     FT_ULong  defOff;
3284     FT_ULong  nondefOff;
3285 
3286 
3287     if ( !p )
3288       return 0;
3289 
3290     defOff    = TT_NEXT_ULONG( p );
3291     nondefOff = TT_PEEK_ULONG( p );
3292 
3293     if ( defOff != 0                                                    &&
3294          tt_cmap14_char_map_def_binary( cmap->data + defOff, charcode ) )
3295     {
3296       /* This is the default variant of this charcode.  GID not stored */
3297       /* here; stored in the normal Unicode charmap instead.           */
3298       return ucmap->cmap.clazz->char_index( &ucmap->cmap, charcode );
3299     }
3300 
3301     if ( nondefOff != 0 )
3302       return tt_cmap14_char_map_nondef_binary( cmap->data + nondefOff,
3303                                                charcode );
3304 
3305     return 0;
3306   }
3307 
3308 
3309   FT_CALLBACK_DEF( FT_Int )
3310   tt_cmap14_char_var_isdefault( TT_CMap    cmap,
3311                                 FT_UInt32  charcode,
3312                                 FT_UInt32  variantSelector )
3313   {
3314     FT_Byte*  p = tt_cmap14_find_variant( cmap->data + 6, variantSelector );
3315     FT_ULong  defOff;
3316     FT_ULong  nondefOff;
3317 
3318 
3319     if ( !p )
3320       return -1;
3321 
3322     defOff    = TT_NEXT_ULONG( p );
3323     nondefOff = TT_NEXT_ULONG( p );
3324 
3325     if ( defOff != 0                                                    &&
3326          tt_cmap14_char_map_def_binary( cmap->data + defOff, charcode ) )
3327       return 1;
3328 
3329     if ( nondefOff != 0                                            &&
3330          tt_cmap14_char_map_nondef_binary( cmap->data + nondefOff,
3331                                            charcode ) != 0         )
3332       return 0;
3333 
3334     return -1;
3335   }
3336 
3337 
3338   FT_CALLBACK_DEF( FT_UInt32* )
3339   tt_cmap14_variants( TT_CMap    cmap,
3340                       FT_Memory  memory )
3341   {
3342     TT_CMap14   cmap14 = (TT_CMap14)cmap;
3343     FT_UInt32   count  = cmap14->num_selectors;
3344     FT_Byte*    p      = cmap->data + 10;
3345     FT_UInt32*  result;
3346     FT_UInt32   i;
3347 
3348 
3349     if ( tt_cmap14_ensure( cmap14, ( count + 1 ), memory ) )
3350       return NULL;
3351 
3352     result = cmap14->results;
3353     for ( i = 0; i < count; i++ )
3354     {
3355       result[i] = (FT_UInt32)TT_NEXT_UINT24( p );
3356       p        += 8;
3357     }
3358     result[i] = 0;
3359 
3360     return result;
3361   }
3362 
3363 
3364   FT_CALLBACK_DEF( FT_UInt32 * )
3365   tt_cmap14_char_variants( TT_CMap    cmap,
3366                            FT_Memory  memory,
3367                            FT_UInt32  charCode )
3368   {
3369     TT_CMap14   cmap14 = (TT_CMap14)  cmap;
3370     FT_UInt32   count  = cmap14->num_selectors;
3371     FT_Byte*    p      = cmap->data + 10;
3372     FT_UInt32*  q;
3373 
3374 
3375     if ( tt_cmap14_ensure( cmap14, ( count + 1 ), memory ) )
3376       return NULL;
3377 
3378     for ( q = cmap14->results; count > 0; count-- )
3379     {
3380       FT_UInt32  varSel    = TT_NEXT_UINT24( p );
3381       FT_ULong   defOff    = TT_NEXT_ULONG( p );
3382       FT_ULong   nondefOff = TT_NEXT_ULONG( p );
3383 
3384 
3385       if ( ( defOff != 0                                               &&
3386              tt_cmap14_char_map_def_binary( cmap->data + defOff,
3387                                             charCode )                 ) ||
3388            ( nondefOff != 0                                            &&
3389              tt_cmap14_char_map_nondef_binary( cmap->data + nondefOff,
3390                                                charCode ) != 0         ) )
3391       {
3392         q[0] = varSel;
3393         q++;
3394       }
3395     }
3396     q[0] = 0;
3397 
3398     return cmap14->results;
3399   }
3400 
3401 
3402   static FT_UInt
3403   tt_cmap14_def_char_count( FT_Byte  *p )
3404   {
3405     FT_UInt32  numRanges = (FT_UInt32)TT_NEXT_ULONG( p );
3406     FT_UInt    tot       = 0;
3407 
3408 
3409     p += 3;  /* point to the first `cnt' field */
3410     for ( ; numRanges > 0; numRanges-- )
3411     {
3412       tot += 1 + p[0];
3413       p   += 4;
3414     }
3415 
3416     return tot;
3417   }
3418 
3419 
3420   static FT_UInt32*
3421   tt_cmap14_get_def_chars( TT_CMap    cmap,
3422                            FT_Byte*   p,
3423                            FT_Memory  memory )
3424   {
3425     TT_CMap14   cmap14 = (TT_CMap14) cmap;
3426     FT_UInt32   numRanges;
3427     FT_UInt     cnt;
3428     FT_UInt32*  q;
3429 
3430 
3431     cnt       = tt_cmap14_def_char_count( p );
3432     numRanges = (FT_UInt32)TT_NEXT_ULONG( p );
3433 
3434     if ( tt_cmap14_ensure( cmap14, ( cnt + 1 ), memory ) )
3435       return NULL;
3436 
3437     for ( q = cmap14->results; numRanges > 0; numRanges-- )
3438     {
3439       FT_UInt32  uni = (FT_UInt32)TT_NEXT_UINT24( p );
3440 
3441 
3442       cnt = FT_NEXT_BYTE( p ) + 1;
3443       do
3444       {
3445         q[0]  = uni;
3446         uni  += 1;
3447         q    += 1;
3448 
3449       } while ( --cnt != 0 );
3450     }
3451     q[0] = 0;
3452 
3453     return cmap14->results;
3454   }
3455 
3456 
3457   static FT_UInt32*
3458   tt_cmap14_get_nondef_chars( TT_CMap     cmap,
3459                               FT_Byte    *p,
3460                               FT_Memory   memory )
3461   {
3462     TT_CMap14   cmap14 = (TT_CMap14) cmap;
3463     FT_UInt32   numMappings;
3464     FT_UInt     i;
3465     FT_UInt32  *ret;
3466 
3467 
3468     numMappings = (FT_UInt32)TT_NEXT_ULONG( p );
3469 
3470     if ( tt_cmap14_ensure( cmap14, ( numMappings + 1 ), memory ) )
3471       return NULL;
3472 
3473     ret = cmap14->results;
3474     for ( i = 0; i < numMappings; i++ )
3475     {
3476       ret[i] = (FT_UInt32)TT_NEXT_UINT24( p );
3477       p += 2;
3478     }
3479     ret[i] = 0;
3480 
3481     return ret;
3482   }
3483 
3484 
3485   FT_CALLBACK_DEF( FT_UInt32 * )
3486   tt_cmap14_variant_chars( TT_CMap    cmap,
3487                            FT_Memory  memory,
3488                            FT_UInt32  variantSelector )
3489   {
3490     FT_Byte    *p  = tt_cmap14_find_variant( cmap->data + 6,
3491                                              variantSelector );
3492     FT_Int      i;
3493     FT_ULong    defOff;
3494     FT_ULong    nondefOff;
3495 
3496 
3497     if ( !p )
3498       return NULL;
3499 
3500     defOff    = TT_NEXT_ULONG( p );
3501     nondefOff = TT_NEXT_ULONG( p );
3502 
3503     if ( defOff == 0 && nondefOff == 0 )
3504       return NULL;
3505 
3506     if ( defOff == 0 )
3507       return tt_cmap14_get_nondef_chars( cmap, cmap->data + nondefOff,
3508                                          memory );
3509     else if ( nondefOff == 0 )
3510       return tt_cmap14_get_def_chars( cmap, cmap->data + defOff,
3511                                       memory );
3512     else
3513     {
3514       /* Both a default and a non-default glyph set?  That's probably not */
3515       /* good font design, but the spec allows for it...                  */
3516       TT_CMap14  cmap14 = (TT_CMap14) cmap;
3517       FT_UInt32  numRanges;
3518       FT_UInt32  numMappings;
3519       FT_UInt32  duni;
3520       FT_UInt32  dcnt;
3521       FT_UInt32  nuni;
3522       FT_Byte*   dp;
3523       FT_UInt    di, ni, k;
3524 
3525       FT_UInt32  *ret;
3526 
3527 
3528       p  = cmap->data + nondefOff;
3529       dp = cmap->data + defOff;
3530 
3531       numMappings = (FT_UInt32)TT_NEXT_ULONG( p );
3532       dcnt        = tt_cmap14_def_char_count( dp );
3533       numRanges   = (FT_UInt32)TT_NEXT_ULONG( dp );
3534 
3535       if ( numMappings == 0 )
3536         return tt_cmap14_get_def_chars( cmap, cmap->data + defOff,
3537                                         memory );
3538       if ( dcnt == 0 )
3539         return tt_cmap14_get_nondef_chars( cmap, cmap->data + nondefOff,
3540                                            memory );
3541 
3542       if ( tt_cmap14_ensure( cmap14, ( dcnt + numMappings + 1 ), memory ) )
3543         return NULL;
3544 
3545       ret  = cmap14->results;
3546       duni = (FT_UInt32)TT_NEXT_UINT24( dp );
3547       dcnt = FT_NEXT_BYTE( dp );
3548       di   = 1;
3549       nuni = (FT_UInt32)TT_NEXT_UINT24( p );
3550       p   += 2;
3551       ni   = 1;
3552       i    = 0;
3553 
3554       for (;;)
3555       {
3556         if ( nuni > duni + dcnt )
3557         {
3558           for ( k = 0; k <= dcnt; k++ )
3559             ret[i++] = duni + k;
3560 
3561           di++;
3562 
3563           if ( di > numRanges )
3564             break;
3565 
3566           duni = (FT_UInt32)TT_NEXT_UINT24( dp );
3567           dcnt = FT_NEXT_BYTE( dp );
3568         }
3569         else
3570         {
3571           if ( nuni < duni )
3572             ret[i++] = nuni;
3573           /* If it is within the default range then ignore it -- */
3574           /* that should not have happened                       */
3575           ni++;
3576           if ( ni > numMappings )
3577             break;
3578 
3579           nuni = (FT_UInt32)TT_NEXT_UINT24( p );
3580           p += 2;
3581         }
3582       }
3583 
3584       if ( ni <= numMappings )
3585       {
3586         /* If we get here then we have run out of all default ranges.   */
3587         /* We have read one non-default mapping which we haven't stored */
3588         /* and there may be others that need to be read.                */
3589         ret[i++] = nuni;
3590         while ( ni < numMappings )
3591         {
3592           ret[i++] = (FT_UInt32)TT_NEXT_UINT24( p );
3593           p += 2;
3594           ni++;
3595         }
3596       }
3597       else if ( di <= numRanges )
3598       {
3599         /* If we get here then we have run out of all non-default     */
3600         /* mappings.  We have read one default range which we haven't */
3601         /* stored and there may be others that need to be read.       */
3602         for ( k = 0; k <= dcnt; k++ )
3603           ret[i++] = duni + k;
3604 
3605         while ( di < numRanges )
3606         {
3607           duni = (FT_UInt32)TT_NEXT_UINT24( dp );
3608           dcnt = FT_NEXT_BYTE( dp );
3609 
3610           for ( k = 0; k <= dcnt; k++ )
3611             ret[i++] = duni + k;
3612           di++;
3613         }
3614       }
3615 
3616       ret[i] = 0;
3617 
3618       return ret;
3619     }
3620   }
3621 
3622 
3623   FT_DEFINE_TT_CMAP(
3624     tt_cmap14_class_rec,
3625 
3626       sizeof ( TT_CMap14Rec ),
3627 
3628       (FT_CMap_InitFunc)     tt_cmap14_init,        /* init       */
3629       (FT_CMap_DoneFunc)     tt_cmap14_done,        /* done       */
3630       (FT_CMap_CharIndexFunc)tt_cmap14_char_index,  /* char_index */
3631       (FT_CMap_CharNextFunc) tt_cmap14_char_next,   /* char_next  */
3632 
3633       /* Format 14 extension functions */
3634       (FT_CMap_CharVarIndexFunc)    tt_cmap14_char_var_index,
3635       (FT_CMap_CharVarIsDefaultFunc)tt_cmap14_char_var_isdefault,
3636       (FT_CMap_VariantListFunc)     tt_cmap14_variants,
3637       (FT_CMap_CharVariantListFunc) tt_cmap14_char_variants,
3638       (FT_CMap_VariantCharListFunc) tt_cmap14_variant_chars,
3639 
3640     14,
3641     (TT_CMap_ValidateFunc)tt_cmap14_validate,  /* validate      */
3642     (TT_CMap_Info_GetFunc)tt_cmap14_get_info   /* get_cmap_info */
3643   )
3644 
3645 #endif /* TT_CONFIG_CMAP_FORMAT_14 */
3646 
3647 
3648   /*************************************************************************/
3649   /*************************************************************************/
3650   /*****                                                               *****/
3651   /*****                       SYNTHETIC UNICODE                       *****/
3652   /*****                                                               *****/
3653   /*************************************************************************/
3654   /*************************************************************************/
3655 
3656   /*        This charmap is generated using postscript glyph names.        */
3657 
3658 #ifdef FT_CONFIG_OPTION_POSTSCRIPT_NAMES
3659 
3660   FT_CALLBACK_DEF( const char * )
3661   tt_get_glyph_name( TT_Face  face,
3662                      FT_UInt  idx )
3663   {
3664     FT_String*  PSname;
3665 
3666 
3667     tt_face_get_ps_name( face, idx, &PSname );
3668 
3669     return PSname;
3670   }
3671 
3672 
3673   FT_CALLBACK_DEF( FT_Error )
3674   tt_cmap_unicode_init( PS_Unicodes  unicodes,
3675                         FT_Pointer   pointer )
3676   {
3677     TT_Face             face    = (TT_Face)FT_CMAP_FACE( unicodes );
3678     FT_Memory           memory  = FT_FACE_MEMORY( face );
3679     FT_Service_PsCMaps  psnames = (FT_Service_PsCMaps)face->psnames;
3680 
3681     FT_UNUSED( pointer );
3682 
3683 
3684     if ( !psnames->unicodes_init )
3685       return FT_THROW( Unimplemented_Feature );
3686 
3687     return psnames->unicodes_init( memory,
3688                                    unicodes,
3689                                    face->root.num_glyphs,
3690                                    (PS_GetGlyphNameFunc)&tt_get_glyph_name,
3691                                    (PS_FreeGlyphNameFunc)NULL,
3692                                    (FT_Pointer)face );
3693   }
3694 
3695 
3696   FT_CALLBACK_DEF( void )
3697   tt_cmap_unicode_done( PS_Unicodes  unicodes )
3698   {
3699     FT_Face    face   = FT_CMAP_FACE( unicodes );
3700     FT_Memory  memory = FT_FACE_MEMORY( face );
3701 
3702 
3703     FT_FREE( unicodes->maps );
3704     unicodes->num_maps = 0;
3705   }
3706 
3707 
3708   FT_CALLBACK_DEF( FT_UInt )
3709   tt_cmap_unicode_char_index( PS_Unicodes  unicodes,
3710                               FT_UInt32    char_code )
3711   {
3712     TT_Face             face    = (TT_Face)FT_CMAP_FACE( unicodes );
3713     FT_Service_PsCMaps  psnames = (FT_Service_PsCMaps)face->psnames;
3714 
3715 
3716     return psnames->unicodes_char_index( unicodes, char_code );
3717   }
3718 
3719 
3720   FT_CALLBACK_DEF( FT_UInt32 )
3721   tt_cmap_unicode_char_next( PS_Unicodes  unicodes,
3722                              FT_UInt32   *pchar_code )
3723   {
3724     TT_Face             face    = (TT_Face)FT_CMAP_FACE( unicodes );
3725     FT_Service_PsCMaps  psnames = (FT_Service_PsCMaps)face->psnames;
3726 
3727 
3728     return psnames->unicodes_char_next( unicodes, pchar_code );
3729   }
3730 
3731 
3732   FT_DEFINE_TT_CMAP(
3733     tt_cmap_unicode_class_rec,
3734 
3735       sizeof ( PS_UnicodesRec ),
3736 
3737       (FT_CMap_InitFunc)     tt_cmap_unicode_init,        /* init       */
3738       (FT_CMap_DoneFunc)     tt_cmap_unicode_done,        /* done       */
3739       (FT_CMap_CharIndexFunc)tt_cmap_unicode_char_index,  /* char_index */
3740       (FT_CMap_CharNextFunc) tt_cmap_unicode_char_next,   /* char_next  */
3741 
3742       (FT_CMap_CharVarIndexFunc)    NULL,  /* char_var_index   */
3743       (FT_CMap_CharVarIsDefaultFunc)NULL,  /* char_var_default */
3744       (FT_CMap_VariantListFunc)     NULL,  /* variant_list     */
3745       (FT_CMap_CharVariantListFunc) NULL,  /* charvariant_list */
3746       (FT_CMap_VariantCharListFunc) NULL,  /* variantchar_list */
3747 
3748     ~0U,
3749     (TT_CMap_ValidateFunc)NULL,  /* validate      */
3750     (TT_CMap_Info_GetFunc)NULL   /* get_cmap_info */
3751   )
3752 
3753 #endif /* FT_CONFIG_OPTION_POSTSCRIPT_NAMES */
3754 
3755 
3756   static const TT_CMap_Class  tt_cmap_classes[] =
3757   {
3758 #define TTCMAPCITEM( a )  &a,
3759 #include "ttcmapc.h"
3760     NULL,
3761   };
3762 
3763 
3764   /* parse the `cmap' table and build the corresponding TT_CMap objects */
3765   /* in the current face                                                */
3766   /*                                                                    */
3767   FT_LOCAL_DEF( FT_Error )
3768   tt_face_build_cmaps( TT_Face  face )
3769   {
3770     FT_Byte*           table = face->cmap_table;
3771     FT_Byte*           limit = table + face->cmap_size;
3772     FT_UInt volatile   num_cmaps;
3773     FT_Byte* volatile  p     = table;
3774     FT_Library         library = FT_FACE_LIBRARY( face );
3775 
3776     FT_UNUSED( library );
3777 
3778 
3779     if ( !p || p + 4 > limit )
3780       return FT_THROW( Invalid_Table );
3781 
3782     /* only recognize format 0 */
3783     if ( TT_NEXT_USHORT( p ) != 0 )
3784     {
3785       FT_ERROR(( "tt_face_build_cmaps:"
3786                  " unsupported `cmap' table format = %d\n",
3787                  TT_PEEK_USHORT( p - 2 ) ));
3788       return FT_THROW( Invalid_Table );
3789     }
3790 
3791     num_cmaps = TT_NEXT_USHORT( p );
3792 
3793     for ( ; num_cmaps > 0 && p + 8 <= limit; num_cmaps-- )
3794     {
3795       FT_CharMapRec  charmap;
3796       FT_UInt32      offset;
3797 
3798 
3799       charmap.platform_id = TT_NEXT_USHORT( p );
3800       charmap.encoding_id = TT_NEXT_USHORT( p );
3801       charmap.face        = FT_FACE( face );
3802       charmap.encoding    = FT_ENCODING_NONE;  /* will be filled later */
3803       offset              = TT_NEXT_ULONG( p );
3804 
3805       if ( offset && offset <= face->cmap_size - 2 )
3806       {
3807         FT_Byte* volatile              cmap   = table + offset;
3808         volatile FT_UInt               format = TT_PEEK_USHORT( cmap );
3809         const TT_CMap_Class* volatile  pclazz = tt_cmap_classes;
3810         TT_CMap_Class volatile         clazz;
3811 
3812 
3813         for ( ; *pclazz; pclazz++ )
3814         {
3815           clazz = *pclazz;
3816           if ( clazz->format == format )
3817           {
3818             volatile TT_ValidatorRec  valid;
3819             volatile FT_Error         error = FT_Err_Ok;
3820 
3821 
3822             ft_validator_init( FT_VALIDATOR( &valid ), cmap, limit,
3823                                FT_VALIDATE_DEFAULT );
3824 
3825             valid.num_glyphs = (FT_UInt)face->max_profile.numGlyphs;
3826 
3827             if ( ft_setjmp( FT_VALIDATOR( &valid )->jump_buffer) == 0 )
3828             {
3829               /* validate this cmap sub-table */
3830               error = clazz->validate( cmap, FT_VALIDATOR( &valid ) );
3831             }
3832 
3833             if ( !valid.validator.error )
3834             {
3835               FT_CMap  ttcmap;
3836 
3837 
3838               /* It might make sense to store the single variation         */
3839               /* selector cmap somewhere special.  But it would have to be */
3840               /* in the public FT_FaceRec, and we can't change that.       */
3841 
3842               if ( !FT_CMap_New( (FT_CMap_Class)clazz,
3843                                  cmap, &charmap, &ttcmap ) )
3844               {
3845                 /* it is simpler to directly set `flags' than adding */
3846                 /* a parameter to FT_CMap_New                        */
3847                 ((TT_CMap)ttcmap)->flags = (FT_Int)error;
3848               }
3849             }
3850             else
3851             {
3852               FT_TRACE0(( "tt_face_build_cmaps:"
3853                           " broken cmap sub-table ignored\n" ));
3854             }
3855             break;
3856           }
3857         }
3858 
3859         if ( !*pclazz )
3860         {
3861           FT_TRACE0(( "tt_face_build_cmaps:"
3862                       " unsupported cmap sub-table ignored\n" ));
3863         }
3864       }
3865     }
3866 
3867     return FT_Err_Ok;
3868   }
3869 
3870 
3871   FT_LOCAL( FT_Error )
3872   tt_get_cmap_info( FT_CharMap    charmap,
3873                     TT_CMapInfo  *cmap_info )
3874   {
3875     FT_CMap        cmap  = (FT_CMap)charmap;
3876     TT_CMap_Class  clazz = (TT_CMap_Class)cmap->clazz;
3877 
3878     if ( clazz->get_cmap_info )
3879       return clazz->get_cmap_info( charmap, cmap_info );
3880     else
3881       return FT_THROW( Invalid_CharMap_Format );
3882   }
3883 
3884 
3885 /* END */