1 /****************************************************************************
   2  *
   3  * ttcmap.c
   4  *
   5  *   TrueType character mapping table (cmap) support (body).
   6  *
   7  * Copyright (C) 2002-2020 by
   8  * David Turner, Robert Wilhelm, and Werner Lemberg.
   9  *
  10  * This file is part of the FreeType project, and may only be used,
  11  * modified, and distributed under the terms of the FreeType project
  12  * license, LICENSE.TXT.  By continuing to use, modify, or distribute
  13  * this file you indicate that you have read the license and
  14  * understand and accept it fully.
  15  *
  16  */
  17 
  18 
  19 #include <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           continue;
2372 
2373         cmap->cur_charcode = char_code;
2374         cmap->cur_gindex   = gindex;
2375         cmap->cur_group    = n;
2376 
2377         return;
2378       }
2379     }
2380 
2381   Fail:
2382     cmap->valid = 0;
2383   }
2384 
2385 
2386   static FT_UInt
2387   tt_cmap12_char_map_binary( TT_CMap     cmap,
2388                              FT_UInt32*  pchar_code,
2389                              FT_Bool     next )
2390   {
2391     FT_UInt    gindex     = 0;
2392     FT_Byte*   p          = cmap->data + 12;
2393     FT_UInt32  num_groups = TT_PEEK_ULONG( p );
2394     FT_UInt32  char_code  = *pchar_code;
2395     FT_UInt32  start, end, start_id;
2396     FT_UInt32  max, min, mid;
2397 
2398 
2399     if ( !num_groups )
2400       return 0;
2401 
2402     /* make compiler happy */
2403     mid = num_groups;
2404     end = 0xFFFFFFFFUL;
2405 
2406     if ( next )
2407     {
2408       if ( char_code >= 0xFFFFFFFFUL )
2409         return 0;
2410 
2411       char_code++;
2412     }
2413 
2414     min = 0;
2415     max = num_groups;
2416 
2417     /* binary search */
2418     while ( min < max )
2419     {
2420       mid = ( min + max ) >> 1;
2421       p   = cmap->data + 16 + 12 * mid;
2422 
2423       start = TT_NEXT_ULONG( p );
2424       end   = TT_NEXT_ULONG( p );
2425 
2426       if ( char_code < start )
2427         max = mid;
2428       else if ( char_code > end )
2429         min = mid + 1;
2430       else
2431       {
2432         start_id = TT_PEEK_ULONG( p );
2433 
2434         /* reject invalid glyph index */
2435         if ( start_id > 0xFFFFFFFFUL - ( char_code - start ) )
2436           gindex = 0;
2437         else
2438           gindex = (FT_UInt)( start_id + ( char_code - start ) );
2439         break;
2440       }
2441     }
2442 
2443     if ( next )
2444     {
2445       FT_Face    face   = cmap->cmap.charmap.face;
2446       TT_CMap12  cmap12 = (TT_CMap12)cmap;
2447 
2448 
2449       /* if `char_code' is not in any group, then `mid' is */
2450       /* the group nearest to `char_code'                  */
2451 
2452       if ( char_code > end )
2453       {
2454         mid++;
2455         if ( mid == num_groups )
2456           return 0;
2457       }
2458 
2459       cmap12->valid        = 1;
2460       cmap12->cur_charcode = char_code;
2461       cmap12->cur_group    = mid;
2462 
2463       if ( gindex >= (FT_UInt)face->num_glyphs )
2464         gindex = 0;
2465 
2466       if ( !gindex )
2467       {
2468         tt_cmap12_next( cmap12 );
2469 
2470         if ( cmap12->valid )
2471           gindex = cmap12->cur_gindex;
2472       }
2473       else
2474         cmap12->cur_gindex = gindex;
2475 
2476       *pchar_code = cmap12->cur_charcode;
2477     }
2478 
2479     return gindex;
2480   }
2481 
2482 
2483   FT_CALLBACK_DEF( FT_UInt )
2484   tt_cmap12_char_index( TT_CMap    cmap,
2485                         FT_UInt32  char_code )
2486   {
2487     return tt_cmap12_char_map_binary( cmap, &char_code, 0 );
2488   }
2489 
2490 
2491   FT_CALLBACK_DEF( FT_UInt32 )
2492   tt_cmap12_char_next( TT_CMap     cmap,
2493                        FT_UInt32  *pchar_code )
2494   {
2495     TT_CMap12  cmap12 = (TT_CMap12)cmap;
2496     FT_UInt    gindex;
2497 
2498 
2499     /* no need to search */
2500     if ( cmap12->valid && cmap12->cur_charcode == *pchar_code )
2501     {
2502       tt_cmap12_next( cmap12 );
2503       if ( cmap12->valid )
2504       {
2505         gindex      = cmap12->cur_gindex;
2506         *pchar_code = (FT_UInt32)cmap12->cur_charcode;
2507       }
2508       else
2509         gindex = 0;
2510     }
2511     else
2512       gindex = tt_cmap12_char_map_binary( cmap, pchar_code, 1 );
2513 
2514     return gindex;
2515   }
2516 
2517 
2518   FT_CALLBACK_DEF( FT_Error )
2519   tt_cmap12_get_info( TT_CMap       cmap,
2520                       TT_CMapInfo  *cmap_info )
2521   {
2522     FT_Byte*  p = cmap->data + 8;
2523 
2524 
2525     cmap_info->format   = 12;
2526     cmap_info->language = (FT_ULong)TT_PEEK_ULONG( p );
2527 
2528     return FT_Err_Ok;
2529   }
2530 
2531 
2532   FT_DEFINE_TT_CMAP(
2533     tt_cmap12_class_rec,
2534 
2535       sizeof ( TT_CMap12Rec ),
2536 
2537       (FT_CMap_InitFunc)     tt_cmap12_init,        /* init       */
2538       (FT_CMap_DoneFunc)     NULL,                  /* done       */
2539       (FT_CMap_CharIndexFunc)tt_cmap12_char_index,  /* char_index */
2540       (FT_CMap_CharNextFunc) tt_cmap12_char_next,   /* char_next  */
2541 
2542       (FT_CMap_CharVarIndexFunc)    NULL,  /* char_var_index   */
2543       (FT_CMap_CharVarIsDefaultFunc)NULL,  /* char_var_default */
2544       (FT_CMap_VariantListFunc)     NULL,  /* variant_list     */
2545       (FT_CMap_CharVariantListFunc) NULL,  /* charvariant_list */
2546       (FT_CMap_VariantCharListFunc) NULL,  /* variantchar_list */
2547 
2548     12,
2549     (TT_CMap_ValidateFunc)tt_cmap12_validate,  /* validate      */
2550     (TT_CMap_Info_GetFunc)tt_cmap12_get_info   /* get_cmap_info */
2551   )
2552 
2553 #endif /* TT_CONFIG_CMAP_FORMAT_12 */
2554 
2555 
2556   /*************************************************************************/
2557   /*************************************************************************/
2558   /*****                                                               *****/
2559   /*****                          FORMAT 13                            *****/
2560   /*****                                                               *****/
2561   /*************************************************************************/
2562   /*************************************************************************/
2563 
2564   /**************************************************************************
2565    *
2566    * TABLE OVERVIEW
2567    * --------------
2568    *
2569    *   NAME        OFFSET     TYPE       DESCRIPTION
2570    *
2571    *   format      0          USHORT     must be 13
2572    *   reserved    2          USHORT     reserved
2573    *   length      4          ULONG      length in bytes
2574    *   language    8          ULONG      Mac language code
2575    *   count       12         ULONG      number of groups
2576    *               16
2577    *
2578    * This header is followed by `count' groups of the following format:
2579    *
2580    *   start       0          ULONG      first charcode
2581    *   end         4          ULONG      last charcode
2582    *   glyphId     8          ULONG      glyph ID for the whole group
2583    */
2584 
2585 #ifdef TT_CONFIG_CMAP_FORMAT_13
2586 
2587   typedef struct  TT_CMap13Rec_
2588   {
2589     TT_CMapRec  cmap;
2590     FT_Bool     valid;
2591     FT_ULong    cur_charcode;
2592     FT_UInt     cur_gindex;
2593     FT_ULong    cur_group;
2594     FT_ULong    num_groups;
2595 
2596   } TT_CMap13Rec, *TT_CMap13;
2597 
2598 
2599   FT_CALLBACK_DEF( FT_Error )
2600   tt_cmap13_init( TT_CMap13  cmap,
2601                   FT_Byte*   table )
2602   {
2603     cmap->cmap.data  = table;
2604 
2605     table           += 12;
2606     cmap->num_groups = FT_PEEK_ULONG( table );
2607 
2608     cmap->valid      = 0;
2609 
2610     return FT_Err_Ok;
2611   }
2612 
2613 
2614   FT_CALLBACK_DEF( FT_Error )
2615   tt_cmap13_validate( FT_Byte*      table,
2616                       FT_Validator  valid )
2617   {
2618     FT_Byte*  p;
2619     FT_ULong  length;
2620     FT_ULong  num_groups;
2621 
2622 
2623     if ( table + 16 > valid->limit )
2624       FT_INVALID_TOO_SHORT;
2625 
2626     p      = table + 4;
2627     length = TT_NEXT_ULONG( p );
2628 
2629     p          = table + 12;
2630     num_groups = TT_NEXT_ULONG( p );
2631 
2632     if ( length > (FT_ULong)( valid->limit - table ) ||
2633          /* length < 16 + 12 * num_groups ? */
2634          length < 16                                 ||
2635          ( length - 16 ) / 12 < num_groups           )
2636       FT_INVALID_TOO_SHORT;
2637 
2638     /* check groups, they must be in increasing order */
2639     {
2640       FT_ULong  n, start, end, glyph_id, last = 0;
2641 
2642 
2643       for ( n = 0; n < num_groups; n++ )
2644       {
2645         start    = TT_NEXT_ULONG( p );
2646         end      = TT_NEXT_ULONG( p );
2647         glyph_id = TT_NEXT_ULONG( p );
2648 
2649         if ( start > end )
2650           FT_INVALID_DATA;
2651 
2652         if ( n > 0 && start <= last )
2653           FT_INVALID_DATA;
2654 
2655         if ( valid->level >= FT_VALIDATE_TIGHT )
2656         {
2657           if ( glyph_id >= TT_VALID_GLYPH_COUNT( valid ) )
2658             FT_INVALID_GLYPH_ID;
2659         }
2660 
2661         last = end;
2662       }
2663     }
2664 
2665     return FT_Err_Ok;
2666   }
2667 
2668 
2669   /* search the index of the charcode next to cmap->cur_charcode */
2670   /* cmap->cur_group should be set up properly by caller         */
2671   /*                                                             */
2672   static void
2673   tt_cmap13_next( TT_CMap13  cmap )
2674   {
2675     FT_Face   face = cmap->cmap.cmap.charmap.face;
2676     FT_Byte*  p;
2677     FT_ULong  start, end, glyph_id, char_code;
2678     FT_ULong  n;
2679     FT_UInt   gindex;
2680 
2681 
2682     if ( cmap->cur_charcode >= 0xFFFFFFFFUL )
2683       goto Fail;
2684 
2685     char_code = cmap->cur_charcode + 1;
2686 
2687     for ( n = cmap->cur_group; n < cmap->num_groups; n++ )
2688     {
2689       p        = cmap->cmap.data + 16 + 12 * n;
2690       start    = TT_NEXT_ULONG( p );
2691       end      = TT_NEXT_ULONG( p );
2692       glyph_id = TT_PEEK_ULONG( p );
2693 
2694       if ( char_code < start )
2695         char_code = start;
2696 
2697       if ( char_code <= end )
2698       {
2699         gindex = (FT_UInt)glyph_id;
2700 
2701         if ( gindex && gindex < (FT_UInt)face->num_glyphs )
2702         {
2703           cmap->cur_charcode = char_code;
2704           cmap->cur_gindex   = gindex;
2705           cmap->cur_group    = n;
2706 
2707           return;
2708         }
2709       }
2710     }
2711 
2712   Fail:
2713     cmap->valid = 0;
2714   }
2715 
2716 
2717   static FT_UInt
2718   tt_cmap13_char_map_binary( TT_CMap     cmap,
2719                              FT_UInt32*  pchar_code,
2720                              FT_Bool     next )
2721   {
2722     FT_UInt    gindex     = 0;
2723     FT_Byte*   p          = cmap->data + 12;
2724     FT_UInt32  num_groups = TT_PEEK_ULONG( p );
2725     FT_UInt32  char_code  = *pchar_code;
2726     FT_UInt32  start, end;
2727     FT_UInt32  max, min, mid;
2728 
2729 
2730     if ( !num_groups )
2731       return 0;
2732 
2733     /* make compiler happy */
2734     mid = num_groups;
2735     end = 0xFFFFFFFFUL;
2736 
2737     if ( next )
2738     {
2739       if ( char_code >= 0xFFFFFFFFUL )
2740         return 0;
2741 
2742       char_code++;
2743     }
2744 
2745     min = 0;
2746     max = num_groups;
2747 
2748     /* binary search */
2749     while ( min < max )
2750     {
2751       mid = ( min + max ) >> 1;
2752       p   = cmap->data + 16 + 12 * mid;
2753 
2754       start = TT_NEXT_ULONG( p );
2755       end   = TT_NEXT_ULONG( p );
2756 
2757       if ( char_code < start )
2758         max = mid;
2759       else if ( char_code > end )
2760         min = mid + 1;
2761       else
2762       {
2763         gindex = (FT_UInt)TT_PEEK_ULONG( p );
2764 
2765         break;
2766       }
2767     }
2768 
2769     if ( next )
2770     {
2771       FT_Face    face   = cmap->cmap.charmap.face;
2772       TT_CMap13  cmap13 = (TT_CMap13)cmap;
2773 
2774 
2775       /* if `char_code' is not in any group, then `mid' is */
2776       /* the group nearest to `char_code'                  */
2777 
2778       if ( char_code > end )
2779       {
2780         mid++;
2781         if ( mid == num_groups )
2782           return 0;
2783       }
2784 
2785       cmap13->valid        = 1;
2786       cmap13->cur_charcode = char_code;
2787       cmap13->cur_group    = mid;
2788 
2789       if ( gindex >= (FT_UInt)face->num_glyphs )
2790         gindex = 0;
2791 
2792       if ( !gindex )
2793       {
2794         tt_cmap13_next( cmap13 );
2795 
2796         if ( cmap13->valid )
2797           gindex = cmap13->cur_gindex;
2798       }
2799       else
2800         cmap13->cur_gindex = gindex;
2801 
2802       *pchar_code = cmap13->cur_charcode;
2803     }
2804 
2805     return gindex;
2806   }
2807 
2808 
2809   FT_CALLBACK_DEF( FT_UInt )
2810   tt_cmap13_char_index( TT_CMap    cmap,
2811                         FT_UInt32  char_code )
2812   {
2813     return tt_cmap13_char_map_binary( cmap, &char_code, 0 );
2814   }
2815 
2816 
2817   FT_CALLBACK_DEF( FT_UInt32 )
2818   tt_cmap13_char_next( TT_CMap     cmap,
2819                        FT_UInt32  *pchar_code )
2820   {
2821     TT_CMap13  cmap13 = (TT_CMap13)cmap;
2822     FT_UInt    gindex;
2823 
2824 
2825     /* no need to search */
2826     if ( cmap13->valid && cmap13->cur_charcode == *pchar_code )
2827     {
2828       tt_cmap13_next( cmap13 );
2829       if ( cmap13->valid )
2830       {
2831         gindex      = cmap13->cur_gindex;
2832         *pchar_code = cmap13->cur_charcode;
2833       }
2834       else
2835         gindex = 0;
2836     }
2837     else
2838       gindex = tt_cmap13_char_map_binary( cmap, pchar_code, 1 );
2839 
2840     return gindex;
2841   }
2842 
2843 
2844   FT_CALLBACK_DEF( FT_Error )
2845   tt_cmap13_get_info( TT_CMap       cmap,
2846                       TT_CMapInfo  *cmap_info )
2847   {
2848     FT_Byte*  p = cmap->data + 8;
2849 
2850 
2851     cmap_info->format   = 13;
2852     cmap_info->language = (FT_ULong)TT_PEEK_ULONG( p );
2853 
2854     return FT_Err_Ok;
2855   }
2856 
2857 
2858   FT_DEFINE_TT_CMAP(
2859     tt_cmap13_class_rec,
2860 
2861       sizeof ( TT_CMap13Rec ),
2862 
2863       (FT_CMap_InitFunc)     tt_cmap13_init,        /* init       */
2864       (FT_CMap_DoneFunc)     NULL,                  /* done       */
2865       (FT_CMap_CharIndexFunc)tt_cmap13_char_index,  /* char_index */
2866       (FT_CMap_CharNextFunc) tt_cmap13_char_next,   /* char_next  */
2867 
2868       (FT_CMap_CharVarIndexFunc)    NULL,  /* char_var_index   */
2869       (FT_CMap_CharVarIsDefaultFunc)NULL,  /* char_var_default */
2870       (FT_CMap_VariantListFunc)     NULL,  /* variant_list     */
2871       (FT_CMap_CharVariantListFunc) NULL,  /* charvariant_list */
2872       (FT_CMap_VariantCharListFunc) NULL,  /* variantchar_list */
2873 
2874     13,
2875     (TT_CMap_ValidateFunc)tt_cmap13_validate,  /* validate      */
2876     (TT_CMap_Info_GetFunc)tt_cmap13_get_info   /* get_cmap_info */
2877   )
2878 
2879 #endif /* TT_CONFIG_CMAP_FORMAT_13 */
2880 
2881 
2882   /*************************************************************************/
2883   /*************************************************************************/
2884   /*****                                                               *****/
2885   /*****                           FORMAT 14                           *****/
2886   /*****                                                               *****/
2887   /*************************************************************************/
2888   /*************************************************************************/
2889 
2890   /**************************************************************************
2891    *
2892    * TABLE OVERVIEW
2893    * --------------
2894    *
2895    *   NAME         OFFSET  TYPE    DESCRIPTION
2896    *
2897    *   format         0     USHORT  must be 14
2898    *   length         2     ULONG   table length in bytes
2899    *   numSelector    6     ULONG   number of variation sel. records
2900    *
2901    * Followed by numSelector records, each of which looks like
2902    *
2903    *   varSelector    0     UINT24  Unicode codepoint of sel.
2904    *   defaultOff     3     ULONG   offset to a default UVS table
2905    *                                describing any variants to be found in
2906    *                                the normal Unicode subtable.
2907    *   nonDefOff      7     ULONG   offset to a non-default UVS table
2908    *                                describing any variants not in the
2909    *                                standard cmap, with GIDs here
2910    * (either offset may be 0 NULL)
2911    *
2912    * Selectors are sorted by code point.
2913    *
2914    * A default Unicode Variation Selector (UVS) subtable is just a list of
2915    * ranges of code points which are to be found in the standard cmap.  No
2916    * glyph IDs (GIDs) here.
2917    *
2918    *   numRanges      0     ULONG   number of ranges following
2919    *
2920    * A range looks like
2921    *
2922    *   uniStart       0     UINT24  code point of the first character in
2923    *                                this range
2924    *   additionalCnt  3     UBYTE   count of additional characters in this
2925    *                                range (zero means a range of a single
2926    *                                character)
2927    *
2928    * Ranges are sorted by `uniStart'.
2929    *
2930    * A non-default Unicode Variation Selector (UVS) subtable is a list of
2931    * mappings from codepoint to GID.
2932    *
2933    *   numMappings    0     ULONG   number of mappings
2934    *
2935    * A range looks like
2936    *
2937    *   uniStart       0     UINT24  code point of the first character in
2938    *                                this range
2939    *   GID            3     USHORT  and its GID
2940    *
2941    * Ranges are sorted by `uniStart'.
2942    */
2943 
2944 #ifdef TT_CONFIG_CMAP_FORMAT_14
2945 
2946   typedef struct  TT_CMap14Rec_
2947   {
2948     TT_CMapRec  cmap;
2949     FT_ULong    num_selectors;
2950 
2951     /* This array is used to store the results of various
2952      * cmap 14 query functions.  The data is overwritten
2953      * on each call to these functions.
2954      */
2955     FT_UInt32   max_results;
2956     FT_UInt32*  results;
2957     FT_Memory   memory;
2958 
2959   } TT_CMap14Rec, *TT_CMap14;
2960 
2961 
2962   FT_CALLBACK_DEF( void )
2963   tt_cmap14_done( TT_CMap14  cmap )
2964   {
2965     FT_Memory  memory = cmap->memory;
2966 
2967 
2968     cmap->max_results = 0;
2969     if ( memory && cmap->results )
2970       FT_FREE( cmap->results );
2971   }
2972 
2973 
2974   static FT_Error
2975   tt_cmap14_ensure( TT_CMap14  cmap,
2976                     FT_UInt32  num_results,
2977                     FT_Memory  memory )
2978   {
2979     FT_UInt32  old_max = cmap->max_results;
2980     FT_Error   error   = FT_Err_Ok;
2981 
2982 
2983     if ( num_results > cmap->max_results )
2984     {
2985        cmap->memory = memory;
2986 
2987        if ( FT_QRENEW_ARRAY( cmap->results, old_max, num_results ) )
2988          return error;
2989 
2990        cmap->max_results = num_results;
2991     }
2992 
2993     return error;
2994   }
2995 
2996 
2997   FT_CALLBACK_DEF( FT_Error )
2998   tt_cmap14_init( TT_CMap14  cmap,
2999                   FT_Byte*   table )
3000   {
3001     cmap->cmap.data = table;
3002 
3003     table               += 6;
3004     cmap->num_selectors  = FT_PEEK_ULONG( table );
3005     cmap->max_results    = 0;
3006     cmap->results        = NULL;
3007 
3008     return FT_Err_Ok;
3009   }
3010 
3011 
3012   FT_CALLBACK_DEF( FT_Error )
3013   tt_cmap14_validate( FT_Byte*      table,
3014                       FT_Validator  valid )
3015   {
3016     FT_Byte*  p;
3017     FT_ULong  length;
3018     FT_ULong  num_selectors;
3019 
3020 
3021     if ( table + 2 + 4 + 4 > valid->limit )
3022       FT_INVALID_TOO_SHORT;
3023 
3024     p             = table + 2;
3025     length        = TT_NEXT_ULONG( p );
3026     num_selectors = TT_NEXT_ULONG( p );
3027 
3028     if ( length > (FT_ULong)( valid->limit - table ) ||
3029          /* length < 10 + 11 * num_selectors ? */
3030          length < 10                                 ||
3031          ( length - 10 ) / 11 < num_selectors        )
3032       FT_INVALID_TOO_SHORT;
3033 
3034     /* check selectors, they must be in increasing order */
3035     {
3036       /* we start lastVarSel at 1 because a variant selector value of 0
3037        * isn't valid.
3038        */
3039       FT_ULong  n, lastVarSel = 1;
3040 
3041 
3042       for ( n = 0; n < num_selectors; n++ )
3043       {
3044         FT_ULong  varSel    = TT_NEXT_UINT24( p );
3045         FT_ULong  defOff    = TT_NEXT_ULONG( p );
3046         FT_ULong  nondefOff = TT_NEXT_ULONG( p );
3047 
3048 
3049         if ( defOff >= length || nondefOff >= length )
3050           FT_INVALID_TOO_SHORT;
3051 
3052         if ( varSel < lastVarSel )
3053           FT_INVALID_DATA;
3054 
3055         lastVarSel = varSel + 1;
3056 
3057         /* check the default table (these glyphs should be reached     */
3058         /* through the normal Unicode cmap, no GIDs, just check order) */
3059         if ( defOff != 0 )
3060         {
3061           FT_Byte*  defp     = table + defOff;
3062           FT_ULong  numRanges;
3063           FT_ULong  i;
3064           FT_ULong  lastBase = 0;
3065 
3066 
3067           if ( defp + 4 > valid->limit )
3068             FT_INVALID_TOO_SHORT;
3069 
3070           numRanges = TT_NEXT_ULONG( defp );
3071 
3072           /* defp + numRanges * 4 > valid->limit ? */
3073           if ( numRanges > (FT_ULong)( valid->limit - defp ) / 4 )
3074             FT_INVALID_TOO_SHORT;
3075 
3076           for ( i = 0; i < numRanges; i++ )
3077           {
3078             FT_ULong  base = TT_NEXT_UINT24( defp );
3079             FT_ULong  cnt  = FT_NEXT_BYTE( defp );
3080 
3081 
3082             if ( base + cnt >= 0x110000UL )              /* end of Unicode */
3083               FT_INVALID_DATA;
3084 
3085             if ( base < lastBase )
3086               FT_INVALID_DATA;
3087 
3088             lastBase = base + cnt + 1U;
3089           }
3090         }
3091 
3092         /* and the non-default table (these glyphs are specified here) */
3093         if ( nondefOff != 0 )
3094         {
3095           FT_Byte*  ndp        = table + nondefOff;
3096           FT_ULong  numMappings;
3097           FT_ULong  i, lastUni = 0;
3098 
3099 
3100           if ( ndp + 4 > valid->limit )
3101             FT_INVALID_TOO_SHORT;
3102 
3103           numMappings = TT_NEXT_ULONG( ndp );
3104 
3105           /* numMappings * 5 > (FT_ULong)( valid->limit - ndp ) ? */
3106           if ( numMappings > ( (FT_ULong)( valid->limit - ndp ) ) / 5 )
3107             FT_INVALID_TOO_SHORT;
3108 
3109           for ( i = 0; i < numMappings; i++ )
3110           {
3111             FT_ULong  uni = TT_NEXT_UINT24( ndp );
3112             FT_ULong  gid = TT_NEXT_USHORT( ndp );
3113 
3114 
3115             if ( uni >= 0x110000UL )                     /* end of Unicode */
3116               FT_INVALID_DATA;
3117 
3118             if ( uni < lastUni )
3119               FT_INVALID_DATA;
3120 
3121             lastUni = uni + 1U;
3122 
3123             if ( valid->level >= FT_VALIDATE_TIGHT    &&
3124                  gid >= TT_VALID_GLYPH_COUNT( valid ) )
3125               FT_INVALID_GLYPH_ID;
3126           }
3127         }
3128       }
3129     }
3130 
3131     return FT_Err_Ok;
3132   }
3133 
3134 
3135   FT_CALLBACK_DEF( FT_UInt )
3136   tt_cmap14_char_index( TT_CMap    cmap,
3137                         FT_UInt32  char_code )
3138   {
3139     FT_UNUSED( cmap );
3140     FT_UNUSED( char_code );
3141 
3142     /* This can't happen */
3143     return 0;
3144   }
3145 
3146 
3147   FT_CALLBACK_DEF( FT_UInt32 )
3148   tt_cmap14_char_next( TT_CMap     cmap,
3149                        FT_UInt32  *pchar_code )
3150   {
3151     FT_UNUSED( cmap );
3152 
3153     /* This can't happen */
3154     *pchar_code = 0;
3155     return 0;
3156   }
3157 
3158 
3159   FT_CALLBACK_DEF( FT_Error )
3160   tt_cmap14_get_info( TT_CMap       cmap,
3161                       TT_CMapInfo  *cmap_info )
3162   {
3163     FT_UNUSED( cmap );
3164 
3165     cmap_info->format   = 14;
3166     /* subtable 14 does not define a language field */
3167     cmap_info->language = 0xFFFFFFFFUL;
3168 
3169     return FT_Err_Ok;
3170   }
3171 
3172 
3173   static FT_UInt
3174   tt_cmap14_char_map_def_binary( FT_Byte    *base,
3175                                  FT_UInt32   char_code )
3176   {
3177     FT_UInt32  numRanges = TT_PEEK_ULONG( base );
3178     FT_UInt32  max, min;
3179 
3180 
3181     min = 0;
3182     max = numRanges;
3183 
3184     base += 4;
3185 
3186     /* binary search */
3187     while ( min < max )
3188     {
3189       FT_UInt32  mid   = ( min + max ) >> 1;
3190       FT_Byte*   p     = base + 4 * mid;
3191       FT_ULong   start = TT_NEXT_UINT24( p );
3192       FT_UInt    cnt   = FT_NEXT_BYTE( p );
3193 
3194 
3195       if ( char_code < start )
3196         max = mid;
3197       else if ( char_code > start + cnt )
3198         min = mid + 1;
3199       else
3200         return TRUE;
3201     }
3202 
3203     return FALSE;
3204   }
3205 
3206 
3207   static FT_UInt
3208   tt_cmap14_char_map_nondef_binary( FT_Byte    *base,
3209                                     FT_UInt32   char_code )
3210   {
3211     FT_UInt32  numMappings = TT_PEEK_ULONG( base );
3212     FT_UInt32  max, min;
3213 
3214 
3215     min = 0;
3216     max = numMappings;
3217 
3218     base += 4;
3219 
3220     /* binary search */
3221     while ( min < max )
3222     {
3223       FT_UInt32  mid = ( min + max ) >> 1;
3224       FT_Byte*   p   = base + 5 * mid;
3225       FT_UInt32  uni = (FT_UInt32)TT_NEXT_UINT24( p );
3226 
3227 
3228       if ( char_code < uni )
3229         max = mid;
3230       else if ( char_code > uni )
3231         min = mid + 1;
3232       else
3233         return TT_PEEK_USHORT( p );
3234     }
3235 
3236     return 0;
3237   }
3238 
3239 
3240   static FT_Byte*
3241   tt_cmap14_find_variant( FT_Byte    *base,
3242                           FT_UInt32   variantCode )
3243   {
3244     FT_UInt32  numVar = TT_PEEK_ULONG( base );
3245     FT_UInt32  max, min;
3246 
3247 
3248     min = 0;
3249     max = numVar;
3250 
3251     base += 4;
3252 
3253     /* binary search */
3254     while ( min < max )
3255     {
3256       FT_UInt32  mid    = ( min + max ) >> 1;
3257       FT_Byte*   p      = base + 11 * mid;
3258       FT_ULong   varSel = TT_NEXT_UINT24( p );
3259 
3260 
3261       if ( variantCode < varSel )
3262         max = mid;
3263       else if ( variantCode > varSel )
3264         min = mid + 1;
3265       else
3266         return p;
3267     }
3268 
3269     return NULL;
3270   }
3271 
3272 
3273   FT_CALLBACK_DEF( FT_UInt )
3274   tt_cmap14_char_var_index( TT_CMap    cmap,
3275                             TT_CMap    ucmap,
3276                             FT_UInt32  charcode,
3277                             FT_UInt32  variantSelector )
3278   {
3279     FT_Byte*  p = tt_cmap14_find_variant( cmap->data + 6, variantSelector );
3280     FT_ULong  defOff;
3281     FT_ULong  nondefOff;
3282 
3283 
3284     if ( !p )
3285       return 0;
3286 
3287     defOff    = TT_NEXT_ULONG( p );
3288     nondefOff = TT_PEEK_ULONG( p );
3289 
3290     if ( defOff != 0                                                    &&
3291          tt_cmap14_char_map_def_binary( cmap->data + defOff, charcode ) )
3292     {
3293       /* This is the default variant of this charcode.  GID not stored */
3294       /* here; stored in the normal Unicode charmap instead.           */
3295       return ucmap->cmap.clazz->char_index( &ucmap->cmap, charcode );
3296     }
3297 
3298     if ( nondefOff != 0 )
3299       return tt_cmap14_char_map_nondef_binary( cmap->data + nondefOff,
3300                                                charcode );
3301 
3302     return 0;
3303   }
3304 
3305 
3306   FT_CALLBACK_DEF( FT_Int )
3307   tt_cmap14_char_var_isdefault( TT_CMap    cmap,
3308                                 FT_UInt32  charcode,
3309                                 FT_UInt32  variantSelector )
3310   {
3311     FT_Byte*  p = tt_cmap14_find_variant( cmap->data + 6, variantSelector );
3312     FT_ULong  defOff;
3313     FT_ULong  nondefOff;
3314 
3315 
3316     if ( !p )
3317       return -1;
3318 
3319     defOff    = TT_NEXT_ULONG( p );
3320     nondefOff = TT_NEXT_ULONG( p );
3321 
3322     if ( defOff != 0                                                    &&
3323          tt_cmap14_char_map_def_binary( cmap->data + defOff, charcode ) )
3324       return 1;
3325 
3326     if ( nondefOff != 0                                            &&
3327          tt_cmap14_char_map_nondef_binary( cmap->data + nondefOff,
3328                                            charcode ) != 0         )
3329       return 0;
3330 
3331     return -1;
3332   }
3333 
3334 
3335   FT_CALLBACK_DEF( FT_UInt32* )
3336   tt_cmap14_variants( TT_CMap    cmap,
3337                       FT_Memory  memory )
3338   {
3339     TT_CMap14   cmap14 = (TT_CMap14)cmap;
3340     FT_UInt32   count  = cmap14->num_selectors;
3341     FT_Byte*    p      = cmap->data + 10;
3342     FT_UInt32*  result;
3343     FT_UInt32   i;
3344 
3345 
3346     if ( tt_cmap14_ensure( cmap14, ( count + 1 ), memory ) )
3347       return NULL;
3348 
3349     result = cmap14->results;
3350     for ( i = 0; i < count; i++ )
3351     {
3352       result[i] = (FT_UInt32)TT_NEXT_UINT24( p );
3353       p        += 8;
3354     }
3355     result[i] = 0;
3356 
3357     return result;
3358   }
3359 
3360 
3361   FT_CALLBACK_DEF( FT_UInt32 * )
3362   tt_cmap14_char_variants( TT_CMap    cmap,
3363                            FT_Memory  memory,
3364                            FT_UInt32  charCode )
3365   {
3366     TT_CMap14   cmap14 = (TT_CMap14)  cmap;
3367     FT_UInt32   count  = cmap14->num_selectors;
3368     FT_Byte*    p      = cmap->data + 10;
3369     FT_UInt32*  q;
3370 
3371 
3372     if ( tt_cmap14_ensure( cmap14, ( count + 1 ), memory ) )
3373       return NULL;
3374 
3375     for ( q = cmap14->results; count > 0; count-- )
3376     {
3377       FT_UInt32  varSel    = TT_NEXT_UINT24( p );
3378       FT_ULong   defOff    = TT_NEXT_ULONG( p );
3379       FT_ULong   nondefOff = TT_NEXT_ULONG( p );
3380 
3381 
3382       if ( ( defOff != 0                                               &&
3383              tt_cmap14_char_map_def_binary( cmap->data + defOff,
3384                                             charCode )                 ) ||
3385            ( nondefOff != 0                                            &&
3386              tt_cmap14_char_map_nondef_binary( cmap->data + nondefOff,
3387                                                charCode ) != 0         ) )
3388       {
3389         q[0] = varSel;
3390         q++;
3391       }
3392     }
3393     q[0] = 0;
3394 
3395     return cmap14->results;
3396   }
3397 
3398 
3399   static FT_UInt
3400   tt_cmap14_def_char_count( FT_Byte  *p )
3401   {
3402     FT_UInt32  numRanges = (FT_UInt32)TT_NEXT_ULONG( p );
3403     FT_UInt    tot       = 0;
3404 
3405 
3406     p += 3;  /* point to the first `cnt' field */
3407     for ( ; numRanges > 0; numRanges-- )
3408     {
3409       tot += 1 + p[0];
3410       p   += 4;
3411     }
3412 
3413     return tot;
3414   }
3415 
3416 
3417   static FT_UInt32*
3418   tt_cmap14_get_def_chars( TT_CMap    cmap,
3419                            FT_Byte*   p,
3420                            FT_Memory  memory )
3421   {
3422     TT_CMap14   cmap14 = (TT_CMap14) cmap;
3423     FT_UInt32   numRanges;
3424     FT_UInt     cnt;
3425     FT_UInt32*  q;
3426 
3427 
3428     cnt       = tt_cmap14_def_char_count( p );
3429     numRanges = (FT_UInt32)TT_NEXT_ULONG( p );
3430 
3431     if ( tt_cmap14_ensure( cmap14, ( cnt + 1 ), memory ) )
3432       return NULL;
3433 
3434     for ( q = cmap14->results; numRanges > 0; numRanges-- )
3435     {
3436       FT_UInt32  uni = (FT_UInt32)TT_NEXT_UINT24( p );
3437 
3438 
3439       cnt = FT_NEXT_BYTE( p ) + 1;
3440       do
3441       {
3442         q[0]  = uni;
3443         uni  += 1;
3444         q    += 1;
3445 
3446       } while ( --cnt != 0 );
3447     }
3448     q[0] = 0;
3449 
3450     return cmap14->results;
3451   }
3452 
3453 
3454   static FT_UInt32*
3455   tt_cmap14_get_nondef_chars( TT_CMap     cmap,
3456                               FT_Byte    *p,
3457                               FT_Memory   memory )
3458   {
3459     TT_CMap14   cmap14 = (TT_CMap14) cmap;
3460     FT_UInt32   numMappings;
3461     FT_UInt     i;
3462     FT_UInt32  *ret;
3463 
3464 
3465     numMappings = (FT_UInt32)TT_NEXT_ULONG( p );
3466 
3467     if ( tt_cmap14_ensure( cmap14, ( numMappings + 1 ), memory ) )
3468       return NULL;
3469 
3470     ret = cmap14->results;
3471     for ( i = 0; i < numMappings; i++ )
3472     {
3473       ret[i] = (FT_UInt32)TT_NEXT_UINT24( p );
3474       p += 2;
3475     }
3476     ret[i] = 0;
3477 
3478     return ret;
3479   }
3480 
3481 
3482   FT_CALLBACK_DEF( FT_UInt32 * )
3483   tt_cmap14_variant_chars( TT_CMap    cmap,
3484                            FT_Memory  memory,
3485                            FT_UInt32  variantSelector )
3486   {
3487     FT_Byte    *p  = tt_cmap14_find_variant( cmap->data + 6,
3488                                              variantSelector );
3489     FT_Int      i;
3490     FT_ULong    defOff;
3491     FT_ULong    nondefOff;
3492 
3493 
3494     if ( !p )
3495       return NULL;
3496 
3497     defOff    = TT_NEXT_ULONG( p );
3498     nondefOff = TT_NEXT_ULONG( p );
3499 
3500     if ( defOff == 0 && nondefOff == 0 )
3501       return NULL;
3502 
3503     if ( defOff == 0 )
3504       return tt_cmap14_get_nondef_chars( cmap, cmap->data + nondefOff,
3505                                          memory );
3506     else if ( nondefOff == 0 )
3507       return tt_cmap14_get_def_chars( cmap, cmap->data + defOff,
3508                                       memory );
3509     else
3510     {
3511       /* Both a default and a non-default glyph set?  That's probably not */
3512       /* good font design, but the spec allows for it...                  */
3513       TT_CMap14  cmap14 = (TT_CMap14) cmap;
3514       FT_UInt32  numRanges;
3515       FT_UInt32  numMappings;
3516       FT_UInt32  duni;
3517       FT_UInt32  dcnt;
3518       FT_UInt32  nuni;
3519       FT_Byte*   dp;
3520       FT_UInt    di, ni, k;
3521 
3522       FT_UInt32  *ret;
3523 
3524 
3525       p  = cmap->data + nondefOff;
3526       dp = cmap->data + defOff;
3527 
3528       numMappings = (FT_UInt32)TT_NEXT_ULONG( p );
3529       dcnt        = tt_cmap14_def_char_count( dp );
3530       numRanges   = (FT_UInt32)TT_NEXT_ULONG( dp );
3531 
3532       if ( numMappings == 0 )
3533         return tt_cmap14_get_def_chars( cmap, cmap->data + defOff,
3534                                         memory );
3535       if ( dcnt == 0 )
3536         return tt_cmap14_get_nondef_chars( cmap, cmap->data + nondefOff,
3537                                            memory );
3538 
3539       if ( tt_cmap14_ensure( cmap14, ( dcnt + numMappings + 1 ), memory ) )
3540         return NULL;
3541 
3542       ret  = cmap14->results;
3543       duni = (FT_UInt32)TT_NEXT_UINT24( dp );
3544       dcnt = FT_NEXT_BYTE( dp );
3545       di   = 1;
3546       nuni = (FT_UInt32)TT_NEXT_UINT24( p );
3547       p   += 2;
3548       ni   = 1;
3549       i    = 0;
3550 
3551       for (;;)
3552       {
3553         if ( nuni > duni + dcnt )
3554         {
3555           for ( k = 0; k <= dcnt; k++ )
3556             ret[i++] = duni + k;
3557 
3558           di++;
3559 
3560           if ( di > numRanges )
3561             break;
3562 
3563           duni = (FT_UInt32)TT_NEXT_UINT24( dp );
3564           dcnt = FT_NEXT_BYTE( dp );
3565         }
3566         else
3567         {
3568           if ( nuni < duni )
3569             ret[i++] = nuni;
3570           /* If it is within the default range then ignore it -- */
3571           /* that should not have happened                       */
3572           ni++;
3573           if ( ni > numMappings )
3574             break;
3575 
3576           nuni = (FT_UInt32)TT_NEXT_UINT24( p );
3577           p += 2;
3578         }
3579       }
3580 
3581       if ( ni <= numMappings )
3582       {
3583         /* If we get here then we have run out of all default ranges.   */
3584         /* We have read one non-default mapping which we haven't stored */
3585         /* and there may be others that need to be read.                */
3586         ret[i++] = nuni;
3587         while ( ni < numMappings )
3588         {
3589           ret[i++] = (FT_UInt32)TT_NEXT_UINT24( p );
3590           p += 2;
3591           ni++;
3592         }
3593       }
3594       else if ( di <= numRanges )
3595       {
3596         /* If we get here then we have run out of all non-default     */
3597         /* mappings.  We have read one default range which we haven't */
3598         /* stored and there may be others that need to be read.       */
3599         for ( k = 0; k <= dcnt; k++ )
3600           ret[i++] = duni + k;
3601 
3602         while ( di < numRanges )
3603         {
3604           duni = (FT_UInt32)TT_NEXT_UINT24( dp );
3605           dcnt = FT_NEXT_BYTE( dp );
3606 
3607           for ( k = 0; k <= dcnt; k++ )
3608             ret[i++] = duni + k;
3609           di++;
3610         }
3611       }
3612 
3613       ret[i] = 0;
3614 
3615       return ret;
3616     }
3617   }
3618 
3619 
3620   FT_DEFINE_TT_CMAP(
3621     tt_cmap14_class_rec,
3622 
3623       sizeof ( TT_CMap14Rec ),
3624 
3625       (FT_CMap_InitFunc)     tt_cmap14_init,        /* init       */
3626       (FT_CMap_DoneFunc)     tt_cmap14_done,        /* done       */
3627       (FT_CMap_CharIndexFunc)tt_cmap14_char_index,  /* char_index */
3628       (FT_CMap_CharNextFunc) tt_cmap14_char_next,   /* char_next  */
3629 
3630       /* Format 14 extension functions */
3631       (FT_CMap_CharVarIndexFunc)    tt_cmap14_char_var_index,
3632       (FT_CMap_CharVarIsDefaultFunc)tt_cmap14_char_var_isdefault,
3633       (FT_CMap_VariantListFunc)     tt_cmap14_variants,
3634       (FT_CMap_CharVariantListFunc) tt_cmap14_char_variants,
3635       (FT_CMap_VariantCharListFunc) tt_cmap14_variant_chars,
3636 
3637     14,
3638     (TT_CMap_ValidateFunc)tt_cmap14_validate,  /* validate      */
3639     (TT_CMap_Info_GetFunc)tt_cmap14_get_info   /* get_cmap_info */
3640   )
3641 
3642 #endif /* TT_CONFIG_CMAP_FORMAT_14 */
3643 
3644 
3645   /*************************************************************************/
3646   /*************************************************************************/
3647   /*****                                                               *****/
3648   /*****                       SYNTHETIC UNICODE                       *****/
3649   /*****                                                               *****/
3650   /*************************************************************************/
3651   /*************************************************************************/
3652 
3653   /*        This charmap is generated using postscript glyph names.        */
3654 
3655 #ifdef FT_CONFIG_OPTION_POSTSCRIPT_NAMES
3656 
3657   FT_CALLBACK_DEF( const char * )
3658   tt_get_glyph_name( TT_Face  face,
3659                      FT_UInt  idx )
3660   {
3661     FT_String*  PSname = NULL;
3662 
3663 
3664     tt_face_get_ps_name( face, idx, &PSname );
3665 
3666     return PSname;
3667   }
3668 
3669 
3670   FT_CALLBACK_DEF( FT_Error )
3671   tt_cmap_unicode_init( PS_Unicodes  unicodes,
3672                         FT_Pointer   pointer )
3673   {
3674     TT_Face             face    = (TT_Face)FT_CMAP_FACE( unicodes );
3675     FT_Memory           memory  = FT_FACE_MEMORY( face );
3676     FT_Service_PsCMaps  psnames = (FT_Service_PsCMaps)face->psnames;
3677 
3678     FT_UNUSED( pointer );
3679 
3680 
3681     if ( !psnames->unicodes_init )
3682       return FT_THROW( Unimplemented_Feature );
3683 
3684     return psnames->unicodes_init( memory,
3685                                    unicodes,
3686                                    face->root.num_glyphs,
3687                                    (PS_GetGlyphNameFunc)&tt_get_glyph_name,
3688                                    (PS_FreeGlyphNameFunc)NULL,
3689                                    (FT_Pointer)face );
3690   }
3691 
3692 
3693   FT_CALLBACK_DEF( void )
3694   tt_cmap_unicode_done( PS_Unicodes  unicodes )
3695   {
3696     FT_Face    face   = FT_CMAP_FACE( unicodes );
3697     FT_Memory  memory = FT_FACE_MEMORY( face );
3698 
3699 
3700     FT_FREE( unicodes->maps );
3701     unicodes->num_maps = 0;
3702   }
3703 
3704 
3705   FT_CALLBACK_DEF( FT_UInt )
3706   tt_cmap_unicode_char_index( PS_Unicodes  unicodes,
3707                               FT_UInt32    char_code )
3708   {
3709     TT_Face             face    = (TT_Face)FT_CMAP_FACE( unicodes );
3710     FT_Service_PsCMaps  psnames = (FT_Service_PsCMaps)face->psnames;
3711 
3712 
3713     return psnames->unicodes_char_index( unicodes, char_code );
3714   }
3715 
3716 
3717   FT_CALLBACK_DEF( FT_UInt32 )
3718   tt_cmap_unicode_char_next( PS_Unicodes  unicodes,
3719                              FT_UInt32   *pchar_code )
3720   {
3721     TT_Face             face    = (TT_Face)FT_CMAP_FACE( unicodes );
3722     FT_Service_PsCMaps  psnames = (FT_Service_PsCMaps)face->psnames;
3723 
3724 
3725     return psnames->unicodes_char_next( unicodes, pchar_code );
3726   }
3727 
3728 
3729   FT_DEFINE_TT_CMAP(
3730     tt_cmap_unicode_class_rec,
3731 
3732       sizeof ( PS_UnicodesRec ),
3733 
3734       (FT_CMap_InitFunc)     tt_cmap_unicode_init,        /* init       */
3735       (FT_CMap_DoneFunc)     tt_cmap_unicode_done,        /* done       */
3736       (FT_CMap_CharIndexFunc)tt_cmap_unicode_char_index,  /* char_index */
3737       (FT_CMap_CharNextFunc) tt_cmap_unicode_char_next,   /* char_next  */
3738 
3739       (FT_CMap_CharVarIndexFunc)    NULL,  /* char_var_index   */
3740       (FT_CMap_CharVarIsDefaultFunc)NULL,  /* char_var_default */
3741       (FT_CMap_VariantListFunc)     NULL,  /* variant_list     */
3742       (FT_CMap_CharVariantListFunc) NULL,  /* charvariant_list */
3743       (FT_CMap_VariantCharListFunc) NULL,  /* variantchar_list */
3744 
3745     ~0U,
3746     (TT_CMap_ValidateFunc)NULL,  /* validate      */
3747     (TT_CMap_Info_GetFunc)NULL   /* get_cmap_info */
3748   )
3749 
3750 #endif /* FT_CONFIG_OPTION_POSTSCRIPT_NAMES */
3751 
3752 
3753   static const TT_CMap_Class  tt_cmap_classes[] =
3754   {
3755 #define TTCMAPCITEM( a )  &a,
3756 #include "ttcmapc.h"
3757     NULL,
3758   };
3759 
3760 
3761   /* parse the `cmap' table and build the corresponding TT_CMap objects */
3762   /* in the current face                                                */
3763   /*                                                                    */
3764   FT_LOCAL_DEF( FT_Error )
3765   tt_face_build_cmaps( TT_Face  face )
3766   {
3767     FT_Byte* const     table   = face->cmap_table;
3768     FT_Byte*           limit;
3769     FT_UInt volatile   num_cmaps;
3770     FT_Byte* volatile  p       = table;
3771     FT_Library         library = FT_FACE_LIBRARY( face );
3772 
3773     FT_UNUSED( library );
3774 
3775 
3776     if ( !p || face->cmap_size < 4 )
3777       return FT_THROW( Invalid_Table );
3778 
3779     /* Version 1.8.3 of the OpenType specification contains the following */
3780     /* (https://docs.microsoft.com/en-us/typography/opentype/spec/cmap):  */
3781     /*                                                                    */
3782     /*   The 'cmap' table version number remains at 0x0000 for fonts that */
3783     /*   make use of the newer subtable formats.                          */
3784     /*                                                                    */
3785     /* This essentially means that a version format test is useless.      */
3786 
3787     /* ignore format */
3788     p += 2;
3789 
3790     num_cmaps = TT_NEXT_USHORT( p );
3791     limit     = table + face->cmap_size;
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 */