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

📄 otvgpos.c

📁 奇趣公司比较新的qt/emd版本
💻 C
📖 第 1 页 / 共 2 页
字号:
/***************************************************************************//*                                                                         *//*  otvgpos.c                                                              *//*                                                                         *//*    OpenType GPOS table validation (body).                               *//*                                                                         *//*  Copyright 2002, 2004, 2005, 2006 by                                    *//*  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.                                        *//*                                                                         *//***************************************************************************/#include "otvalid.h"#include "otvcommn.h"#include "otvgpos.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_otvgpos  static void  otv_Anchor_validate( FT_Bytes       table,                       OTV_Validator  valid );  static void  otv_MarkArray_validate( FT_Bytes       table,                          OTV_Validator  valid );  /*************************************************************************/  /*************************************************************************/  /*****                                                               *****/  /*****                      UTILITY FUNCTIONS                        *****/  /*****                                                               *****/  /*************************************************************************/  /*************************************************************************/#define BaseArrayFunc       otv_x_sxy#define LigatureAttachFunc  otv_x_sxy#define Mark2ArrayFunc      otv_x_sxy  /* uses valid->extra1 (counter)                             */  /* uses valid->extra2 (boolean to handle NULL anchor field) */  static void  otv_x_sxy( FT_Bytes       table,             OTV_Validator  valid )  {    FT_Bytes  p = table;    FT_UInt   Count, count1, table_size;    OTV_ENTER;    OTV_LIMIT_CHECK( 2 );    Count = FT_NEXT_USHORT( p );    OTV_TRACE(( " (Count = %d)\n", Count ));    OTV_LIMIT_CHECK( Count * valid->extra1 * 2 );    table_size = Count * valid->extra1 * 2 + 2;    for ( ; Count > 0; Count-- )      for ( count1 = valid->extra1; count1 > 0; count1-- )      {        OTV_OPTIONAL_TABLE( anchor_offset );        OTV_OPTIONAL_OFFSET( anchor_offset );        if ( valid->extra2 )        {          OTV_SIZE_CHECK( anchor_offset );          if ( anchor_offset )            otv_Anchor_validate( table + anchor_offset, valid );        }        else          otv_Anchor_validate( table + anchor_offset, valid );      }    OTV_EXIT;  }#define MarkBasePosFormat1Func  otv_u_O_O_u_O_O#define MarkLigPosFormat1Func   otv_u_O_O_u_O_O#define MarkMarkPosFormat1Func  otv_u_O_O_u_O_O  /* sets valid->extra1 (class count) */  static void  otv_u_O_O_u_O_O( FT_Bytes       table,                   OTV_Validator  valid )  {    FT_Bytes           p = table;    FT_UInt            Coverage1, Coverage2, ClassCount;    FT_UInt            Array1, Array2;    OTV_Validate_Func  func;    OTV_ENTER;    p += 2;     /* skip PosFormat */    OTV_LIMIT_CHECK( 10 );    Coverage1  = FT_NEXT_USHORT( p );    Coverage2  = FT_NEXT_USHORT( p );    ClassCount = FT_NEXT_USHORT( p );    Array1     = FT_NEXT_USHORT( p );    Array2     = FT_NEXT_USHORT( p );    otv_Coverage_validate( table + Coverage1, valid );    otv_Coverage_validate( table + Coverage2, valid );    otv_MarkArray_validate( table + Array1, valid );    valid->nesting_level++;    func          = valid->func[valid->nesting_level];    valid->extra1 = ClassCount;    func( table + Array2, valid );    valid->nesting_level--;    OTV_EXIT;  }  /*************************************************************************/  /*************************************************************************/  /*****                                                               *****/  /*****                        VALUE RECORDS                          *****/  /*****                                                               *****/  /*************************************************************************/  /*************************************************************************/  static FT_UInt  otv_value_length( FT_UInt  format )  {    FT_UInt  count;    count = ( ( format & 0xAA ) >> 1 ) + ( format & 0x55 );    count = ( ( count  & 0xCC ) >> 2 ) + ( count  & 0x33 );    count = ( ( count  & 0xF0 ) >> 4 ) + ( count  & 0x0F );    return count * 2;  }  /* uses valid->extra3 (pointer to base table) */  static void  otv_ValueRecord_validate( FT_Bytes       table,                            FT_UInt        format,                            OTV_Validator  valid )  {    FT_Bytes  p = table;    FT_UInt   count;#ifdef FT_DEBUG_LEVEL_TRACE    FT_Int    loop;    FT_ULong  res = 0;    OTV_NAME_ENTER( "ValueRecord" );    /* display `format' in dual representation */    for ( loop = 7; loop >= 0; loop-- )    {      res <<= 4;      res  += ( format >> loop ) & 1;    }    OTV_TRACE(( " (format 0b%08lx)\n", res ));#endif    if ( format >= 0x100 )      FT_INVALID_DATA;    for ( count = 4; count > 0; count-- )    {      if ( format & 1 )      {        /* XPlacement, YPlacement, XAdvance, YAdvance */        OTV_LIMIT_CHECK( 2 );        p += 2;      }      format >>= 1;    }    for ( count = 4; count > 0; count-- )    {      if ( format & 1 )      {        FT_UInt   table_size;        OTV_OPTIONAL_TABLE( device );        /* XPlaDevice, YPlaDevice, XAdvDevice, YAdvDevice */        OTV_LIMIT_CHECK( 2 );        OTV_OPTIONAL_OFFSET( device );        /* XXX: this value is usually too small, especially if the current */        /* ValueRecord is part of an array -- getting the correct table    */        /* size is probably not worth the trouble                          */        table_size = p - valid->extra3;        OTV_SIZE_CHECK( device );        if ( device )          otv_Device_validate( valid->extra3 + device, valid );      }      format >>= 1;    }    OTV_EXIT;  }  /*************************************************************************/  /*************************************************************************/  /*****                                                               *****/  /*****                           ANCHORS                             *****/  /*****                                                               *****/  /*************************************************************************/  /*************************************************************************/  static void  otv_Anchor_validate( FT_Bytes       table,                       OTV_Validator  valid )  {    FT_Bytes  p = table;    FT_UInt   AnchorFormat;    OTV_NAME_ENTER( "Anchor");    OTV_LIMIT_CHECK( 6 );    AnchorFormat = FT_NEXT_USHORT( p );    OTV_TRACE(( " (format %d)\n", AnchorFormat ));    p += 4;     /* skip XCoordinate and YCoordinate */    switch ( AnchorFormat )    {    case 1:      break;    case 2:      OTV_LIMIT_CHECK( 2 );  /* AnchorPoint */      break;    case 3:      {        FT_UInt   table_size;        OTV_OPTIONAL_TABLE( XDeviceTable );        OTV_OPTIONAL_TABLE( YDeviceTable );        OTV_LIMIT_CHECK( 4 );        OTV_OPTIONAL_OFFSET( XDeviceTable );        OTV_OPTIONAL_OFFSET( YDeviceTable );        table_size = 6 + 4;        OTV_SIZE_CHECK( XDeviceTable );        if ( XDeviceTable )          otv_Device_validate( table + XDeviceTable, valid );        OTV_SIZE_CHECK( YDeviceTable );        if ( YDeviceTable )          otv_Device_validate( table + YDeviceTable, valid );      }      break;    default:      FT_INVALID_DATA;    }    OTV_EXIT;  }  /*************************************************************************/  /*************************************************************************/  /*****                                                               *****/  /*****                         MARK ARRAYS                           *****/  /*****                                                               *****/  /*************************************************************************/  /*************************************************************************/  static void  otv_MarkArray_validate( FT_Bytes       table,                          OTV_Validator  valid )  {    FT_Bytes  p = table;    FT_UInt   MarkCount;    OTV_NAME_ENTER( "MarkArray" );    OTV_LIMIT_CHECK( 2 );    MarkCount = FT_NEXT_USHORT( p );    OTV_TRACE(( " (MarkCount = %d)\n", MarkCount ));    OTV_LIMIT_CHECK( MarkCount * 4 );    /* MarkRecord */    for ( ; MarkCount > 0; MarkCount-- )    {      p += 2;   /* skip Class */      /* MarkAnchor */      otv_Anchor_validate( table + FT_NEXT_USHORT( p ), valid );    }    OTV_EXIT;  }  /*************************************************************************/  /*************************************************************************/  /*****                                                               *****/  /*****                     GPOS LOOKUP TYPE 1                        *****/  /*****                                                               *****/  /*************************************************************************/  /*************************************************************************/  /* sets valid->extra3 (pointer to base table) */  static void  otv_SinglePos_validate( FT_Bytes       table,                          OTV_Validator  valid )  {    FT_Bytes  p = table;    FT_UInt   PosFormat;    OTV_NAME_ENTER( "SinglePos" );    OTV_LIMIT_CHECK( 2 );    PosFormat = FT_NEXT_USHORT( p );    OTV_TRACE(( " (format %d)\n", PosFormat ));    valid->extra3 = table;    switch ( PosFormat )    {    case 1:     /* SinglePosFormat1 */      {        FT_UInt  Coverage, ValueFormat;        OTV_LIMIT_CHECK( 4 );        Coverage    = FT_NEXT_USHORT( p );        ValueFormat = FT_NEXT_USHORT( p );        otv_Coverage_validate( table + Coverage, valid );        otv_ValueRecord_validate( p, ValueFormat, valid ); /* Value */      }      break;    case 2:     /* SinglePosFormat2 */      {        FT_UInt  Coverage, ValueFormat, ValueCount, len_value;        OTV_LIMIT_CHECK( 6 );        Coverage    = FT_NEXT_USHORT( p );        ValueFormat = FT_NEXT_USHORT( p );        ValueCount  = FT_NEXT_USHORT( p );        OTV_TRACE(( " (ValueCount = %d)\n", ValueCount ));        len_value = otv_value_length( ValueFormat );        otv_Coverage_validate( table + Coverage, valid );        OTV_LIMIT_CHECK( ValueCount * len_value );        /* Value */        for ( ; ValueCount > 0; ValueCount-- )        {          otv_ValueRecord_validate( p, ValueFormat, valid );          p += len_value;        }      }      break;    default:      FT_INVALID_DATA;    }    OTV_EXIT;  }  /*************************************************************************/  /*************************************************************************/  /*****                                                               *****/  /*****                     GPOS LOOKUP TYPE 2                        *****/  /*****                                                               *****/  /*************************************************************************/  /*************************************************************************/  static void  otv_PairSet_validate( FT_Bytes       table,                        FT_UInt        format1,                        FT_UInt        format2,                        OTV_Validator  valid )  {    FT_Bytes  p = table;    FT_UInt   value_len1, value_len2, PairValueCount;    OTV_NAME_ENTER( "PairSet" );    OTV_LIMIT_CHECK( 2 );    PairValueCount = FT_NEXT_USHORT( p );    OTV_TRACE(( " (PairValueCount = %d)\n", PairValueCount ));    value_len1 = otv_value_length( format1 );    value_len2 = otv_value_length( format2 );    OTV_LIMIT_CHECK( PairValueCount * ( value_len1 + value_len2 + 2 ) );    /* PairValueRecord */    for ( ; PairValueCount > 0; PairValueCount-- )    {      p += 2;       /* skip SecondGlyph */      if ( format1 )        otv_ValueRecord_validate( p, format1, valid ); /* Value1 */      p += value_len1;      if ( format2 )        otv_ValueRecord_validate( p, format2, valid ); /* Value2 */      p += value_len2;    }    OTV_EXIT;  }  /* sets valid->extra3 (pointer to base table) */  static void  otv_PairPos_validate( FT_Bytes       table,                        OTV_Validator  valid )  {    FT_Bytes  p = table;    FT_UInt   PosFormat;    OTV_NAME_ENTER( "PairPos" );    OTV_LIMIT_CHECK( 2 );    PosFormat = FT_NEXT_USHORT( p );    OTV_TRACE(( " (format %d)\n", PosFormat ));    valid->extra3 = table;    switch ( PosFormat )    {    case 1:     /* PairPosFormat1 */      {        FT_UInt  Coverage, ValueFormat1, ValueFormat2, PairSetCount;        OTV_LIMIT_CHECK( 8 );        Coverage     = FT_NEXT_USHORT( p );        ValueFormat1 = FT_NEXT_USHORT( p );        ValueFormat2 = FT_NEXT_USHORT( p );        PairSetCount = FT_NEXT_USHORT( p );        OTV_TRACE(( " (PairSetCount = %d)\n", PairSetCount ));        otv_Coverage_validate( table + Coverage, valid );        OTV_LIMIT_CHECK( PairSetCount * 2 );        /* PairSetOffset */        for ( ; PairSetCount > 0; PairSetCount-- )          otv_PairSet_validate( table + FT_NEXT_USHORT( p ),

⌨️ 快捷键说明

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