⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ttcmap.c

📁 一个类似windows
💻 C
📖 第 1 页 / 共 5 页
字号:

        if ( offset != 0 && offset != 0xFFFFU )
        {
          /* parse the glyph ids array for non-zero index */
          p += offset + ( code - start ) * 2;
          while ( code <= end )
          {
            gindex = TT_NEXT_USHORT( p );
            if ( gindex != 0 )
            {
              gindex = (FT_UInt)( gindex + delta ) & 0xFFFFU;
              if ( gindex != 0 )
              {
                result = code;
#ifdef OPT_CMAP4
                tt_cmap4_reset( (TT_CMap4)cmap, code, hi );
#endif
                goto Exit;
              }
            }
            code++;
          }
        }
        else if ( offset == 0xFFFFU )
        {
          /* an offset of 0xFFFF means an empty segment in certain fonts! */
          code = end + 1;
        }
        else  /* offset == 0 */
        {
          gindex = (FT_UInt)( code + delta ) & 0xFFFFU;
          if ( gindex != 0 )
          {
            result = code;
#ifdef OPT_CMAP4
            tt_cmap4_reset( (TT_CMap4)cmap, code, hi );
#endif
            goto Exit;
          }
          code++;
        }
      }
    }
    else
    {
      for ( ;; )
      {
        FT_UInt   offset, n;
        FT_Int    delta;
        FT_Byte*  q;


        p = table + 14;              /* ends table  */
        q = table + 16 + num_segs2;  /* starts table */

        for ( n = 0; n < num_segs2; n += 2 )
        {
          FT_UInt  end   = TT_NEXT_USHORT( p );
          FT_UInt  start = TT_NEXT_USHORT( q );


          if ( code < start )
            code = start;

          if ( code <= end )
          {
            p = q + num_segs2 - 2;
            delta = TT_PEEK_SHORT( p );
            p += num_segs2;
            offset = TT_PEEK_USHORT( p );

            if ( offset != 0 && offset != 0xFFFFU )
            {
              /* parse the glyph ids array for non-0 index */
              p += offset + ( code - start ) * 2;
              while ( code <= end )
              {
                gindex = TT_NEXT_USHORT( p );
                if ( gindex != 0 )
                {
                  gindex = (FT_UInt)( gindex + delta ) & 0xFFFFU;
                  if ( gindex != 0 )
                    break;
                }
                code++;
              }
            }
            else if ( offset == 0xFFFFU )
            {
              /* an offset of 0xFFFF means an empty glyph in certain fonts! */
              code = end;
              break;
            }
            else
              gindex = (FT_UInt)( code + delta ) & 0xFFFFU;

            if ( gindex == 0 )
              break;

            result = code;
            goto Exit;
          }
        }
        /* loop to next trial charcode */
        if ( code >= 0xFFFFU )
          break;

        code++;
      }
    }

  Exit:
    *pchar_code = result;
    return gindex;
  }


  FT_CALLBACK_DEF( FT_Error )
  tt_cmap4_get_info( TT_CMap       cmap,
                     TT_CMapInfo  *cmap_info )
  {
    FT_Byte*  p = cmap->data + 4;


    cmap_info->language = (FT_ULong)TT_PEEK_USHORT( p );

    return SFNT_Err_Ok;
  }


  FT_CALLBACK_TABLE_DEF
  const TT_CMap_ClassRec  tt_cmap4_class_rec =
  {
    {
#ifdef OPT_CMAP4
      sizeof ( TT_CMap4Rec ),
      (FT_CMap_InitFunc)     tt_cmap4_init,
#else
      sizeof ( TT_CMapRec ),
      (FT_CMap_InitFunc)     tt_cmap_init,
#endif
      (FT_CMap_DoneFunc)     NULL,
      (FT_CMap_CharIndexFunc)tt_cmap4_char_index,
      (FT_CMap_CharNextFunc) tt_cmap4_char_next
    },
    4,
    (TT_CMap_ValidateFunc)   tt_cmap4_validate,
    (TT_CMap_Info_GetFunc)   tt_cmap4_get_info
  };

