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

📄 ftxgdef.c

📁 神龙卡开发原代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/******************************************************************* * *  ftxgdef.c * *    TrueType Open GDEF 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 "tttags.h"#include "ttload.h"#include "ttextend.h"#include "ttmemory.h"#include "ttfile.h"#include "ftxopen.h"#include "ftxopenf.h"#define GDEF_ID  Build_Extension_ID( 'G', 'D', 'E', 'F' )  static TT_Error  Load_AttachList( TTO_AttachList*  al,                                    PFace            input );  static TT_Error  Load_LigCaretList( TTO_LigCaretList*  lcl,                                      PFace              input );  static void  Free_AttachList( TTO_AttachList*  al );  static void  Free_LigCaretList( TTO_LigCaretList*  lcl );  static void  Free_NewGlyphClasses( TTO_GDEFHeader*  gdef );  /**********************   * Extension Functions   **********************/  static TT_Error  GDEF_Create( void*  ext,                                PFace  face )  {    DEFINE_LOAD_LOCALS( face->stream );    TTO_GDEFHeader*  gdef = (TTO_GDEFHeader*)ext;    Long             table;    /* by convention */    if ( !gdef )      return TT_Err_Ok;    /* a null offset indicates that there is no GDEF table */    gdef->offset = 0;    /* we store the start offset and the size of the subtable */    table = TT_LookUp_Table( face, TTAG_GDEF );    if ( table < 0 )      return TT_Err_Ok;             /* The table is optional */    if ( FILE_Seek( face->dirTables[table].Offset ) ||         ACCESS_Frame( 4L ) )      return error;    gdef->offset  = FILE_Pos() - 4L;    /* undo ACCESS_Frame() */    gdef->Version = GET_ULong();    FORGET_Frame();    gdef->loaded = FALSE;    return TT_Err_Ok;  }  static TT_Error  GDEF_Destroy( void*  ext,                                 PFace  face )  {    TTO_GDEFHeader*  gdef = (TTO_GDEFHeader*)ext;    /* by convention */    if ( !gdef )      return TT_Err_Ok;    if ( gdef->loaded )    {      Free_LigCaretList( &gdef->LigCaretList );      Free_AttachList( &gdef->AttachList );      Free_ClassDefinition( &gdef->GlyphClassDef );      Free_ClassDefinition( &gdef->MarkAttachClassDef );      Free_NewGlyphClasses( gdef );    }    return TT_Err_Ok;  }  EXPORT_FUNC  TT_Error  TT_Init_GDEF_Extension( TT_Engine  engine )  {    PEngine_Instance  _engine = HANDLE_Engine( engine );    if ( !_engine )      return TT_Err_Invalid_Engine;    return  TT_Register_Extension( _engine,                                   GDEF_ID,                                   sizeof ( TTO_GDEFHeader ),                                   GDEF_Create,                                   GDEF_Destroy );  }  EXPORT_FUNC  TT_Error  TT_Load_GDEF_Table( TT_Face          face,                                TTO_GDEFHeader*  retptr )  {    ULong            cur_offset, new_offset, base_offset;    TT_Error         error;    TT_Stream        stream;    TTO_GDEFHeader*  gdef;    PFace  faze = HANDLE_Face( face );    if ( !retptr )      return TT_Err_Invalid_Argument;    if ( !faze )      return TT_Err_Invalid_Face_Handle;    error = TT_Extension_Get( faze, GDEF_ID, (void**)&gdef );    if ( error )      return error;    if ( gdef->offset == 0 )      return TT_Err_Table_Missing;      /* no GDEF table; nothing to do */    /* now access stream */    if ( USE_Stream( faze->stream, stream ) )      return error;    base_offset = gdef->offset;    /* skip version */    if ( FILE_Seek( base_offset + 4L ) ||         ACCESS_Frame( 2L ) )      return error;    new_offset = GET_UShort();    FORGET_Frame();    /* all GDEF subtables are optional */    if ( new_offset )    {      new_offset += base_offset;      /* only classes 1-4 are allowed here */      cur_offset = FILE_Pos();      if ( FILE_Seek( new_offset ) ||           ( error = Load_ClassDefinition( &gdef->GlyphClassDef, 5,                                           faze ) ) != TT_Err_Ok )        return error;      (void)FILE_Seek( cur_offset );    }    else      gdef->GlyphClassDef.loaded = FALSE;    if ( ACCESS_Frame( 2L ) )      return error;    new_offset = GET_UShort();    FORGET_Frame();    if ( new_offset )    {      new_offset += base_offset;      cur_offset = FILE_Pos();      if ( FILE_Seek( new_offset ) ||           ( error = Load_AttachList( &gdef->AttachList,                                      faze ) ) != TT_Err_Ok )        goto Fail1;      (void)FILE_Seek( cur_offset );    }    else      gdef->AttachList.loaded = FALSE;    if ( ACCESS_Frame( 2L ) )      return error;    new_offset = GET_UShort();    FORGET_Frame();    if ( new_offset )    {      new_offset += base_offset;      cur_offset = FILE_Pos();      if ( FILE_Seek( new_offset ) ||           ( error = Load_LigCaretList( &gdef->LigCaretList,                                        faze ) ) != TT_Err_Ok )        goto Fail2;      (void)FILE_Seek( cur_offset );    }    else      gdef->LigCaretList.loaded = FALSE;    /* OpenType 1.2 has introduced the `MarkAttachClassDef' field.  We       first have to scan the LookupFlag values to find out whether we       must load it or not.  Here we only store the current file offset. */    gdef->MarkAttachClassDef_offset = FILE_Pos();    gdef->MarkAttachClassDef.loaded = FALSE;    gdef->LastGlyph       = 0;    gdef->NewGlyphClasses = NULL;    gdef->loaded          = TRUE;    *retptr = *gdef;    DONE_Stream( stream );    return TT_Err_Ok;  Fail2:    Free_AttachList( &gdef->AttachList );  Fail1:    Free_ClassDefinition( &gdef->GlyphClassDef );    /* release stream */    DONE_Stream( stream );    return error;  }  /*******************************   * AttachList related functions   *******************************/  /* AttachPoint */  static TT_Error  Load_AttachPoint( TTO_AttachPoint*  ap,                                     PFace             input )  {    DEFINE_LOAD_LOCALS( input->stream );    UShort   n, count;    UShort*  pi;    if ( ACCESS_Frame( 2L ) )      return error;    count = ap->PointCount = GET_UShort();    FORGET_Frame();    ap->PointIndex = NULL;    if ( count )    {      if ( ALLOC_ARRAY( ap->PointIndex, count, UShort ) )        return error;      pi = ap->PointIndex;      if ( ACCESS_Frame( count * 2L ) )      {        FREE( pi );        return error;      }      for ( n = 0; n < count; n++ )        pi[n] = GET_UShort();      FORGET_Frame();    }    return TT_Err_Ok;  }  static void  Free_AttachPoint( TTO_AttachPoint*  ap )  {    FREE( ap->PointIndex );  }  /* AttachList */  static TT_Error  Load_AttachList( TTO_AttachList*  al,                                    PFace            input )  {    DEFINE_LOAD_LOCALS( input->stream );    UShort            n, count;    ULong             cur_offset, new_offset, base_offset;    TTO_AttachPoint*  ap;    base_offset = FILE_Pos();    if ( ACCESS_Frame( 2L ) )      return error;    new_offset = GET_UShort() + base_offset;    FORGET_Frame();    cur_offset = FILE_Pos();    if ( FILE_Seek( new_offset ) ||         ( error = Load_Coverage( &al->Coverage, input ) ) != TT_Err_Ok )      return error;    (void)FILE_Seek( cur_offset );    if ( ACCESS_Frame( 2L ) )      goto Fail2;    count = al->GlyphCount = GET_UShort();    FORGET_Frame();    al->AttachPoint = NULL;    if ( ALLOC_ARRAY( al->AttachPoint, count, TTO_AttachPoint ) )      goto Fail2;    ap = al->AttachPoint;    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_AttachPoint( &ap[n], input ) ) != TT_Err_Ok )        goto Fail1;      (void)FILE_Seek( cur_offset );    }    al->loaded = TRUE;    return TT_Err_Ok;  Fail1:    for ( n = 0; n < count; n++ )      Free_AttachPoint( &ap[n] );    FREE( ap );  Fail2:    Free_Coverage( &al->Coverage );    return error;  }  static void  Free_AttachList( TTO_AttachList*  al )  {    UShort            n, count;    TTO_AttachPoint*  ap;    if ( !al->loaded )      return;    if ( al->AttachPoint )    {      count = al->GlyphCount;      ap    = al->AttachPoint;      for ( n = 0; n < count; n++ )        Free_AttachPoint( &ap[n] );      FREE( ap );    }    Free_Coverage( &al->Coverage );  }  /*********************************   * LigCaretList related functions   *********************************/  /* CaretValueFormat1 */  /* CaretValueFormat2 */  /* CaretValueFormat3 */  /* CaretValueFormat4 */  static TT_Error  Load_CaretValue( TTO_CaretValue*  cv,                                    PFace            input )  {    DEFINE_LOAD_LOCALS( input->stream );    ULong    cur_offset, new_offset, base_offset;    base_offset = FILE_Pos();    if ( ACCESS_Frame( 2L ) )      return error;    cv->CaretValueFormat = GET_UShort();    FORGET_Frame();    switch ( cv->CaretValueFormat )    {    case 1:      if ( ACCESS_Frame( 2L ) )        return error;      cv->cvf.cvf1.Coordinate = GET_Short();      FORGET_Frame();      break;    case 2:      if ( ACCESS_Frame( 2L ) )        return error;      cv->cvf.cvf2.CaretValuePoint = GET_UShort();      FORGET_Frame();      break;    case 3:      if ( ACCESS_Frame( 4L ) )        return error;      cv->cvf.cvf3.Coordinate = GET_Short();      new_offset = GET_UShort() + base_offset;      FORGET_Frame();      cur_offset = FILE_Pos();      if ( FILE_Seek( new_offset ) ||           ( error = Load_Device( &cv->cvf.cvf3.Device,                                  input ) ) != TT_Err_Ok )        return error;      (void)FILE_Seek( cur_offset );      break;    case 4:      if ( ACCESS_Frame( 2L ) )        return error;      cv->cvf.cvf4.IdCaretValue = GET_UShort();      FORGET_Frame();      break;    default:      return TTO_Err_Invalid_GDEF_SubTable_Format;    }    return TT_Err_Ok;  }  static void  Free_CaretValue( TTO_CaretValue*  cv )  {    if ( cv->CaretValueFormat == 3 )      Free_Device( &cv->cvf.cvf3.Device );  }  /* LigGlyph */  static TT_Error  Load_LigGlyph( TTO_LigGlyph*  lg,                                  PFace          input )  {    DEFINE_LOAD_LOCALS( input->stream );    UShort           n, count;    ULong            cur_offset, new_offset, base_offset;    TTO_CaretValue*  cv;    base_offset = FILE_Pos();    if ( ACCESS_Frame( 2L ) )      return error;    count = lg->CaretCount = GET_UShort();    FORGET_Frame();    lg->CaretValue = NULL;    if ( ALLOC_ARRAY( lg->CaretValue, count, TTO_CaretValue ) )      return error;    cv = lg->CaretValue;    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_CaretValue( &cv[n], input ) ) != TT_Err_Ok )

⌨️ 快捷键说明

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