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

📄 ftxopen.c

📁 字体缩放显示
💻 C
📖 第 1 页 / 共 3 页
字号:
      {      case GSUB_LOOKUP_SINGLE:        Free_SingleSubst( &st->st.gsub.single );        break;      case GSUB_LOOKUP_MULTIPLE:        Free_MultipleSubst( &st->st.gsub.multiple );        break;      case GSUB_LOOKUP_ALTERNATE:        Free_AlternateSubst( &st->st.gsub.alternate );        break;      case GSUB_LOOKUP_LIGATURE:        Free_LigatureSubst( &st->st.gsub.ligature );        break;      case GSUB_LOOKUP_CONTEXT:        Free_ContextSubst( &st->st.gsub.context );        break;      case GSUB_LOOKUP_CHAIN:        Free_ChainContextSubst( &st->st.gsub.chain );        break;      }    else      switch ( lookup_type )      {      case GPOS_LOOKUP_SINGLE:        Free_SinglePos( &st->st.gpos.single );        break;      case GPOS_LOOKUP_PAIR:        Free_PairPos( &st->st.gpos.pair );        break;      case GPOS_LOOKUP_CURSIVE:        Free_CursivePos( &st->st.gpos.cursive );        break;      case GPOS_LOOKUP_MARKBASE:        Free_MarkBasePos( &st->st.gpos.markbase );        break;      case GPOS_LOOKUP_MARKLIG:        Free_MarkLigPos( &st->st.gpos.marklig );        break;      case GPOS_LOOKUP_MARKMARK:        Free_MarkMarkPos( &st->st.gpos.markmark );        break;      case GPOS_LOOKUP_CONTEXT:        Free_ContextPos( &st->st.gpos.context );        break;      case GPOS_LOOKUP_CHAIN:        Free_ChainContextPos ( &st->st.gpos.chain );        break;      }  }  /* Lookup */  static TT_Error  Load_Lookup( TTO_Lookup*   l,                                PFace         input,                                TTO_Type      type )  {    DEFINE_LOAD_LOCALS( input->stream );    UShort         n, count;    ULong          cur_offset, new_offset, base_offset;    TTO_SubTable*  st;    Bool           is_extension = FALSE;    base_offset = FILE_Pos();    if ( ACCESS_Frame( 6L ) )      return error;    l->LookupType            = GET_UShort();    l->LookupFlag            = GET_UShort();    count = l->SubTableCount = GET_UShort();    FORGET_Frame();    l->SubTable = NULL;    if ( ALLOC_ARRAY( l->SubTable, count, TTO_SubTable ) )      return error;    st = l->SubTable;    if ( ( type == GSUB && l->LookupType == GSUB_LOOKUP_EXTENSION ) ||         ( type == GPOS && l->LookupType == GPOS_LOOKUP_EXTENSION ) )      is_extension = TRUE;    for ( n = 0; n < count; n++ )    {      if ( ACCESS_Frame( 2L ) )        goto Fail;      new_offset = GET_UShort() + base_offset;      FORGET_Frame();      cur_offset = FILE_Pos();      if ( is_extension )      {        if ( FILE_Seek( new_offset ) || ACCESS_Frame( 8L ) )          goto Fail;        (void)GET_UShort();                     /* format should be 1 */        l->LookupType = GET_UShort();        new_offset = GET_ULong() + base_offset;        FORGET_Frame();      }      if ( FILE_Seek( new_offset ) ||           ( error = Load_SubTable( &st[n], input,                                    type, l->LookupType ) ) != TT_Err_Ok )        goto Fail;      (void)FILE_Seek( cur_offset );    }    return TT_Err_Ok;  Fail:    for ( n = 0; n < count; n++ )      Free_SubTable( &st[n], type, l->LookupType );    FREE( l->SubTable );    return error;  }  static void  Free_Lookup( TTO_Lookup*   l,                            TTO_Type      type )  {    UShort         n, count;    TTO_SubTable*  st;    if ( l->SubTable )    {      count = l->SubTableCount;      st    = l->SubTable;      for ( n = 0; n < count; n++ )        Free_SubTable( &st[n], type, l->LookupType );      FREE( st );    }  }  /* LookupList */  TT_Error  Load_LookupList( TTO_LookupList*  ll,                             PFace            input,                             TTO_Type         type )  {    DEFINE_LOAD_LOCALS( input->stream );    UShort       n, count;    ULong        cur_offset, new_offset, base_offset;    TTO_Lookup*  l;    base_offset = FILE_Pos();    if ( ACCESS_Frame( 2L ) )      return error;    count = ll->LookupCount = GET_UShort();    FORGET_Frame();    ll->Lookup = NULL;    if ( ALLOC_ARRAY( ll->Lookup, count, TTO_Lookup ) )      return error;    if ( ALLOC_ARRAY( ll->Properties, count, UShort ) )      goto Fail2;    l = ll->Lookup;    for ( n = 0; n < count; n++ )    {      if ( ACCESS_Frame( 2L ) )        goto Fail1;      new_offset = GET_UShort() + base_offset;      FORGET_Frame();      cur_offset = FILE_Pos();      if ( FILE_Seek( new_offset ) ||           ( error = Load_Lookup( &l[n], input, type ) ) != TT_Err_Ok )        goto Fail1;      (void)FILE_Seek( cur_offset );    }    return TT_Err_Ok;  Fail1:    FREE( ll->Properties );    for ( n = 0; n < count; n++ )      Free_Lookup( &l[n], type );  Fail2:    FREE( ll->Lookup );    return error;  }  void  Free_LookupList( TTO_LookupList*  ll,                         TTO_Type         type )  {    UShort       n, count;    TTO_Lookup*  l;    FREE( ll->Properties );    if ( ll->Lookup )    {      count = ll->LookupCount;      l     = ll->Lookup;      for ( n = 0; n < count; n++ )        Free_Lookup( &l[n], type );      FREE( l );    }  }  /*****************************   * Coverage related functions   *****************************/  /* 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;

⌨️ 快捷键说明

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