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

📄 ftxkern.c

📁 字体缩放显示
💻 C
📖 第 1 页 / 共 2 页
字号:
  Fail_Right:    FREE( kern2->rightClass.classes );    kern2->rightClass.nGlyphs = 0;  Fail_Left:    FREE( kern2->leftClass.classes );    kern2->leftClass.nGlyphs = 0;    return error;  }/******************************************************************* * *  Function    :  Kerning_Create * *  Description :  Creates the kerning directory if a face is *                 loaded.  The tables however are loaded on *                 demand to save space. * *  Input  :  face    pointer to the parent face object *            kern    pointer to the extension's kerning field * *  Output :  error code * *  Notes  :  as in all constructors, the memory allocated isn't *            released in case of failure.  Rather, the task is left *            to the destructor (which is called if an error *            occurs during the loading of a face). * ******************************************************************/  static TT_Error  Kerning_Create( void*  ext,                  PFace  face )  {    DEFINE_LOAD_LOCALS( face->stream );    TT_Kerning*  kern = (TT_Kerning*)ext;    UShort       num_tables;    Long         table;    TT_Kern_Subtable*  sub;    /* by convention */    if ( !kern )      return TT_Err_Ok;    /* Now load the kerning directory. We're called from the face */    /* constructor.  We thus need not use the stream.             */    kern->version = 0;    kern->nTables = 0;    kern->tables  = NULL;    table = TT_LookUp_Table( face, TTAG_kern );    if ( table < 0 )      return TT_Err_Ok;  /* The table is optional */    if ( FILE_Seek( face->dirTables[table].Offset ) ||         ACCESS_Frame( 4L ) )      return error;    kern->version = GET_UShort();    num_tables    = GET_UShort();    FORGET_Frame();    /* we don't set kern->nTables until we have allocated the array */    if ( ALLOC_ARRAY( kern->tables, num_tables, TT_Kern_Subtable ) )      return error;    kern->nTables = num_tables;    /* now load the directory entries, but do _not_ load the tables ! */    sub = kern->tables;    for ( table = 0; table < num_tables; table++ )    {      if ( ACCESS_Frame( 6L ) )        return error;      sub->loaded   = FALSE;             /* redundant, but good to see */      sub->version  = GET_UShort();      sub->length   = GET_UShort() - 6;  /* substract header length */      sub->format   = GET_Byte();      sub->coverage = GET_Byte();      FORGET_Frame();      sub->offset = FILE_Pos();      /* now skip to the next table */      if ( FILE_Skip( sub->length ) )        return error;      sub++;    }    /* that's fine, leave now */    return TT_Err_Ok;  }/******************************************************************* * *  Function    :  Kerning_Destroy * *  Description :  Destroys all kerning information. * *  Input  :  kern   pointer to the extension's kerning field * *  Output :  error code * *  Notes  :  This function is a destructor; it must be able *            to destroy partially built tables. * ******************************************************************/  static TT_Error  Kerning_Destroy( void*  ext,                   PFace  face )  {    TT_Kerning*        kern = (TT_Kerning*)ext;    TT_Kern_Subtable*  sub;    UShort             n;    /* by convention */    if ( !kern )      return TT_Err_Ok;    if ( kern->nTables == 0 )      return TT_Err_Ok;      /* no tables to release */    /* scan the table directory and release loaded entries */    sub = kern->tables;    for ( n = 0; n < kern->nTables; n++ )    {      if ( sub->loaded )      {        switch ( sub->format )        {        case 0:          FREE( sub->t.kern0.pairs );          sub->t.kern0.nPairs        = 0;          sub->t.kern0.searchRange   = 0;          sub->t.kern0.entrySelector = 0;          sub->t.kern0.rangeShift    = 0;          break;        case 2:          FREE( sub->t.kern2.leftClass.classes );          sub->t.kern2.leftClass.firstGlyph = 0;          sub->t.kern2.leftClass.nGlyphs    = 0;          FREE( sub->t.kern2.rightClass.classes );          sub->t.kern2.rightClass.firstGlyph = 0;          sub->t.kern2.rightClass.nGlyphs    = 0;          FREE( sub->t.kern2.array );          sub->t.kern2.rowWidth = 0;          break;        default:          ;       /* invalid subtable format - do nothing */        }        sub->loaded   = FALSE;        sub->version  = 0;        sub->offset   = 0;        sub->length   = 0;        sub->coverage = 0;        sub->format   = 0;      }      sub++;    }    FREE( kern->tables );    kern->nTables = 0;    return TT_Err_Ok;  }/******************************************************************* * *  Function    :  TT_Get_Kerning_Directory * *  Description :  Returns a given face's kerning directory. * *  Input  :  face       handle to the face object *            directory  pointer to client's target directory * *  Output :  error code * *  Notes  :  The kerning table directory is loaded with the face *            through the extension constructor.  However, the kerning *            tables themselves are only loaded on demand, as they *            may represent a lot of data, unneeded by most uses of *            the engine. * ******************************************************************/  FT_EXPORT_FUNC( TT_Error )  TT_Get_Kerning_Directory( TT_Face      face,                            TT_Kerning*  directory )  {    PFace        faze = HANDLE_Face( face );    TT_Error     error;    TT_Kerning*  kerning;    if ( !faze )      return TT_Err_Invalid_Face_Handle;    /* copy directory header */    error = TT_Extension_Get( faze, KERNING_ID, (void**)&kerning );    if ( !error )      *directory = *kerning;    return error;  }/******************************************************************* * *  Function    :  TT_Load_Kerning_Table * *  Description :  Loads a kerning table intro memory. * *  Input  :  face          face handle *            kern_index    index in the face's kerning directory * *  Output :  error code * *  Notes  : * ******************************************************************/  FT_EXPORT_FUNC( TT_Error )  TT_Load_Kerning_Table( TT_Face    face,                         TT_UShort  kern_index )  {    TT_Error   error;    TT_Stream  stream;    TT_Kerning*        kern;    TT_Kern_Subtable*  sub;    PFace  faze = HANDLE_Face( face );    if ( !faze )      return TT_Err_Invalid_Face_Handle;    error = TT_Extension_Get( faze, KERNING_ID, (void**)&kern );    if ( error )      return error;    if ( kern->nTables == 0 )      return TT_Err_Table_Missing;    if ( kern_index >= kern->nTables )      return TT_Err_Invalid_Argument;    sub = kern->tables + kern_index;    if ( sub->format != 0 && sub->format != 2 )      return TT_Err_Invalid_Kerning_Table_Format;    /* now access stream */    if ( USE_Stream( faze->stream, stream ) )      return error;    if ( FILE_Seek( sub->offset ) )      goto Fail;    if ( sub->format == 0 )      error = Subtable_Load_0( &sub->t.kern0, faze );    else if ( sub->format == 2 )      error = Subtable_Load_2( &sub->t.kern2, faze );    if ( !error )      sub->loaded = TRUE;  Fail:    /* release stream */    DONE_Stream( stream );    return error;  }  FT_EXPORT_FUNC( TT_Error )  TT_Init_Kerning_Extension( TT_Engine  engine )  {    PEngine_Instance  _engine = HANDLE_Engine( engine );    TT_Error  error;    if ( !_engine )      return TT_Err_Invalid_Engine;    error = TT_Register_Extension( _engine,                                KERNING_ID,                                sizeof ( TT_Kerning ),                                Kerning_Create,                                Kerning_Destroy );    return error;  }/* END */

⌨️ 快捷键说明

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