#endif /* TT_CONFIG_CMAP_FORMAT_4 */


  /*************************************************************************/
  /*************************************************************************/
  /*****                                                               *****/
  /*****                          FORMAT 6                             *****/
  /*****                                                               *****/
  /*************************************************************************/
  /*************************************************************************/

  /*************************************************************************/
  /*                                                                       */
  /* TABLE OVERVIEW                                                        */
  /* --------------                                                        */
  /*                                                                       */
  /*   NAME        OFFSET          TYPE             DESCRIPTION            */
  /*                                                                       */
  /*   format       0              USHORT           must be 4              */
  /*   length       2              USHORT           table length in bytes  */
  /*   language     4              USHORT           Mac language code      */
  /*                                                                       */
  /*   first        6              USHORT           first segment code     */
  /*   count        8              USHORT           segment size in chars  */
  /*   glyphIds     10             USHORT[count]    glyph ids              */
  /*                                                                       */
  /* A very simplified segment mapping.                                    */
  /*                                                                       */

#ifdef TT_CONFIG_CMAP_FORMAT_6

  FT_CALLBACK_DEF( FT_Error )
  tt_cmap6_validate( FT_Byte*      table,
                     FT_Validator  valid )
  {
    FT_Byte*  p;
    FT_UInt   length, count;


    if ( table + 10 > valid->limit )
      FT_INVALID_TOO_SHORT;

    p      = table + 2;
    length = TT_NEXT_USHORT( p );

    p      = table + 8;             /* skip language and start index */
    count  = TT_NEXT_USHORT( p );

    if ( table + length > valid->limit || length < 10 + count * 2 )
      FT_INVALID_TOO_SHORT;

    /* check glyph indices */
    if ( valid->level >= FT_VALIDATE_TIGHT )
    {
      FT_UInt  gindex;


      for ( ; count > 0; count-- )
      {
        gindex = TT_NEXT_USHORT( p );
        if ( gindex >= TT_VALID_GLYPH_COUNT( valid ) )
          FT_INVALID_GLYPH_ID;
      }
    }

    return SFNT_Err_Ok;
  }


  FT_CALLBACK_DEF( FT_UInt )
  tt_cmap6_char_index( TT_CMap    cmap,
                       FT_UInt32  char_code )
  {
    FT_Byte*  table  = cmap->data;
    FT_UInt   result = 0;
    FT_Byte*  p      = table + 6;
    FT_UInt   start  = TT_NEXT_USHORT( p );
    FT_UInt   count  = TT_NEXT_USHORT( p );
    FT_UInt   idx    = (FT_UInt)( char_code - start );


    if ( idx < count )
    {
      p += 2 * idx;
      result = TT_PEEK_USHORT( p );
    }
    return result;
  }


  FT_CALLBACK_DEF( FT_UInt )
  tt_cmap6_char_next( TT_CMap     cmap,
                      FT_UInt32  *pchar_code )
  {
    FT_Byte*   table     = cmap->data;
    FT_UInt32  result    = 0;
    FT_UInt32  char_code = *pchar_code + 1;
    FT_UInt    gindex    = 0;

    FT_Byte*   p         = table + 6;
    FT_UInt    start     = TT_NEXT_USHORT( p );
    FT_UInt    count     = TT_NEXT_USHORT( p );
    FT_UInt    idx;


    if ( char_code >= 0x10000UL )
      goto Exit;

    if ( char_code < start )
      char_code = start;

    idx = (FT_UInt)( char_code - start );
    p  += 2 * idx;

    for ( ; idx < count; idx++ )
    {
      gindex = TT_NEXT_USHORT( p );
      if ( gindex != 0 )
      {
        result = char_code;
        break;
      }
      char_code++;
    }

  Exit:
    *pchar_code = result;
    return gindex;
  }


  FT_CALLBACK_DEF( FT_Error )
  tt_cmap6_get_info( TT_CMap       cmap,
                     TT_CMapInfo  *cmap_info )
  {
    FT_Byte*  p = cmap->data + 4;


    cmap_info->language = (FT_ULong)TT_PEEK_USHORT( p );

    return SFNT_Err_Ok;
  }


  FT_CALLBACK_TABLE_DEF
  const TT_CMap_ClassRec  tt_cmap6_class_rec =
  {
    {
      sizeof ( TT_CMapRec ),

      (FT_CMap_InitFunc)     tt_cmap_init,
      (FT_CMap_DoneFunc)     NULL,
      (FT_CMap_CharIndexFunc)tt_cmap6_char_index,
      (FT_CMap_CharNextFunc) tt_cmap6_char_next
    },
    6,
    (TT_CMap_ValidateFunc)   tt_cmap6_validate,
    (TT_CMap_Info_GetFunc)   tt_cmap6_get_info
  };

