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

📄 ftxopen.c

📁 神龙卡开发原代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/******************************************************************* * *  ftxopen.c * *    TrueType Open common table support. * *  Copyright 1996-1999 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 "tttypes.h"#include "ttload.h"#include "ttextend.h"#include "ttmemory.h"#include "ttfile.h"#include "ftxopen.h"#include "ftxopenf.h"  /***************************   * Script related functions   ***************************/  /* LangSys */  static TT_Error  Load_LangSys( TTO_LangSys*  ls,                                 PFace         input )  {    DEFINE_LOAD_LOCALS( input->stream );    UShort   n, count;    UShort*  fi;    if ( ACCESS_Frame( 6L ) )      return error;    ls->LookupOrderOffset    = GET_UShort();    /* should be 0 */    ls->ReqFeatureIndex      = GET_UShort();    count = ls->FeatureCount = GET_UShort();    FORGET_Frame();    ls->FeatureIndex = NULL;    if ( ALLOC_ARRAY( ls->FeatureIndex, count, UShort ) )      return error;    if ( ACCESS_Frame( count * 2L ) )    {      FREE( ls->FeatureIndex );      return error;    }    fi = ls->FeatureIndex;    for ( n = 0; n < count; n++ )      fi[n] = GET_UShort();    FORGET_Frame();    return TT_Err_Ok;  }  static void  Free_LangSys( TTO_LangSys*  ls )  {    FREE( ls->FeatureIndex );  }  /* Script */  static TT_Error  Load_Script( TTO_Script*  s,                                PFace        input )  {    DEFINE_LOAD_LOCALS( input->stream );    UShort              n, count;    ULong               cur_offset, new_offset, base_offset;    TTO_LangSysRecord*  lsr;    base_offset = FILE_Pos();    if ( ACCESS_Frame( 2L ) )      return error;    new_offset = GET_UShort() + base_offset;    FORGET_Frame();    if ( new_offset != base_offset )        /* not a NULL offset */    {      cur_offset = FILE_Pos();      if ( FILE_Seek( new_offset ) ||           ( error = Load_LangSys( &s->DefaultLangSys,                                   input ) ) != TT_Err_Ok )        return error;      (void)FILE_Seek( cur_offset );    }    else    {      /* we create a DefaultLangSys table with no entries */      s->DefaultLangSys.LookupOrderOffset = 0;      s->DefaultLangSys.ReqFeatureIndex   = 0xFFFF;      s->DefaultLangSys.FeatureCount      = 0;      s->DefaultLangSys.FeatureIndex      = NULL;    }    if ( ACCESS_Frame( 2L ) )      goto Fail2;    count = s->LangSysCount = GET_UShort();    /* safety check; otherwise the official handling of TrueType Open       fonts won't work */    if ( s->LangSysCount == 0 && s->DefaultLangSys.FeatureCount == 0 )    {      error = TTO_Err_Invalid_SubTable;      goto Fail2;    }    FORGET_Frame();    s->LangSysRecord = NULL;    if ( ALLOC_ARRAY( s->LangSysRecord, count, TTO_LangSysRecord ) )      goto Fail2;    lsr = s->LangSysRecord;    for ( n = 0; n < count; n++ )    {      if ( ACCESS_Frame( 6L ) )        goto Fail1;      lsr[n].LangSysTag = GET_ULong();      new_offset = GET_UShort() + base_offset;      FORGET_Frame();      cur_offset = FILE_Pos();      if ( FILE_Seek( new_offset ) ||           ( error = Load_LangSys( &lsr[n].LangSys, input ) ) != TT_Err_Ok )        goto Fail1;      (void)FILE_Seek( cur_offset );    }    return TT_Err_Ok;  Fail1:    for ( n = 0; n < count; n++ )      Free_LangSys( &lsr[n].LangSys );    FREE( s->LangSysRecord );  Fail2:    Free_LangSys( &s->DefaultLangSys );    return error;  }  static void  Free_Script( TTO_Script*  s )  {    UShort              n, count;    TTO_LangSysRecord*  lsr;    Free_LangSys( &s->DefaultLangSys );    if ( s->LangSysRecord )    {      count = s->LangSysCount;      lsr   = s->LangSysRecord;      for ( n = 0; n < count; n++ )        Free_LangSys( &lsr[n].LangSys );      FREE( lsr );    }  }  /* ScriptList */  TT_Error  Load_ScriptList( TTO_ScriptList*  sl,                             PFace            input )  {    DEFINE_LOAD_LOCALS( input->stream );    UShort             n, count;    ULong              cur_offset, new_offset, base_offset;    TTO_ScriptRecord*  sr;    base_offset = FILE_Pos();    if ( ACCESS_Frame( 2L ) )      return error;    count = sl->ScriptCount = GET_UShort();    FORGET_Frame();    sl->ScriptRecord = NULL;    if ( ALLOC_ARRAY( sl->ScriptRecord, count, TTO_ScriptRecord ) )      return error;    sr = sl->ScriptRecord;    for ( n = 0; n < count; n++ )    {      if ( ACCESS_Frame( 6L ) )        goto Fail;      sr[n].ScriptTag = GET_ULong();      new_offset = GET_UShort() + base_offset;      FORGET_Frame();      cur_offset = FILE_Pos();      if ( FILE_Seek( new_offset ) ||           ( error = Load_Script( &sr[n].Script, input ) ) != TT_Err_Ok )        goto Fail;      (void)FILE_Seek( cur_offset );    }    return TT_Err_Ok;  Fail:    for ( n = 0; n < count; n++ )      Free_Script( &sr[n].Script );    FREE( sl->ScriptRecord );    return error;  }  void  Free_ScriptList( TTO_ScriptList*  sl )  {    UShort             n, count;    TTO_ScriptRecord*  sr;    if ( sl->ScriptRecord )    {      count = sl->ScriptCount;      sr    = sl->ScriptRecord;      for ( n = 0; n < count; n++ )        Free_Script( &sr[n].Script );      FREE( sr );    }  }  /*********************************   * Feature List related functions   *********************************/  /* Feature */  static TT_Error  Load_Feature( TTO_Feature*  f,                                 PFace         input )  {    DEFINE_LOAD_LOCALS( input->stream );    UShort   n, count;    UShort*  lli;    if ( ACCESS_Frame( 4L ) )      return error;    f->FeatureParams           = GET_UShort();    /* should be 0 */    count = f->LookupListCount = GET_UShort();    FORGET_Frame();    f->LookupListIndex = NULL;    if ( ALLOC_ARRAY( f->LookupListIndex, count, UShort ) )      return error;    lli = f->LookupListIndex;    if ( ACCESS_Frame( count * 2L ) )    {      FREE( f->LookupListIndex );      return error;    }    for ( n = 0; n < count; n++ )      lli[n] = GET_UShort();    FORGET_Frame();    return TT_Err_Ok;  }  static void  Free_Feature( TTO_Feature*  f )  {    FREE( f->LookupListIndex );  }  /* FeatureList */  TT_Error  Load_FeatureList( TTO_FeatureList*  fl,                              PFace             input )  {    DEFINE_LOAD_LOCALS( input->stream );    UShort              n, count;    ULong               cur_offset, new_offset, base_offset;    TTO_FeatureRecord*  fr;    base_offset = FILE_Pos();    if ( ACCESS_Frame( 2L ) )      return error;    count = fl->FeatureCount = GET_UShort();    FORGET_Frame();    fl->FeatureRecord = NULL;    if ( ALLOC_ARRAY( fl->FeatureRecord, count, TTO_FeatureRecord ) )      return error;    fr = fl->FeatureRecord;    for ( n = 0; n < count; n++ )    {      if ( ACCESS_Frame( 6L ) )        goto Fail;      fr[n].FeatureTag = GET_ULong();      new_offset = GET_UShort() + base_offset;      FORGET_Frame();      cur_offset = FILE_Pos();      if ( FILE_Seek( new_offset ) ||           ( error = Load_Feature( &fr[n].Feature, input ) ) != TT_Err_Ok )        goto Fail;      (void)FILE_Seek( cur_offset );    }    return TT_Err_Ok;  Fail:    for ( n = 0; n < count; n++ )      Free_Feature( &fr[n].Feature );    FREE( fl->FeatureRecord );    return error;  }  void  Free_FeatureList( TTO_FeatureList*  fl )  {    UShort              n, count;    TTO_FeatureRecord*  fr;    if ( fl->FeatureRecord )    {      count = fl->FeatureCount;      fr    = fl->FeatureRecord;      for ( n = 0; n < count; n++ )        Free_Feature( &fr[n].Feature );      FREE( fr );    }  }  /********************************   * Lookup List related functions   ********************************/  /* the subroutines of the following two functions are defined in     ftxgsub.c and ftxgpos.c respectively                          */  /* SubTable */  static TT_Error  Load_SubTable( TTO_SubTable*  st,                                  PFace          input,                                  TTO_Type       table_type,                                  UShort         lookup_type )  {    if ( table_type == GSUB )      switch ( lookup_type )      {      case GSUB_LOOKUP_SINGLE:        return Load_SingleSubst( &st->st.gsub.single, input );      case GSUB_LOOKUP_MULTIPLE:        return Load_MultipleSubst( &st->st.gsub.multiple, input );      case GSUB_LOOKUP_ALTERNATE:        return Load_AlternateSubst( &st->st.gsub.alternate, input );      case GSUB_LOOKUP_LIGATURE:        return Load_LigatureSubst( &st->st.gsub.ligature, input );      case GSUB_LOOKUP_CONTEXT:        return Load_ContextSubst( &st->st.gsub.context, input );      case GSUB_LOOKUP_CHAIN:        return Load_ChainContextSubst( &st->st.gsub.chain, input );      default:        return TTO_Err_Invalid_GSUB_SubTable_Format;      }    else      switch ( lookup_type )      {        case GPOS_LOOKUP_SINGLE:          return Load_SinglePos( &st->st.gpos.single, input );        case GPOS_LOOKUP_PAIR:          return Load_PairPos( &st->st.gpos.pair, input );        case GPOS_LOOKUP_CURSIVE:          return Load_CursivePos( &st->st.gpos.cursive, input );        case GPOS_LOOKUP_MARKBASE:          return Load_MarkBasePos( &st->st.gpos.markbase, input );        case GPOS_LOOKUP_MARKLIG:          return Load_MarkLigPos( &st->st.gpos.marklig, input );        case GPOS_LOOKUP_MARKMARK:          return Load_MarkMarkPos( &st->st.gpos.markmark, input );        case GPOS_LOOKUP_CONTEXT:          return Load_ContextPos( &st->st.gpos.context, input );        case GPOS_LOOKUP_CHAIN:          return Load_ChainContextPos ( &st->st.gpos.chain, input );        default:          return TTO_Err_Invalid_GPOS_SubTable_Format;      }    return TT_Err_Ok;           /* never reached */  }  static void  Free_SubTable( TTO_SubTable*  st,                              TTO_Type       table_type,                              UShort         lookup_type )  {    if ( table_type == GSUB )      switch ( lookup_type )      {      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;    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;    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 ( 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   *****************************/

⌨️ 快捷键说明

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