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

📄 ftxopen.c

📁 神龙卡开发原代码
💻 C
📖 第 1 页 / 共 2 页
字号:
  /* CoverageFormat1 */  static TT_Error  Load_Coverage1( TTO_CoverageFormat1*  cf1,                                   PFace                 input )  {    DEFINE_LOAD_LOCALS( input->stream );    UShort   n, count;    UShort*  ga;    if ( ACCESS_Frame( 2L ) )      return error;    count = cf1->GlyphCount = GET_UShort();    FORGET_Frame();    cf1->GlyphArray = NULL;    if ( ALLOC_ARRAY( cf1->GlyphArray, count, UShort ) )      return error;    ga = cf1->GlyphArray;    if ( ACCESS_Frame( count * 2L ) )    {      FREE( cf1->GlyphArray );      return error;    }    for ( n = 0; n < count; n++ )      ga[n] = GET_UShort();    FORGET_Frame();    return TT_Err_Ok;  }  static void  Free_Coverage1( TTO_CoverageFormat1*  cf1 )  {    FREE( cf1->GlyphArray );  }  /* CoverageFormat2 */  static TT_Error  Load_Coverage2( TTO_CoverageFormat2*  cf2,                                   PFace                 input )  {    DEFINE_LOAD_LOCALS( input->stream );    UShort            n, count;    TTO_RangeRecord*  rr;    if ( ACCESS_Frame( 2L ) )      return error;    count = cf2->RangeCount = GET_UShort();    FORGET_Frame();    cf2->RangeRecord = NULL;    if ( ALLOC_ARRAY( cf2->RangeRecord, count, TTO_RangeRecord ) )      return error;    rr = cf2->RangeRecord;    if ( ACCESS_Frame( count * 6L ) )      goto Fail;    for ( n = 0; n < count; n++ )    {      rr[n].Start              = GET_UShort();      rr[n].End                = GET_UShort();      rr[n].StartCoverageIndex = GET_UShort();      /* sanity check; we are limited to 16bit integers */      if ( rr[n].Start > rr[n].End ||           ( rr[n].End - rr[n].Start + (long)rr[n].StartCoverageIndex ) >=             0x10000L )      {        error = TTO_Err_Invalid_SubTable;        goto Fail;      }    }    FORGET_Frame();    return TT_Err_Ok;  Fail:    FREE( cf2->RangeRecord );    return error;  }  static void  Free_Coverage2( TTO_CoverageFormat2*  cf2 )  {    FREE( cf2->RangeRecord );  }  TT_Error  Load_Coverage( TTO_Coverage*  c,                           PFace          input )  {    DEFINE_LOAD_LOCALS( input->stream );    if ( ACCESS_Frame( 2L ) )      return error;    c->CoverageFormat = GET_UShort();    FORGET_Frame();    switch ( c->CoverageFormat )    {    case 1:      return Load_Coverage1( &c->cf.cf1, input );    case 2:      return Load_Coverage2( &c->cf.cf2, input );    default:      return TTO_Err_Invalid_SubTable_Format;    }    return TT_Err_Ok;               /* never reached */  }  void  Free_Coverage( TTO_Coverage*  c )  {    switch ( c->CoverageFormat )    {    case 1:      Free_Coverage1( &c->cf.cf1 );      break;    case 2:      Free_Coverage2( &c->cf.cf2 );      break;    }  }  static TT_Error  Coverage_Index1( TTO_CoverageFormat1*  cf1,                                    UShort                glyphID,                                    UShort*               index )  {    UShort   min, max, new_min, new_max, middle;    UShort*  array = cf1->GlyphArray;    /* binary search */    new_min = 0;    new_max = cf1->GlyphCount - 1;    do    {      min = new_min;      max = new_max;      /* we use (min + max) / 2 = max - (max - min) / 2  to avoid         overflow and rounding errors                             */      middle = max - ( ( max - min ) >> 1 );      if ( glyphID == array[middle] )      {        *index = middle;        return TT_Err_Ok;      }      else if ( glyphID < array[middle] )      {        if ( middle == min )          break;        new_max = middle - 1;      }      else      {        if ( middle == max )          break;        new_min = middle + 1;      }    } while ( min < max );    return TTO_Err_Not_Covered;  }  static TT_Error  Coverage_Index2( TTO_CoverageFormat2*  cf2,                                    UShort                glyphID,                                    UShort*               index )  {    UShort            min, max, new_min, new_max, middle;    TTO_RangeRecord*  rr = cf2->RangeRecord;    /* binary search */    new_min = 0;    new_max = cf2->RangeCount - 1;    do    {      min = new_min;      max = new_max;      /* we use (min + max) / 2 = max - (max - min) / 2  to avoid         overflow and rounding errors                             */      middle = max - ( ( max - min ) >> 1 );      if ( glyphID >= rr[middle].Start && glyphID <= rr[middle].End )      {        *index = rr[middle].StartCoverageIndex + glyphID - rr[middle].Start;        return TT_Err_Ok;      }      else if ( glyphID < rr[middle].Start )      {        if ( middle == min )          break;        new_max = middle - 1;      }      else      {        if ( middle == max )          break;        new_min = middle + 1;      }    } while ( min < max );    return TTO_Err_Not_Covered;  }  TT_Error  Coverage_Index( TTO_Coverage*  c,                            UShort         glyphID,                            UShort*        index )  {    switch ( c->CoverageFormat )    {    case 1:      return Coverage_Index1( &c->cf.cf1, glyphID, index );    case 2:      return Coverage_Index2( &c->cf.cf2, glyphID, index );    default:      return TTO_Err_Invalid_SubTable_Format;    }    return TT_Err_Ok;               /* never reached */  }  /*************************************   * Class Definition related functions   *************************************/  /* ClassDefFormat1 */  static TT_Error  Load_ClassDef1( TTO_ClassDefinition*  cd,                                   UShort                limit,                                   PFace                 input )  {    DEFINE_LOAD_LOCALS( input->stream );    UShort                n, count;    UShort*               cva;    Bool*                 d;    TTO_ClassDefFormat1*  cdf1;    cdf1 = &cd->cd.cd1;    if ( ACCESS_Frame( 4L ) )      return error;    cdf1->StartGlyph         = GET_UShort();    count = cdf1->GlyphCount = GET_UShort();    FORGET_Frame();    /* sanity check; we are limited to 16bit integers */    if ( cdf1->StartGlyph + (long)count >= 0x10000L )      return TTO_Err_Invalid_SubTable;    cdf1->ClassValueArray = NULL;    if ( ALLOC_ARRAY( cdf1->ClassValueArray, count, UShort ) )      return error;    d   = cd->Defined;    cva = cdf1->ClassValueArray;    if ( ACCESS_Frame( count * 2L ) )      goto Fail;    for ( n = 0; n < count; n++ )    {      cva[n] = GET_UShort();      if ( cva[n] >= limit )      {        error = TTO_Err_Invalid_SubTable;        goto Fail;      }      d[cva[n]] = TRUE;    }    FORGET_Frame();    return TT_Err_Ok;  Fail:    FREE( cva );    return error;  }  static void  Free_ClassDef1( TTO_ClassDefFormat1*  cdf1 )  {    FREE( cdf1->ClassValueArray );  }  /* ClassDefFormat2 */  static TT_Error  Load_ClassDef2 ( TTO_ClassDefinition*  cd,                                    UShort                limit,                                    PFace                 input )  {    DEFINE_LOAD_LOCALS( input->stream );    UShort                 n, count;    TTO_ClassRangeRecord*  crr;    Bool*                  d;    TTO_ClassDefFormat2*   cdf2;    cdf2 = &cd->cd.cd2;    if ( ACCESS_Frame( 2L ) )      return error;    count = cdf2->ClassRangeCount = GET_UShort();    FORGET_Frame();    cdf2->ClassRangeRecord = NULL;    if ( ALLOC_ARRAY( cdf2->ClassRangeRecord, count, TTO_ClassRangeRecord ) )      return error;    d   = cd->Defined;    crr = cdf2->ClassRangeRecord;    if ( ACCESS_Frame( count * 6L ) )      goto Fail;    for ( n = 0; n < count; n++ )    {      crr[n].Start = GET_UShort();      crr[n].End   = GET_UShort();      crr[n].Class = GET_UShort();      /* sanity check */      if ( crr[n].Start > crr[n].End ||           crr[n].Class >= limit )      {        error = TTO_Err_Invalid_SubTable;        goto Fail;      }      d[crr[n].Class] = TRUE;    }    FORGET_Frame();    return TT_Err_Ok;  Fail:    FREE( crr );    return error;  }  static void  Free_ClassDef2( TTO_ClassDefFormat2*  cdf2 )  {    FREE( cdf2->ClassRangeRecord );  }  /* ClassDefinition */  TT_Error  Load_ClassDefinition( TTO_ClassDefinition*  cd,                                  UShort                limit,                                  PFace                 input )  {    DEFINE_LOAD_LOCALS( input->stream );    if ( ALLOC_ARRAY( cd->Defined, limit, Bool ) )      return error;    if ( ACCESS_Frame( 2L ) )      goto Fail;    cd->ClassFormat = GET_UShort();    FORGET_Frame();    switch ( cd->ClassFormat )    {    case 1:      error = Load_ClassDef1( cd, limit, input );      break;    case 2:      error = Load_ClassDef2( cd, limit, input );      break;    default:      error = TTO_Err_Invalid_SubTable_Format;      break;    }    if ( error )      goto Fail;    cd->loaded = TRUE;    return TT_Err_Ok;  Fail:    FREE( cd->Defined );    return error;  }  void  Free_ClassDefinition( TTO_ClassDefinition*  cd )  {    if ( !cd->loaded )      return;    FREE( cd->Defined );    switch ( cd->ClassFormat )    {    case 1:      Free_ClassDef1( &cd->cd.cd1 );      break;    case 2:      Free_ClassDef2( &cd->cd.cd2 );      break;    }  }  static TT_Error  Get_Class1( TTO_ClassDefFormat1*  cdf1,                               UShort                glyphID,                               UShort*               class,                               UShort*               index )  {    UShort*  cva = cdf1->ClassValueArray;    *index = 0;    if ( glyphID >= cdf1->StartGlyph &&         glyphID <= cdf1->StartGlyph + cdf1->GlyphCount )    {      *class = cva[glyphID - cdf1->StartGlyph];      return TT_Err_Ok;    }    else    {      *class = 0;      return TTO_Err_Not_Covered;    }  }  /* we need the index value of the last searched class range record     in case of failure for constructed GDEF tables                  */  static TT_Error  Get_Class2( TTO_ClassDefFormat2*  cdf2,                               UShort                glyphID,                               UShort*               class,                               UShort*               index )  {    TT_Error               error = TT_Err_Ok;    UShort                 min, max, new_min, new_max, middle;    TTO_ClassRangeRecord*  crr = cdf2->ClassRangeRecord;    /* binary search */    new_min = 0;    new_max = cdf2->ClassRangeCount - 1;    do    {      min = new_min;      max = new_max;      /* we use (min + max) / 2 = max - (max - min) / 2  to avoid         overflow and rounding errors                             */      middle = max - ( ( max - min ) >> 1 );      if ( glyphID >= crr[middle].Start && glyphID <= crr[middle].End )      {        *class = crr[middle].Class;        error  = TT_Err_Ok;        break;      }      else if ( glyphID < crr[middle].Start )      {        if ( middle == min )        {          *class = 0;          error  = TTO_Err_Not_Covered;          break;        }        new_max = middle - 1;      }      else      {        if ( middle == max )        {          *class = 0;          error  = TTO_Err_Not_Covered;          break;        }        new_min = middle + 1;      }    } while ( min < max );    if ( index )      *index = middle;    return error;  }  TT_Error  Get_Class( TTO_ClassDefinition*  cd,                       UShort                glyphID,                       UShort*               class,                       UShort*               index )  {    switch ( cd->ClassFormat )    {    case 1:      return Get_Class1( &cd->cd.cd1, glyphID, class, index );    case 2:      return Get_Class2( &cd->cd.cd2, glyphID, class, index );    default:      return TTO_Err_Invalid_SubTable_Format;    }    return TT_Err_Ok;               /* never reached */  }  /***************************   * Device related functions   ***************************/  TT_Error  Load_Device( TTO_Device*  d,                         PFace        input )  {    DEFINE_LOAD_LOCALS( input->stream );    UShort   n, count;    UShort*  dv;    if ( ACCESS_Frame( 6L ) )      return error;    d->StartSize   = GET_UShort();    d->EndSize     = GET_UShort();    d->DeltaFormat = GET_UShort();    FORGET_Frame();    if ( d->StartSize > d->EndSize ||         d->DeltaFormat == 0 || d->DeltaFormat > 3 )      return TTO_Err_Invalid_SubTable;    d->DeltaValue = NULL;    count = ( ( d->EndSize - d->StartSize + 1 ) >>                ( 4 - d->DeltaFormat ) ) + 1;    if ( ALLOC_ARRAY( d->DeltaValue, count, UShort ) )      return error;    if ( ACCESS_Frame( count * 2L ) )    {      FREE( d->DeltaValue );      return error;    }    dv = d->DeltaValue;    for ( n = 0; n < count; n++ )      dv[n] = GET_UShort();    FORGET_Frame();    return TT_Err_Ok;  }  void  Free_Device( TTO_Device*  d )  {    FREE( d->DeltaValue );  }  /* Since we have the delta values stored in compressed form, we must     uncompress it now.  To simplify the interface, the function always     returns a meaningful value in `value'; the error is just for     information.                                 |     format = 1: 0011223344556677|8899101112131415|...                                 |                      byte 1           byte 2       00: (byte >> 14) & mask       11: (byte >> 12) & mask       ...       mask = 0x0003                                 |     format = 2: 0000111122223333|4444555566667777|...                                 |                      byte 1           byte 2       0000: (byte >> 12) & mask       1111: (byte >>  8) & mask       ...       mask = 0x000F                                 |     format = 3: 0000000011111111|2222222233333333|...                                 |                      byte 1           byte 2       00000000: (byte >> 8) & mask       11111111: (byte >> 0) & mask       ....       mask = 0x00FF                                    */  TT_Error  Get_Device( TTO_Device*  d,                        UShort       size,                        Short*       value )  {    UShort  byte, bits, mask, f, s;    f = d->DeltaFormat;    if ( size >= d->StartSize && size <= d->EndSize )    {      s    = size - d->StartSize;      byte = d->DeltaValue[s >> ( 4 - f )];      bits = byte >> ( 16 - ( s % ( 1 << ( 4 - f ) ) + 1 ) * ( 1 << f ) );      mask = 0xFFFF >> ( 16 - ( 1 << f ) );      *value = (Short)( bits & mask );      /* conversion to a signed value */      if ( *value >= ( ( mask + 1 ) >> 1 ) )        *value -= mask + 1;      return TT_Err_Ok;    }    else    {      *value = 0;      return TTO_Err_Not_Covered;    }  }/* END */

⌨️ 快捷键说明

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