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

📄 gxvcommn.c

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 C
📖 第 1 页 / 共 4 页
字号:
  }


  /* ================= eXtended State Table (for morx) =================== */

  FT_LOCAL_DEF( void )
  gxv_XStateTable_subtable_setup( FT_ULong       table_size,
                                  FT_ULong       classTable,
                                  FT_ULong       stateArray,
                                  FT_ULong       entryTable,
                                  FT_ULong*      classTable_length_p,
                                  FT_ULong*      stateArray_length_p,
                                  FT_ULong*      entryTable_length_p,
                                  GXV_Validator  valid )
  {
    FT_ULong   o[3];
    FT_ULong*  l[3];
    FT_ULong   buff[4];


    o[0] = classTable;
    o[1] = stateArray;
    o[2] = entryTable;
    l[0] = classTable_length_p;
    l[1] = stateArray_length_p;
    l[2] = entryTable_length_p;

    gxv_set_length_by_ulong_offset( o, l, buff, 4, table_size, valid );
  }


  static void
  gxv_XClassTable_lookupval_validate( FT_UShort            glyph,
                                      GXV_LookupValueDesc  value,
                                      GXV_Validator        valid )
  {
    FT_UNUSED( glyph );

    if ( value.u >= valid->xstatetable.nClasses )
      FT_INVALID_DATA;
    if ( value.u > valid->xstatetable.maxClassID )
      valid->xstatetable.maxClassID = value.u;
  }


  /*
    +===============+ --------+
    | lookup header |         |
    +===============+         |
    | BinSrchHeader |         |
    +===============+         |
    | lastGlyph[0]  |         |
    +---------------+         |
    | firstGlyph[0] |         |    head of lookup table
    +---------------+         |             +
    | offset[0]     |    ->   |          offset            [byte]
    +===============+         |             +
    | lastGlyph[1]  |         | (glyphID - firstGlyph) * 2 [byte]
    +---------------+         |
    | firstGlyph[1] |         |
    +---------------+         |
    | offset[1]     |         |
    +===============+         |
                              |
     ....                     |
                              |
    16bit value array         |
    +===============+         |
    |     value     | <-------+
     ....
  */
  static GXV_LookupValueDesc
  gxv_XClassTable_lookupfmt4_transit( FT_UShort            relative_gindex,
                                      GXV_LookupValueDesc  base_value,
                                      FT_Bytes             lookuptbl_limit,
                                      GXV_Validator        valid )
  {
    FT_Bytes             p;
    FT_Bytes             limit;
    FT_UShort            offset;
    GXV_LookupValueDesc  value;

    /* XXX: check range? */
    offset = (FT_UShort)( base_value.u +
                          relative_gindex * sizeof ( FT_UShort ) );

    p     = valid->lookuptbl_head + offset;
    limit = lookuptbl_limit;

    GXV_LIMIT_CHECK ( 2 );
    value.u = FT_NEXT_USHORT( p );

    return value;
  }


  static void
  gxv_XStateArray_validate( FT_Bytes       table,
                            FT_ULong*      length_p,
                            FT_UShort      maxClassID,
                            FT_ULong       stateSize,
                            FT_UShort*     maxState_p,
                            FT_UShort*     maxEntry_p,
                            GXV_Validator  valid )
  {
    FT_Bytes   p = table;
    FT_Bytes   limit = table + *length_p;
    FT_UShort  clazz;
    FT_UShort  entry;

    FT_UNUSED( stateSize ); /* for the non-debugging case */


    GXV_NAME_ENTER( "XStateArray" );

    GXV_TRACE(( "parse % 3d bytes by stateSize=% 3d maxClassID=% 3d\n",
                (int)(*length_p), stateSize, (int)(maxClassID) ));

    /*
     * 2 states are predefined and must be described:
     * state 0 (start of text), 1 (start of line)
     */
    GXV_LIMIT_CHECK( ( 1 + maxClassID ) * 2 * 2 );

    *maxState_p = 0;
    *maxEntry_p = 0;

    /* read if enough to read another state */
    while ( p + ( ( 1 + maxClassID ) * 2 ) <= limit )
    {
      (*maxState_p)++;
      for ( clazz = 0; clazz <= maxClassID; clazz++ )
      {
        entry = FT_NEXT_USHORT( p );
        *maxEntry_p = (FT_UShort)FT_MAX( *maxEntry_p, entry );
      }
    }
    GXV_TRACE(( "parsed: maxState=%d, maxEntry=%d\n",
                *maxState_p, *maxEntry_p ));

    *length_p = p - table;

    GXV_EXIT;
  }


  static void
  gxv_XEntryTable_validate( FT_Bytes       table,
                            FT_ULong*      length_p,
                            FT_UShort      maxEntry,
                            FT_ULong       stateArray_length,
                            FT_UShort      maxClassID,
                            FT_Bytes       xstatetable_table,
                            FT_Bytes       xstatetable_limit,
                            GXV_Validator  valid )
  {
    FT_Bytes   p = table;
    FT_Bytes   limit = table + *length_p;
    FT_UShort  entry;
    FT_UShort  state;
    FT_Int     entrySize = 2 + 2 + GXV_GLYPHOFFSET_SIZE( xstatetable );


    GXV_NAME_ENTER( "XEntryTable" );
    GXV_TRACE(( "maxEntry=%d entrySize=%d\n", maxEntry, entrySize ));

    if ( ( p + ( maxEntry + 1 ) * entrySize ) > limit )
      FT_INVALID_TOO_SHORT;

    for (entry = 0; entry <= maxEntry ; entry++ )
    {
      FT_UShort                        newState_idx;
      FT_UShort                        flags;
      GXV_XStateTable_GlyphOffsetDesc  glyphOffset;


      GXV_LIMIT_CHECK( 2 + 2 );
      newState_idx = FT_NEXT_USHORT( p );
      flags        = FT_NEXT_USHORT( p );

      if ( stateArray_length < (FT_ULong)( newState_idx * 2 ) )
      {
        GXV_TRACE(( "  newState index 0x%04x points out of stateArray\n",
                    newState_idx ));
        if ( valid->root->level >= FT_VALIDATE_PARANOID )
          FT_INVALID_OFFSET;
      }

      state = (FT_UShort)( newState_idx / ( 1 + maxClassID ) );
      if ( 0 != ( newState_idx % ( 1 + maxClassID ) ) )
      {
        FT_TRACE4(( "-> new state = %d (supposed)\n"
                    "but newState index 0x%04x is not aligned to %d-classes\n",
                    state, newState_idx,  1 + maxClassID ));
        if ( valid->root->level >= FT_VALIDATE_PARANOID )
          FT_INVALID_OFFSET;
      }

      switch ( GXV_GLYPHOFFSET_FMT( xstatetable ) )
      {
      case GXV_GLYPHOFFSET_NONE:
        glyphOffset.uc = 0; /* make compiler happy */
        break;

      case GXV_GLYPHOFFSET_UCHAR:
        glyphOffset.uc = FT_NEXT_BYTE( p );
        break;

      case GXV_GLYPHOFFSET_CHAR:
        glyphOffset.c = FT_NEXT_CHAR( p );
        break;

      case GXV_GLYPHOFFSET_USHORT:
        glyphOffset.u = FT_NEXT_USHORT( p );
        break;

      case GXV_GLYPHOFFSET_SHORT:
        glyphOffset.s = FT_NEXT_SHORT( p );
        break;

      case GXV_GLYPHOFFSET_ULONG:
        glyphOffset.ul = FT_NEXT_ULONG( p );
        break;

      case GXV_GLYPHOFFSET_LONG:
        glyphOffset.l = FT_NEXT_LONG( p );
        break;

      default:
        if ( valid->root->level >= FT_VALIDATE_PARANOID )
          FT_INVALID_FORMAT;
        goto Exit;
      }

      if ( NULL != valid->xstatetable.entry_validate_func )
        valid->xstatetable.entry_validate_func( state,
                                                flags,
                                                glyphOffset,
                                                xstatetable_table,
                                                xstatetable_limit,
                                                valid );
    }

  Exit:
    *length_p = p - table;

    GXV_EXIT;
  }


  FT_LOCAL_DEF( void )
  gxv_XStateTable_validate( FT_Bytes       table,
                            FT_Bytes       limit,
                            GXV_Validator  valid )
  {
    /* StateHeader members */
    FT_ULong   classTable;      /* offset to Class(Sub)Table */
    FT_ULong   stateArray;      /* offset to StateArray */
    FT_ULong   entryTable;      /* offset to EntryTable */

    FT_ULong   classTable_length;
    FT_ULong   stateArray_length;
    FT_ULong   entryTable_length;
    FT_UShort  maxState;
    FT_UShort  maxEntry;

    GXV_XStateTable_Subtable_Setup_Func  setup_func;

    FT_Bytes   p = table;


    GXV_NAME_ENTER( "XStateTable" );

    GXV_TRACE(( "XStateTable header\n" ));

    GXV_LIMIT_CHECK( 4 + 4 + 4 + 4 );
    valid->xstatetable.nClasses = FT_NEXT_ULONG( p );
    classTable = FT_NEXT_ULONG( p );
    stateArray = FT_NEXT_ULONG( p );
    entryTable = FT_NEXT_ULONG( p );

    GXV_TRACE(( "nClasses =0x%08x\n", valid->xstatetable.nClasses ));
    GXV_TRACE(( "offset to classTable=0x%08x\n", classTable ));
    GXV_TRACE(( "offset to stateArray=0x%08x\n", stateArray ));
    GXV_TRACE(( "offset to entryTable=0x%08x\n", entryTable ));

    if ( valid->xstatetable.nClasses > 0xFFFFU )
      FT_INVALID_DATA;

    GXV_TRACE(( "StateTable Subtables\n" ));

    if ( valid->xstatetable.optdata_load_func != NULL )
      valid->xstatetable.optdata_load_func( p, limit, valid );

    if ( valid->xstatetable.subtable_setup_func != NULL )
      setup_func = valid->xstatetable.subtable_setup_func;
    else
      setup_func = gxv_XStateTable_subtable_setup;

    setup_func( limit - table,
                classTable,
                stateArray,
                entryTable,
                &classTable_length,
                &stateArray_length,
                &entryTable_length,
                valid );

    if ( classTable != 0 )
    {
      valid->xstatetable.maxClassID = 0;
      valid->lookupval_sign         = GXV_LOOKUPVALUE_UNSIGNED;
      valid->lookupval_func         = gxv_XClassTable_lookupval_validate;
      valid->lookupfmt4_trans       = gxv_XClassTable_lookupfmt4_transit;
      gxv_LookupTable_validate( table + classTable,
                                table + classTable + classTable_length,
                                valid );
      if ( valid->subtable_length < classTable_length )
        classTable_length = valid->subtable_length;
    }
    else
    {
      /* XXX: check range? */
      valid->xstatetable.maxClassID =
        (FT_UShort)( valid->xstatetable.nClasses - 1 );
    }

    if ( stateArray != 0 )
      gxv_XStateArray_validate( table + stateArray,
                                &stateArray_length,
                                valid->xstatetable.maxClassID,
                                valid->xstatetable.nClasses,
                                &maxState,
                                &maxEntry,
                                valid );
    else
    {
      maxState = 1; /* 0:start of text, 1:start of line are predefined */
      maxEntry = 0;
    }

    if ( maxEntry > 0 && entryTable == 0 )
      FT_INVALID_OFFSET;

    if ( entryTable != 0 )
      gxv_XEntryTable_validate( table + entryTable,
                                &entryTable_length,
                                maxEntry,
                                stateArray_length,
                                valid->xstatetable.maxClassID,
                                table,
                                limit,
                                valid );

    GXV_EXIT;
  }


  /*************************************************************************/
  /*************************************************************************/
  /*****                                                               *****/
  /*****                        Table overlapping                      *****/
  /*****                                                               *****/
  /*************************************************************************/
  /*************************************************************************/

  static int
  gxv_compare_ranges( FT_Bytes  table1_start,
                      FT_ULong  table1_length,
                      FT_Bytes  table2_start,
                      FT_ULong  table2_length )
  {
    if ( table1_start == table2_start )
    {
      if ( ( table1_length == 0 || table2_length == 0 ) )
        goto Out;
    }
    else if ( table1_start < table2_start )
    {
      if ( ( table1_start + table1_length ) <= table2_start )
        goto Out;
    }
    else if ( table1_start > table2_start )
    {
      if ( ( table1_start >= table2_start + table2_length ) )
        goto Out;
    }
    return 1;

  Out:
    return 0;
  }


  FT_LOCAL_DEF( void )
  gxv_odtect_add_range( FT_Bytes          start,
                        FT_ULong          length,
                        const FT_String*  name,
                        GXV_odtect_Range  odtect )
  {
    odtect->range[ odtect->nRanges ].start  = start;
    odtect->range[ odtect->nRanges ].length = length;
    odtect->range[ odtect->nRanges ].name   = (FT_String*)name;
    odtect->nRanges++;
  }


  FT_LOCAL_DEF( void )
  gxv_odtect_validate( GXV_odtect_Range  odtect,
                       GXV_Validator     valid )
  {
    FT_UInt  i, j;


    GXV_NAME_ENTER( "check overlap among multi ranges" );

    for ( i = 0; i < odtect->nRanges; i++ )
      for ( j = 0; j < i; j++ )
        if ( 0 != gxv_compare_ranges( odtect->range[i].start,
                                      odtect->range[i].length,
                                      odtect->range[j].start,
                                      odtect->range[j].length ) )
        {
          if ( odtect->range[i].name || odtect->range[j].name )
            GXV_TRACE(( "found overlap between range %d and range %d\n",
                        i, j ));
          else
            GXV_TRACE(( "found overlap between `%s' and `%s\'\n",
                        odtect->range[i].name,
                        odtect->range[j].name ));
          FT_INVALID_OFFSET;
        }

    GXV_EXIT;
  }


/* END */

⌨️ 快捷键说明

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