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

📄 gxvcommn.c

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 C
📖 第 1 页 / 共 4 页
字号:
      {
        GXV_TRACE(( "too short, glyphs %d - %d are missing\n",
                    i, valid->face->num_glyphs ));
        if ( valid->root->level >= FT_VALIDATE_PARANOID )
          FT_INVALID_GLYPH_ID;
        break;
      }

      value = GXV_LOOKUP_VALUE_LOAD( p, valid->lookupval_sign );
      valid->lookupval_func( i, value, valid );
    }

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


  /* ================= Segment Single Format 2 Loolup Table ============== */
  /*
   * Apple spec says:
   *
   *   To guarantee that a binary search terminates, you must include one or
   *   more special `end of search table' values at the end of the data to
   *   be searched.  The number of termination values that need to be
   *   included is table-specific.  The value that indicates binary search
   *   termination is 0xFFFF.
   *
   * The problem is that nUnits does not include this end-marker.  It's
   * quite difficult to discriminate whether the following 0xFFFF comes from
   * the end-marker or some next data.
   *
   *   -- suzuki toshiya <mpsuzuki@hiroshima-u.ac.jp>
   */
  static void
  gxv_LookupTable_fmt2_skip_endmarkers( FT_Bytes       table,
                                        FT_UShort      unitSize,
                                        GXV_Validator  valid )
  {
    FT_Bytes  p = table;


    while ( ( p + 4 ) < valid->root->limit )
    {
      if ( p[0] != 0xFF || p[1] != 0xFF || /* lastGlyph */
           p[2] != 0xFF || p[3] != 0xFF )  /* firstGlyph */
        break;
      p += unitSize;
    }

    valid->subtable_length = p - table;
  }


  static void
  gxv_LookupTable_fmt2_validate( FT_Bytes       table,
                                 FT_Bytes       limit,
                                 GXV_Validator  valid )
  {
    FT_Bytes             p = table;
    FT_UShort            gid;

    FT_UShort            unitSize;
    FT_UShort            nUnits;
    FT_UShort            unit;
    FT_UShort            lastGlyph;
    FT_UShort            firstGlyph;
    GXV_LookupValueDesc  value;


    GXV_NAME_ENTER( "LookupTable format 2" );

    unitSize = nUnits = 0;
    gxv_BinSrchHeader_validate( p, limit, &unitSize, &nUnits, valid );
    p += valid->subtable_length;

    GXV_UNITSIZE_VALIDATE( "format2", unitSize, nUnits, 6 );

    for ( unit = 0, gid = 0; unit < nUnits; unit++ )
    {
      GXV_LIMIT_CHECK( 2 + 2 + 2 );
      lastGlyph  = FT_NEXT_USHORT( p );
      firstGlyph = FT_NEXT_USHORT( p );
      value      = GXV_LOOKUP_VALUE_LOAD( p, valid->lookupval_sign );

      gxv_glyphid_validate( firstGlyph, valid );
      gxv_glyphid_validate( lastGlyph, valid );

      if ( lastGlyph < gid )
      {
        GXV_TRACE(( "reverse ordered segment specification:"
                    " lastGlyph[%d]=%d < lastGlyph[%d]=%d\n",
                    unit, lastGlyph, unit - 1 , gid ));
        if ( valid->root->level >= FT_VALIDATE_PARANOID )
          FT_INVALID_GLYPH_ID;
      }

      if ( lastGlyph < firstGlyph )
      {
        GXV_TRACE(( "reverse ordered range specification at unit %d:",
                    " lastGlyph %d < firstGlyph %d ",
                    unit, lastGlyph, firstGlyph ));
        if ( valid->root->level >= FT_VALIDATE_PARANOID )
          FT_INVALID_GLYPH_ID;

        if ( valid->root->level == FT_VALIDATE_TIGHT )
          continue;     /* ftxvalidator silently skips such an entry */

        FT_TRACE4(( "continuing with exchanged values\n" ));
        gid        = firstGlyph;
        firstGlyph = lastGlyph;
        lastGlyph  = gid;
      }

      for ( gid = firstGlyph; gid <= lastGlyph; gid++ )
        valid->lookupval_func( gid, value, valid );
    }

    gxv_LookupTable_fmt2_skip_endmarkers( p, unitSize, valid );
    p += valid->subtable_length;

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


  /* ================= Segment Array Format 4 Lookup Table =============== */
  static void
  gxv_LookupTable_fmt4_validate( FT_Bytes       table,
                                 FT_Bytes       limit,
                                 GXV_Validator  valid )
  {
    FT_Bytes             p = table;
    FT_UShort            unit;
    FT_UShort            gid;

    FT_UShort            unitSize;
    FT_UShort            nUnits;
    FT_UShort            lastGlyph;
    FT_UShort            firstGlyph;
    GXV_LookupValueDesc  base_value;
    GXV_LookupValueDesc  value;


    GXV_NAME_ENTER( "LookupTable format 4" );

    unitSize = nUnits = 0;
    gxv_BinSrchHeader_validate( p, limit, &unitSize, &nUnits, valid );
    p += valid->subtable_length;

    GXV_UNITSIZE_VALIDATE( "format4", unitSize, nUnits, 6 );

    for ( unit = 0, gid = 0; unit < nUnits; unit++ )
    {
      GXV_LIMIT_CHECK( 2 + 2 );
      lastGlyph  = FT_NEXT_USHORT( p );
      firstGlyph = FT_NEXT_USHORT( p );

      gxv_glyphid_validate( firstGlyph, valid );
      gxv_glyphid_validate( lastGlyph, valid );

      if ( lastGlyph < gid )
      {
        GXV_TRACE(( "reverse ordered segment specification:"
                    " lastGlyph[%d]=%d < lastGlyph[%d]=%d\n",
                    unit, lastGlyph, unit - 1 , gid ));
        if ( valid->root->level >= FT_VALIDATE_PARANOID )
          FT_INVALID_GLYPH_ID;
      }

      if ( lastGlyph < firstGlyph )
      {
        GXV_TRACE(( "reverse ordered range specification at unit %d:",
                    " lastGlyph %d < firstGlyph %d ",
                    unit, lastGlyph, firstGlyph ));
        if ( valid->root->level >= FT_VALIDATE_PARANOID )
          FT_INVALID_GLYPH_ID;

        if ( valid->root->level == FT_VALIDATE_TIGHT )
          continue; /* ftxvalidator silently skips such an entry */

        FT_TRACE4(( "continuing with exchanged values\n" ));
        gid        = firstGlyph;
        firstGlyph = lastGlyph;
        lastGlyph  = gid;
      }

      GXV_LIMIT_CHECK( 2 );
      base_value = GXV_LOOKUP_VALUE_LOAD( p, GXV_LOOKUPVALUE_UNSIGNED );

      for ( gid = firstGlyph; gid <= lastGlyph; gid++ )
      {
        value = valid->lookupfmt4_trans( (FT_UShort)( gid - firstGlyph ),
                                         base_value,
                                         limit,
                                         valid );

        valid->lookupval_func( gid, value, valid );
      }
    }

    gxv_LookupTable_fmt2_skip_endmarkers( p, unitSize, valid );
    p += valid->subtable_length;

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


  /* ================= Segment Table Format 6 Lookup Table =============== */
  static void
  gxv_LookupTable_fmt6_skip_endmarkers( FT_Bytes       table,
                                        FT_UShort      unitSize,
                                        GXV_Validator  valid )
  {
    FT_Bytes  p = table;


    while ( p < valid->root->limit )
    {
      if ( p[0] != 0xFF || p[1] != 0xFF )
        break;
      p += unitSize;
    }

    valid->subtable_length = p - table;
  }


  static void
  gxv_LookupTable_fmt6_validate( FT_Bytes       table,
                                 FT_Bytes       limit,
                                 GXV_Validator  valid )
  {
    FT_Bytes             p = table;
    FT_UShort            unit;
    FT_UShort            prev_glyph;

    FT_UShort            unitSize;
    FT_UShort            nUnits;
    FT_UShort            glyph;
    GXV_LookupValueDesc  value;


    GXV_NAME_ENTER( "LookupTable format 6" );

    unitSize = nUnits = 0;
    gxv_BinSrchHeader_validate( p, limit, &unitSize, &nUnits, valid );
    p += valid->subtable_length;

    GXV_UNITSIZE_VALIDATE( "format6", unitSize, nUnits, 4 );

    for ( unit = 0, prev_glyph = 0; unit < nUnits; unit++ )
    {
      GXV_LIMIT_CHECK( 2 + 2 );
      glyph = FT_NEXT_USHORT( p );
      value = GXV_LOOKUP_VALUE_LOAD( p, valid->lookupval_sign );

      if ( gxv_glyphid_validate( glyph, valid ) )
        GXV_TRACE(( " endmarker found within defined range"
                    " (entry %d < nUnits=%d)\n",
                    unit, nUnits ));

      if ( prev_glyph > glyph )
      {
        GXV_TRACE(( "current gid 0x%04x < previous gid 0x%04x\n",
                    glyph, prev_glyph ));
        if ( valid->root->level >= FT_VALIDATE_PARANOID )
          FT_INVALID_GLYPH_ID;
      }
      prev_glyph = glyph;

      valid->lookupval_func( glyph, value, valid );
    }

    gxv_LookupTable_fmt6_skip_endmarkers( p, unitSize, valid );
    p += valid->subtable_length;

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


  /* ================= Trimmed Array Format 8 Lookup Table =============== */
  static void
  gxv_LookupTable_fmt8_validate( FT_Bytes       table,
                                 FT_Bytes       limit,
                                 GXV_Validator  valid )
  {
    FT_Bytes              p = table;
    FT_UShort             i;

    GXV_LookupValueDesc   value;
    FT_UShort             firstGlyph;
    FT_UShort             glyphCount;


    GXV_NAME_ENTER( "LookupTable format 8" );

    /* firstGlyph + glyphCount */
    GXV_LIMIT_CHECK( 2 + 2 );
    firstGlyph = FT_NEXT_USHORT( p );
    glyphCount = FT_NEXT_USHORT( p );

    gxv_glyphid_validate( firstGlyph, valid );
    gxv_glyphid_validate( (FT_UShort)( firstGlyph + glyphCount ), valid );

    /* valueArray */
    for ( i = 0; i < glyphCount; i++ )
    {
      GXV_LIMIT_CHECK( 2 );
      value = GXV_LOOKUP_VALUE_LOAD( p, valid->lookupval_sign );
      valid->lookupval_func( (FT_UShort)( firstGlyph + i ), value, valid );
    }

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


  FT_LOCAL_DEF( void )
  gxv_LookupTable_validate( FT_Bytes       table,
                            FT_Bytes       limit,
                            GXV_Validator  valid )
  {
    FT_Bytes   p = table;
    FT_UShort  format;

    GXV_Validate_Func  fmt_funcs_table[] =
    {
      gxv_LookupTable_fmt0_validate, /* 0 */
      NULL,                          /* 1 */
      gxv_LookupTable_fmt2_validate, /* 2 */
      NULL,                          /* 3 */
      gxv_LookupTable_fmt4_validate, /* 4 */
      NULL,                          /* 5 */
      gxv_LookupTable_fmt6_validate, /* 6 */
      NULL,                          /* 7 */
      gxv_LookupTable_fmt8_validate, /* 8 */
    };

    GXV_Validate_Func  func;


    GXV_NAME_ENTER( "LookupTable" );

    /* lookuptbl_head may be used in fmt4 transit function. */
    valid->lookuptbl_head = table;

    /* format */
    GXV_LIMIT_CHECK( 2 );
    format = FT_NEXT_USHORT( p );
    GXV_TRACE(( " (format %d)\n", format ));

    if ( format > 8 )
      FT_INVALID_FORMAT;

    func = fmt_funcs_table[format];
    if ( func == NULL )
      FT_INVALID_FORMAT;

    func( p, limit, valid );
    p += valid->subtable_length;

    valid->subtable_length = p - table;

    GXV_EXIT;
  }


  /*************************************************************************/
  /*************************************************************************/
  /*****                                                               *****/
  /*****                          Glyph ID                             *****/
  /*****                                                               *****/
  /*************************************************************************/
  /*************************************************************************/

  FT_LOCAL_DEF( FT_Int )
  gxv_glyphid_validate( FT_UShort      gid,
                        GXV_Validator  valid )
  {
    FT_Face  face;


    if ( gid == 0xFFFFU )
    {
      GXV_EXIT;
      return 1;
    }

    face = valid->face;
    if ( face->num_glyphs < gid )
    {
      GXV_TRACE(( " gxv_glyphid_check() gid overflow: num_glyphs %d < %d\n",
                  face->num_glyphs, gid ));
      if ( valid->root->level >= FT_VALIDATE_PARANOID )
        FT_INVALID_GLYPH_ID;
    }

    return 0;
  }


  /*************************************************************************/
  /*************************************************************************/
  /*****                                                               *****/
  /*****                        CONTROL POINT                          *****/
  /*****                                                               *****/
  /*************************************************************************/
  /*************************************************************************/

  FT_LOCAL_DEF( void )
  gxv_ctlPoint_validate( FT_UShort      gid,
                         FT_Short       ctl_point,
                         GXV_Validator  valid )
  {
    FT_Face       face;
    FT_Error      error;

    FT_GlyphSlot  glyph;
    FT_Outline    outline;
    short         n_points;


    face = valid->face;

    error = FT_Load_Glyph( face,
                           gid,
                           FT_LOAD_NO_BITMAP | FT_LOAD_IGNORE_TRANSFORM );
    if ( error )
      FT_INVALID_GLYPH_ID;

    glyph    = face->glyph;
    outline  = glyph->outline;
    n_points = outline.n_points;


    if ( !( ctl_point < n_points ) )
      FT_INVALID_DATA;
  }

⌨️ 快捷键说明

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