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

📄 gxvcommn.c

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 C
📖 第 1 页 / 共 4 页
字号:
/***************************************************************************/
/*                                                                         */
/*  gxvcommn.c                                                             */
/*                                                                         */
/*    TrueTypeGX/AAT common tables validation (body).                      */
/*                                                                         */
/*  Copyright 2004, 2005 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */
/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
/*                                                                         */
/*  This file is part of the FreeType project, and may only be used,       */
/*  modified, and distributed under the terms of the FreeType project      */
/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
/*  this file you indicate that you have read the license and              */
/*  understand and accept it fully.                                        */
/*                                                                         */
/***************************************************************************/

/***************************************************************************/
/*                                                                         */
/* gxvalid is derived from both gxlayout module and otvalid module.        */
/* Development of gxlayout is supported by the Information-technology      */
/* Promotion Agency(IPA), Japan.                                           */
/*                                                                         */
/***************************************************************************/


#include "gxvcommn.h"


  /*************************************************************************/
  /*                                                                       */
  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
  /* messages during execution.                                            */
  /*                                                                       */
#undef  FT_COMPONENT
#define FT_COMPONENT  trace_gxvcommon


  /*************************************************************************/
  /*************************************************************************/
  /*****                                                               *****/
  /*****                       16bit offset sorter                     *****/
  /*****                                                               *****/
  /*************************************************************************/
  /*************************************************************************/

  static int
  gxv_compare_ushort_offset( FT_UShort*  a,
                             FT_UShort*  b )
  {
    if ( *a < *b )
      return ( -1 );
    else if ( *a > *b )
      return ( 1 );
    else
      return ( 0 );
  }


  FT_LOCAL_DEF( void )
  gxv_set_length_by_ushort_offset( FT_UShort*     offset,
                                   FT_UShort**    length,
                                   FT_UShort*     buff,
                                   FT_UInt        nmemb,
                                   FT_UShort      limit,
                                   GXV_Validator  valid )
  {
    FT_UInt  i;


    for ( i = 0; i < nmemb; i++ )
      *(length[i]) = 0;

    for ( i = 0; i < nmemb; i++ )
      buff[i] = offset[i];
    buff[nmemb] = limit;

    ft_qsort( buff, ( nmemb + 1 ), sizeof ( FT_UShort ),
              ( int(*)(const void*, const void*) )gxv_compare_ushort_offset );

    if ( buff[nmemb] > limit )
      FT_INVALID_OFFSET;

    for ( i = 0; i < nmemb; i++ )
    {
      FT_UInt  j;


      for ( j = 0; j < nmemb; j++ )
        if ( buff[j] == offset[i] )
          break;

      if ( j == nmemb )
        FT_INVALID_OFFSET;

      *(length[i]) = (FT_UShort)( buff[j + 1] - buff[j] );

      if ( 0 != offset[i] && 0 == *(length[i]) )
        FT_INVALID_OFFSET;
    }
  }


  /*************************************************************************/
  /*************************************************************************/
  /*****                                                               *****/
  /*****                       32bit offset sorter                     *****/
  /*****                                                               *****/
  /*************************************************************************/
  /*************************************************************************/

  static int
  gxv_compare_ulong_offset( FT_ULong*  a,
                            FT_ULong*  b )
  {
    if ( *a < *b )
      return ( -1 );
    else if ( *a > *b )
      return ( 1 );
    else
      return ( 0 );
  }


  FT_LOCAL_DEF( void )
  gxv_set_length_by_ulong_offset( FT_ULong*      offset,
                                  FT_ULong**     length,
                                  FT_ULong*      buff,
                                  FT_UInt        nmemb,
                                  FT_ULong       limit,
                                  GXV_Validator  valid)
  {
    FT_UInt  i;


    for ( i = 0; i < nmemb; i++ )
      *(length[i]) = 0;

    for ( i = 0; i < nmemb; i++ )
      buff[i] = offset[i];
    buff[nmemb] = limit;

    ft_qsort( buff, ( nmemb + 1 ), sizeof ( FT_ULong ),
              ( int(*)(const void*, const void*) )gxv_compare_ulong_offset );

    if ( buff[nmemb] > limit )
      FT_INVALID_OFFSET;

    for ( i = 0; i < nmemb; i++ )
    {
      FT_UInt  j;


      for ( j = 0; j < nmemb; j++ )
        if ( buff[j] == offset[i] )
          break;

      if ( j == nmemb )
        FT_INVALID_OFFSET;

      *(length[i]) = buff[j + 1] - buff[j];

      if ( 0 != offset[i] && 0 == *(length[i]) )
        FT_INVALID_OFFSET;
    }
  }


  /*************************************************************************/
  /*************************************************************************/
  /*****                                                               *****/
  /*****               scan value array and get min & max              *****/
  /*****                                                               *****/
  /*************************************************************************/
  /*************************************************************************/


  FT_LOCAL_DEF( void )
  gxv_array_getlimits_byte( FT_Bytes       table,
                            FT_Bytes       limit,
                            FT_Byte*       min,
                            FT_Byte*       max,
                            GXV_Validator  valid )
  {
    FT_Bytes  p = table;


    *min = 0xFF;
    *max = 0x00;

    while ( p < limit )
    {
      FT_Byte  val;


      GXV_LIMIT_CHECK( 1 );
      val = FT_NEXT_BYTE( p );

      *min = (FT_Byte)FT_MIN( *min, val );
      *max = (FT_Byte)FT_MAX( *max, val );
    }

    valid->subtable_length = p - table;
  }


  FT_LOCAL_DEF( void )
  gxv_array_getlimits_ushort( FT_Bytes       table,
                              FT_Bytes       limit,
                              FT_UShort*     min,
                              FT_UShort*     max,
                              GXV_Validator  valid )
  {
    FT_Bytes  p = table;


    *min = 0xFFFFU;
    *max = 0x0000;

    while ( p < limit )
    {
      FT_UShort  val;


      GXV_LIMIT_CHECK( 2 );
      val = FT_NEXT_USHORT( p );

      *min = (FT_Byte)FT_MIN( *min, val );
      *max = (FT_Byte)FT_MAX( *max, val );
    }

    valid->subtable_length = p - table;
  }


  /*************************************************************************/
  /*************************************************************************/
  /*****                                                               *****/
  /*****                       BINSEARCHHEADER                         *****/
  /*****                                                               *****/
  /*************************************************************************/
  /*************************************************************************/

  typedef struct  GXV_BinSrchHeader_
  {
    FT_UShort  unitSize;
    FT_UShort  nUnits;
    FT_UShort  searchRange;
    FT_UShort  entrySelector;
    FT_UShort  rangeShift;

  } GXV_BinSrchHeader;


  static void
  gxv_BinSrchHeader_check_consistency( GXV_BinSrchHeader*  binSrchHeader,
                                       GXV_Validator       valid )
  {
    FT_UShort  searchRange;
    FT_UShort  entrySelector;
    FT_UShort  rangeShift;


    if ( binSrchHeader->unitSize == 0 )
      FT_INVALID_DATA;

    if ( binSrchHeader->nUnits == 0 )
    {
      if ( binSrchHeader->searchRange   == 0 &&
           binSrchHeader->entrySelector == 0 &&
           binSrchHeader->rangeShift    == 0 )
        return;
      else
        FT_INVALID_DATA;
    }

    for ( searchRange = 1, entrySelector = 1;
          ( searchRange * 2 ) <= binSrchHeader->nUnits &&
            searchRange < 0x8000U;
          searchRange *= 2, entrySelector++ )
      ;

    entrySelector--;
    searchRange = (FT_UShort)( searchRange * binSrchHeader->unitSize );
    rangeShift  = (FT_UShort)( binSrchHeader->nUnits * binSrchHeader->unitSize
                               - searchRange );

    if ( searchRange   != binSrchHeader->searchRange   ||
         entrySelector != binSrchHeader->entrySelector ||
         rangeShift    != binSrchHeader->rangeShift    )
    {
      GXV_TRACE(( "Inconsistency found in BinSrchHeader\n" ));
      GXV_TRACE(( "originally: unitSize=%d, nUnits=%d, "
                  "searchRange=%d, entrySelector=%d, "
                  "rangeShift=%d\n",
                  binSrchHeader->unitSize, binSrchHeader->nUnits,
                  binSrchHeader->searchRange, binSrchHeader->entrySelector,
                  binSrchHeader->rangeShift ));
      GXV_TRACE(( "calculated: unitSize=%d, nUnits=%d, "
                  "searchRange=%d, entrySelector=%d, "
                  "rangeShift=%d\n",
                  binSrchHeader->unitSize, binSrchHeader->nUnits,
                  searchRange, entrySelector, rangeShift ));

      if ( valid->root->level >= FT_VALIDATE_PARANOID )
        FT_INVALID_DATA;
    }
  }


  /*
   * parser & validator of BinSrchHeader
   * which is used in LookupTable format 2, 4, 6.
   *
   * Essential parameters (unitSize, nUnits) are returned by
   * given pointer, others (searchRange, entrySelector, rangeShift)
   * can be calculated by essential parameters, so they are just
   * validated and discarded.
   *
   * However, wrong values in searchRange, entrySelector, rangeShift
   * won't cause fatal errors, because these parameters might be
   * only used in old m68k font driver in MacOS.
   *   -- suzuki toshiya <mpsuzuki@hiroshima-u.ac.jp>
   */

  FT_LOCAL_DEF( void )
  gxv_BinSrchHeader_validate( FT_Bytes       table,
                              FT_Bytes       limit,
                              FT_UShort*     unitSize_p,
                              FT_UShort*     nUnits_p,
                              GXV_Validator  valid )
  {
    FT_Bytes           p = table;
    GXV_BinSrchHeader  binSrchHeader;


    GXV_NAME_ENTER( "BinSrchHeader validate" );

    if ( *unitSize_p == 0 )
    {
      GXV_LIMIT_CHECK( 2 );
      binSrchHeader.unitSize =  FT_NEXT_USHORT( p );
    }
    else
      binSrchHeader.unitSize = *unitSize_p;

    if ( *nUnits_p == 0 )
    {
      GXV_LIMIT_CHECK( 2 );
      binSrchHeader.nUnits = FT_NEXT_USHORT( p );
    }
    else
      binSrchHeader.nUnits = *nUnits_p;

    GXV_LIMIT_CHECK( 2 + 2 + 2 );
    binSrchHeader.searchRange   = FT_NEXT_USHORT( p );
    binSrchHeader.entrySelector = FT_NEXT_USHORT( p );
    binSrchHeader.rangeShift    = FT_NEXT_USHORT( p );
    GXV_TRACE(( "nUnits %d\n", binSrchHeader.nUnits ));

    gxv_BinSrchHeader_check_consistency( &binSrchHeader, valid );

    if ( *unitSize_p == 0 )
      *unitSize_p = binSrchHeader.unitSize;

    if ( *nUnits_p == 0 )
      *nUnits_p = binSrchHeader.nUnits;

    valid->subtable_length = p - table;
    GXV_EXIT;
  }


  /*************************************************************************/
  /*************************************************************************/
  /*****                                                               *****/
  /*****                         LOOKUP TABLE                          *****/
  /*****                                                               *****/
  /*************************************************************************/
  /*************************************************************************/

#define GXV_LOOKUP_VALUE_LOAD( P, SIGNSPEC )                   \
          ( P += 2, gxv_lookup_value_load( P - 2, SIGNSPEC ) )

  static GXV_LookupValueDesc
  gxv_lookup_value_load( FT_Bytes  p,
                         int       signspec )
  {
    GXV_LookupValueDesc  v;


    if ( signspec == GXV_LOOKUPVALUE_UNSIGNED )
      v.u = FT_NEXT_USHORT( p );
    else
      v.s = FT_NEXT_SHORT( p );

    return v;
  }


#define GXV_UNITSIZE_VALIDATE( FORMAT, UNITSIZE, NUNITS, CORRECTSIZE ) \
          FT_BEGIN_STMNT                                               \
            if ( UNITSIZE != CORRECTSIZE )                             \
            {                                                          \
              FT_ERROR(( "unitSize=%d differs from"                    \
                         "expected unitSize=%d"                        \
                         "in LookupTable %s",                          \
                          UNITSIZE, CORRECTSIZE, FORMAT ));            \
              if ( UNITSIZE != 0 && NUNITS != 0 )                      \
              {                                                        \
                FT_ERROR(( " cannot validate anymore\n" ));            \
                FT_INVALID_FORMAT;                                     \
              }                                                        \
              else                                                     \
                FT_ERROR(( " forcibly continues\n" ));                 \
            }                                                          \
          FT_END_STMNT


  /* ================= Simple Array Format 0 Lookup Table ================ */
  static void
  gxv_LookupTable_fmt0_validate( FT_Bytes       table,
                                 FT_Bytes       limit,
                                 GXV_Validator  valid )
  {
    FT_Bytes   p = table;
    FT_UShort  i;

    GXV_LookupValueDesc  value;


    GXV_NAME_ENTER( "LookupTable format 0" );

    GXV_LIMIT_CHECK( 2 * valid->face->num_glyphs );

    for ( i = 0; i < valid->face->num_glyphs; i++ )
    {
      GXV_LIMIT_CHECK( 2 );
      if ( p + 2 >= limit )     /* some fonts have too-short fmt0 array */

⌨️ 快捷键说明

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