#endif /* TT_CONFIG_CMAP_FORMAT_6 */


  /*************************************************************************/
  /*************************************************************************/
  /*****                                                               *****/
  /*****                          FORMAT 8                             *****/
  /*****                                                               *****/
  /***** It's hard to completely understand what the OpenType spec     *****/
  /***** says about this format, but here is my conclusion.            *****/
  /*****                                                               *****/
  /***** The purpose of this format is to easily map UTF-16 text to    *****/
  /***** glyph indices.  Basically, the `char_code' must be in one of  *****/
  /***** the following formats:                                        *****/
  /*****                                                               *****/
  /*****   - A 16-bit value that isn't part of the Unicode Surrogates  *****/
  /*****     Area (i.e. U+D800-U+DFFF).                                *****/
  /*****                                                               *****/
  /*****   - A 32-bit value, made of two surrogate values, i.e.. if    *****/
  /*****     `char_code = (char_hi << 16) | char_lo', then both        *****/
  /*****     `char_hi' and `char_lo' must be in the Surrogates Area.   *****/
  /*****      Area.                                                    *****/
  /*****                                                               *****/
  /***** The 'is32' table embedded in the charmap indicates whether a  *****/
  /***** given 16-bit value is in the surrogates area or not.          *****/
  /*****                                                               *****/
  /***** So, for any given `char_code', we can assert the following:   *****/
  /*****                                                               *****/
  /*****   If `char_hi == 0' then we must have `is32[char_lo] == 0'.   *****/
  /*****                                                               *****/
  /*****   If `char_hi != 0' then we must have both                    *****/
  /*****   `is32[char_hi] != 0' and `is32[char_lo] != 0'.              *****/
  /*****                                                               *****/
  /*************************************************************************/
  /*************************************************************************/

  /*************************************************************************/
  /*                                                                       */
  /* TABLE OVERVIEW                                                        */
  /* --------------                                                        */
  /*                                                                       */
  /*   NAME        OFFSET         TYPE        DESCRIPTION                  */
  /*                                                                       */
  /*   format      0              USHORT      must be 8                    */
  /*   reseved     2              USHORT      reserved                     */
  /*   length      4              ULONG       length in bytes              */
  /*   language    8              ULONG       Mac language code            */
  /*   is32        12             BYTE[8192]  32-bitness bitmap            */
  /*   count       8204           ULONG       number of groups             */
  /*                                                                       */
  /* This header is followed by 'count' groups of the following format:    */
  /*                                                                       */
  /*   start       0              ULONG       first charcode               */
  /*   end         4              ULONG       last charcode                */
  /*   startId     8              ULONG       start glyph id for the group */
  /*                                                                       */

#ifdef TT_CONFIG_CMAP_FORMAT_8

  FT_CALLBACK_DEF( FT_Error )
  tt_cmap8_validate( FT_Byte*      table,
                     FT_Validator  valid )
  {
    FT_Byte*   p = table + 4;
    FT_Byte*   is32;
    FT_UInt32  length;
    FT_UInt32  num_groups;


    if ( table + 16 + 8192 > valid->limit )
      FT_INVALID_TOO_SHORT;

    length = TT_NEXT_ULONG( p );
    if ( table + length > valid->limit || length < 8208 )
      FT_INVALID_TOO_SHORT;

    is32       = table + 12;
    p          = is32  + 8192;          /* skip `is32' array */
    num_groups = TT_NEXT_ULONG( p );

    if ( p + num_groups * 12 > valid->limit )

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -