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

📄 otvgpos.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 2 页
字号:
                                ValueFormat1, ValueFormat2, valid );
      }
      break;

    case 2:     /* PairPosFormat2 */
      {
        FT_UInt  Coverage, ValueFormat1, ValueFormat2, ClassDef1, ClassDef2;
        FT_UInt  ClassCount1, ClassCount2, len_value1, len_value2, count;


        OTV_LIMIT_CHECK( 14 );
        Coverage     = FT_NEXT_USHORT( p );
        ValueFormat1 = FT_NEXT_USHORT( p );
        ValueFormat2 = FT_NEXT_USHORT( p );
        ClassDef1    = FT_NEXT_USHORT( p );
        ClassDef2    = FT_NEXT_USHORT( p );
        ClassCount1  = FT_NEXT_USHORT( p );
        ClassCount2  = FT_NEXT_USHORT( p );

        OTV_TRACE(( " (ClassCount1 = %d)\n", ClassCount1 ));
        OTV_TRACE(( " (ClassCount2 = %d)\n", ClassCount2 ));

        len_value1 = otv_value_length( ValueFormat1 );
        len_value2 = otv_value_length( ValueFormat2 );

        otv_Coverage_validate( table + Coverage, valid );
        otv_ClassDef_validate( table + ClassDef1, valid );
        otv_ClassDef_validate( table + ClassDef2, valid );

        OTV_LIMIT_CHECK( ClassCount1 * ClassCount2 *
                     ( len_value1 + len_value2 ) );

        /* Class1Record */
        for ( ; ClassCount1 > 0; ClassCount1-- )
        {
          /* Class2Record */
          for ( count = ClassCount2; count > 0; count-- )
          {
            if ( ValueFormat1 )
              /* Value1 */
              otv_ValueRecord_validate( p, ValueFormat1, valid );
            p += len_value1;

            if ( ValueFormat2 )
              /* Value2 */
              otv_ValueRecord_validate( p, ValueFormat2, valid );
            p += len_value2;
          }
        }
      }
      break;

    default:
      FT_INVALID_DATA;
    }

    OTV_EXIT;
  }


  /*************************************************************************/
  /*************************************************************************/
  /*****                                                               *****/
  /*****                     GPOS LOOKUP TYPE 3                        *****/
  /*****                                                               *****/
  /*************************************************************************/
  /*************************************************************************/

  static void
  otv_CursivePos_validate( FT_Bytes       table,
                           OTV_Validator  valid )
  {
    FT_Bytes  p = table;
    FT_UInt   PosFormat;


    OTV_NAME_ENTER( "CursivePos" );

    OTV_LIMIT_CHECK( 2 );
    PosFormat = FT_NEXT_USHORT( p );

    OTV_TRACE(( " (format %d)\n", PosFormat ));

    switch ( PosFormat )
    {
    case 1:     /* CursivePosFormat1 */
      {
        FT_UInt   table_size;
        FT_UInt   Coverage, EntryExitCount;

        OTV_OPTIONAL_TABLE( EntryAnchor );
        OTV_OPTIONAL_TABLE( ExitAnchor  );


        OTV_LIMIT_CHECK( 4 );
        Coverage       = FT_NEXT_USHORT( p );
        EntryExitCount = FT_NEXT_USHORT( p );

        OTV_TRACE(( " (EntryExitCount = %d)\n", EntryExitCount ));

        otv_Coverage_validate( table + Coverage, valid );

        OTV_LIMIT_CHECK( EntryExitCount * 4 );

        table_size = EntryExitCount * 4 + 4;

        /* EntryExitRecord */
        for ( ; EntryExitCount > 0; EntryExitCount-- )
        {
          OTV_OPTIONAL_OFFSET( EntryAnchor );
          OTV_OPTIONAL_OFFSET( ExitAnchor  );

          OTV_SIZE_CHECK( EntryAnchor );
          if ( EntryAnchor )
            otv_Anchor_validate( table + EntryAnchor, valid );

          OTV_SIZE_CHECK( ExitAnchor );
          if ( ExitAnchor )
            otv_Anchor_validate( table + ExitAnchor, valid );
        }
      }
      break;

    default:
      FT_INVALID_DATA;
    }

    OTV_EXIT;
  }


  /*************************************************************************/
  /*************************************************************************/
  /*****                                                               *****/
  /*****                     GPOS LOOKUP TYPE 4                        *****/
  /*****                                                               *****/
  /*************************************************************************/
  /*************************************************************************/

  /* sets valid->extra2 (0) */

  static void
  otv_MarkBasePos_validate( FT_Bytes       table,
                            OTV_Validator  valid )
  {
    FT_Bytes  p = table;
    FT_UInt   PosFormat;


    OTV_NAME_ENTER( "MarkBasePos" );

    OTV_LIMIT_CHECK( 2 );
    PosFormat = FT_NEXT_USHORT( p );

    OTV_TRACE(( " (format %d)\n", PosFormat ));

    switch ( PosFormat )
    {
    case 1:
      valid->extra2 = 0;
      OTV_NEST2( MarkBasePosFormat1, BaseArray );
      OTV_RUN( table, valid );
      break;

    default:
      FT_INVALID_DATA;
    }

    OTV_EXIT;
  }


  /*************************************************************************/
  /*************************************************************************/
  /*****                                                               *****/
  /*****                     GPOS LOOKUP TYPE 5                        *****/
  /*****                                                               *****/
  /*************************************************************************/
  /*************************************************************************/

  /* sets valid->extra2 (1) */

  static void
  otv_MarkLigPos_validate( FT_Bytes       table,
                           OTV_Validator  valid )
  {
    FT_Bytes  p = table;
    FT_UInt   PosFormat;


    OTV_NAME_ENTER( "MarkLigPos" );

    OTV_LIMIT_CHECK( 2 );
    PosFormat = FT_NEXT_USHORT( p );

    OTV_TRACE(( " (format %d)\n", PosFormat ));

    switch ( PosFormat )
    {
    case 1:
      valid->extra2 = 1;
      OTV_NEST3( MarkLigPosFormat1, LigatureArray, LigatureAttach );
      OTV_RUN( table, valid );
      break;

    default:
      FT_INVALID_DATA;
    }

    OTV_EXIT;
  }


  /*************************************************************************/
  /*************************************************************************/
  /*****                                                               *****/
  /*****                     GPOS LOOKUP TYPE 6                        *****/
  /*****                                                               *****/
  /*************************************************************************/
  /*************************************************************************/

  /* sets valid->extra2 (0) */

  static void
  otv_MarkMarkPos_validate( FT_Bytes       table,
                            OTV_Validator  valid )
  {
    FT_Bytes  p = table;
    FT_UInt   PosFormat;


    OTV_NAME_ENTER( "MarkMarkPos" );

    OTV_LIMIT_CHECK( 2 );
    PosFormat = FT_NEXT_USHORT( p );

    OTV_TRACE(( " (format %d)\n", PosFormat ));

    switch ( PosFormat )
    {
    case 1:
      valid->extra2 = 0;
      OTV_NEST2( MarkMarkPosFormat1, Mark2Array );
      OTV_RUN( table, valid );
      break;

    default:
      FT_INVALID_DATA;
    }

    OTV_EXIT;
  }


  /*************************************************************************/
  /*************************************************************************/
  /*****                                                               *****/
  /*****                     GPOS LOOKUP TYPE 7                        *****/
  /*****                                                               *****/
  /*************************************************************************/
  /*************************************************************************/

  /* sets valid->extra1 (lookup count) */

  static void
  otv_ContextPos_validate( FT_Bytes       table,
                           OTV_Validator  valid )
  {
    FT_Bytes  p = table;
    FT_UInt   PosFormat;


    OTV_NAME_ENTER( "ContextPos" );

    OTV_LIMIT_CHECK( 2 );
    PosFormat = FT_NEXT_USHORT( p );

    OTV_TRACE(( " (format %d)\n", PosFormat ));

    switch ( PosFormat )
    {
    case 1:
      /* no need to check glyph indices/classes used as input for these */
      /* context rules since even invalid glyph indices/classes return  */
      /* meaningful results                                             */

      valid->extra1 = valid->lookup_count;
      OTV_NEST3( ContextPosFormat1, PosRuleSet, PosRule );
      OTV_RUN( table, valid );
      break;

    case 2:
      /* no need to check glyph indices/classes used as input for these */
      /* context rules since even invalid glyph indices/classes return  */
      /* meaningful results                                             */

      OTV_NEST3( ContextPosFormat2, PosClassSet, PosClassRule );
      OTV_RUN( table, valid );
      break;

    case 3:
      OTV_NEST1( ContextPosFormat3 );
      OTV_RUN( table, valid );
      break;

    default:
      FT_INVALID_DATA;
    }

    OTV_EXIT;
  }


  /*************************************************************************/
  /*************************************************************************/
  /*****                                                               *****/
  /*****                     GPOS LOOKUP TYPE 8                        *****/
  /*****                                                               *****/
  /*************************************************************************/
  /*************************************************************************/

  /* sets valid->extra1 (lookup count) */

  static void
  otv_ChainContextPos_validate( FT_Bytes       table,
                                OTV_Validator  valid )
  {
    FT_Bytes  p = table;
    FT_UInt   PosFormat;


    OTV_NAME_ENTER( "ChainContextPos" );

    OTV_LIMIT_CHECK( 2 );
    PosFormat = FT_NEXT_USHORT( p );

    OTV_TRACE(( " (format %d)\n", PosFormat ));

    switch ( PosFormat )
    {
    case 1:
      /* no need to check glyph indices/classes used as input for these */
      /* context rules since even invalid glyph indices/classes return  */
      /* meaningful results                                             */

      valid->extra1 = valid->lookup_count;
      OTV_NEST3( ChainContextPosFormat1,
                 ChainPosRuleSet, ChainPosRule );
      OTV_RUN( table, valid );
      break;

    case 2:
      /* no need to check glyph indices/classes used as input for these */
      /* context rules since even invalid glyph indices/classes return  */
      /* meaningful results                                             */

      OTV_NEST3( ChainContextPosFormat2,
                 ChainPosClassSet, ChainPosClassRule );
      OTV_RUN( table, valid );
      break;

    case 3:
      OTV_NEST1( ChainContextPosFormat3 );
      OTV_RUN( table, valid );
      break;

    default:
      FT_INVALID_DATA;
    }

    OTV_EXIT;
  }


  /*************************************************************************/
  /*************************************************************************/
  /*****                                                               *****/
  /*****                     GPOS LOOKUP TYPE 9                        *****/
  /*****                                                               *****/
  /*************************************************************************/
  /*************************************************************************/

  /* uses valid->type_funcs */

  static void
  otv_ExtensionPos_validate( FT_Bytes       table,
                             OTV_Validator  valid )
  {
    FT_Bytes  p = table;
    FT_UInt   PosFormat;


    OTV_NAME_ENTER( "ExtensionPos" );

    OTV_LIMIT_CHECK( 2 );
    PosFormat = FT_NEXT_USHORT( p );

    OTV_TRACE(( " (format %d)\n", PosFormat ));

    switch ( PosFormat )
    {
    case 1:     /* ExtensionPosFormat1 */
      {
        FT_UInt            ExtensionLookupType, ExtensionOffset;
        OTV_Validate_Func  validate;


        OTV_LIMIT_CHECK( 6 );
        ExtensionLookupType = FT_NEXT_USHORT( p );
        ExtensionOffset     = FT_NEXT_ULONG( p );

        if ( ExtensionLookupType == 0 || ExtensionLookupType >= 9 )
          FT_INVALID_DATA;

        validate = valid->type_funcs[ExtensionLookupType - 1];
        validate( table + ExtensionOffset, valid );
      }
      break;

    default:
      FT_INVALID_DATA;
    }

    OTV_EXIT;
  }


  static const OTV_Validate_Func  otv_gpos_validate_funcs[9] =
  {
    otv_SinglePos_validate,
    otv_PairPos_validate,
    otv_CursivePos_validate,
    otv_MarkBasePos_validate,
    otv_MarkLigPos_validate,
    otv_MarkMarkPos_validate,
    otv_ContextPos_validate,
    otv_ChainContextPos_validate,
    otv_ExtensionPos_validate
  };


  /* sets valid->type_count */
  /* sets valid->type_funcs */

  FT_LOCAL_DEF( void )
  otv_GPOS_subtable_validate( FT_Bytes       table,
                              OTV_Validator  valid )
  {
    valid->type_count = 9;
    valid->type_funcs = (OTV_Validate_Func*)otv_gpos_validate_funcs;

    otv_Lookup_validate( table, valid );
  }


  /*************************************************************************/
  /*************************************************************************/
  /*****                                                               *****/
  /*****                          GPOS TABLE                           *****/
  /*****                                                               *****/
  /*************************************************************************/
  /*************************************************************************/

  /* sets valid->glyph_count */

  FT_LOCAL_DEF( void )
  otv_GPOS_validate( FT_Bytes      table,
                     FT_UInt       glyph_count,
                     FT_Validator  ftvalid )
  {
    OTV_ValidatorRec  validrec;
    OTV_Validator     valid = &validrec;
    FT_Bytes          p     = table;
    FT_UInt           ScriptList, FeatureList, LookupList;


    valid->root = ftvalid;

    FT_TRACE3(( "validating GPOS table\n" ));
    OTV_INIT;

    OTV_LIMIT_CHECK( 10 );

    if ( FT_NEXT_ULONG( p ) != 0x10000UL )      /* Version */
      FT_INVALID_DATA;

    ScriptList  = FT_NEXT_USHORT( p );
    FeatureList = FT_NEXT_USHORT( p );
    LookupList  = FT_NEXT_USHORT( p );

    valid->type_count  = 9;
    valid->type_funcs  = (OTV_Validate_Func*)otv_gpos_validate_funcs;
    valid->glyph_count = glyph_count;

    otv_LookupList_validate( table + LookupList,
                             valid );
    otv_FeatureList_validate( table + FeatureList, table + LookupList,
                              valid );
    otv_ScriptList_validate( table + ScriptList, table + FeatureList,
                             valid );

    FT_TRACE4(( "\n" ));
  }


/* END */

⌨️ 快捷键说明

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