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

📄 ftxgdef.c

📁 神龙卡开发原代码
💻 C
📖 第 1 页 / 共 2 页
字号:
        goto Fail;      (void)FILE_Seek( cur_offset );    }    return TT_Err_Ok;  Fail:    for ( n = 0; n < count; n++ )      Free_CaretValue( &cv[n] );    FREE( cv );    return error;  }  static void  Free_LigGlyph( TTO_LigGlyph*  lg )  {    UShort           n, count;    TTO_CaretValue*  cv;    if ( lg->CaretValue )    {      count = lg->CaretCount;      cv    = lg->CaretValue;      for ( n = 0; n < count; n++ )        Free_CaretValue( &cv[n] );      FREE( cv );    }  }  /* LigCaretList */  static TT_Error  Load_LigCaretList( TTO_LigCaretList*  lcl,                                      PFace              input )  {    DEFINE_LOAD_LOCALS( input->stream );    UShort         n, count;    ULong          cur_offset, new_offset, base_offset;    TTO_LigGlyph*  lg;    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( &lcl->Coverage, input ) ) != TT_Err_Ok )      return error;    (void)FILE_Seek( cur_offset );    if ( ACCESS_Frame( 2L ) )      goto Fail2;    count = lcl->LigGlyphCount = GET_UShort();    FORGET_Frame();    lcl->LigGlyph = NULL;    if ( ALLOC_ARRAY( lcl->LigGlyph, count, TTO_LigGlyph ) )      goto Fail2;    lg = lcl->LigGlyph;    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_LigGlyph( &lg[n], input ) ) != TT_Err_Ok )        goto Fail1;      (void)FILE_Seek( cur_offset );    }    lcl->loaded = TRUE;    return TT_Err_Ok;  Fail1:    for ( n = 0; n < count; n++ )      Free_LigGlyph( &lg[n] );    FREE( lg );  Fail2:    Free_Coverage( &lcl->Coverage );    return error;  }  static void  Free_LigCaretList( TTO_LigCaretList*  lcl )  {    UShort         n, count;    TTO_LigGlyph*  lg;    if ( !lcl->loaded )      return;    if ( lcl->LigGlyph )    {      count = lcl->LigGlyphCount;      lg    = lcl->LigGlyph;      for ( n = 0; n < count; n++ )        Free_LigGlyph( &lg[n] );      FREE( lg );    }    Free_Coverage( &lcl->Coverage );  }  /***********   * GDEF API   ***********/  static UShort  Get_New_Class( TTO_GDEFHeader*  gdef,                                UShort           glyphID,                                UShort           index )  {    UShort                 glyph_index, array_index;    UShort                 byte, bits;    TTO_ClassRangeRecord*  gcrr;    UShort**               ngc;    if ( glyphID >= gdef->LastGlyph )      return 0;    gcrr = gdef->GlyphClassDef.cd.cd2.ClassRangeRecord;    ngc  = gdef->NewGlyphClasses;    if ( glyphID < gcrr[index].Start )    {      array_index = 0;      if ( index == 0 )        glyph_index = glyphID;      else        glyph_index = glyphID - gcrr[index - 1].End - 1;    }    else    {      array_index = index + 1;      glyph_index = glyphID - gcrr[index].End - 1;    }    byte = ngc[array_index][glyph_index / 4 + 1];    bits = byte >> ( 16 - ( glyph_index % 4 + 1 ) * 4 );    return bits & 0x000F;  }  EXPORT_FUNC  TT_Error  TT_GDEF_Get_Glyph_Property( TTO_GDEFHeader*  gdef,                                        TT_UShort        glyphID,                                        TT_UShort*       property )  {    UShort    class, index;    TT_Error  error;    if ( !gdef || !property )      return TT_Err_Invalid_Argument;    /* first, we check for mark attach classes */    if ( gdef->MarkAttachClassDef.loaded )    {      error = Get_Class( &gdef->MarkAttachClassDef, glyphID, &class, &index );      if ( error && error != TTO_Err_Not_Covered )        return error;      if ( !error )      {        *property = class << 8;        return TT_Err_Ok;      }    }    error = Get_Class( &gdef->GlyphClassDef, glyphID, &class, &index );    if ( error && error != TTO_Err_Not_Covered )      return error;    /* if we have a constructed class table, check whether additional       values have been assigned                                      */    if ( error == TTO_Err_Not_Covered && gdef->NewGlyphClasses )      class = Get_New_Class( gdef, glyphID, index );    switch ( class )    {    case UNCLASSIFIED_GLYPH:      *property = 0;      break;    case SIMPLE_GLYPH:      *property = TTO_BASE_GLYPH;      break;    case LIGATURE_GLYPH:      *property = TTO_LIGATURE;      break;    case MARK_GLYPH:      *property = TTO_MARK;      break;    case COMPONENT_GLYPH:      *property = TTO_COMPONENT;      break;    }    return TT_Err_Ok;  }  static TT_Error  Make_ClassRange( TTO_ClassDefinition*  cd,                                    UShort                start,                                    UShort                end,                                    UShort                class )  {    TT_Error               error;    UShort                 index;    TTO_ClassDefFormat2*   cdf2;    TTO_ClassRangeRecord*  crr;    cdf2 = &cd->cd.cd2;    cdf2->ClassRangeCount++;    if ( REALLOC_ARRAY( cdf2->ClassRangeRecord, cdf2->ClassRangeCount,                        TTO_ClassRangeRecord ) )      return error;    crr   = cdf2->ClassRangeRecord;    index = cdf2->ClassRangeCount - 1;    crr[index].Start = start;    crr[index].End   = end;    crr[index].Class = class;    cd->Defined[class] = TRUE;    return TT_Err_Ok;  }  EXPORT_FUNC  TT_Error  TT_GDEF_Build_ClassDefinition( TTO_GDEFHeader*  gdef,                                           TT_UShort        num_glyphs,                                           TT_UShort        glyph_count,                                           TT_UShort*       glyph_array,                                           TT_UShort*       class_array )  {    UShort                 start, curr_glyph, curr_class;    UShort                 n, count;    TT_Error               error;    TTO_ClassDefinition*   gcd;    TTO_ClassRangeRecord*  gcrr;    UShort**               ngc;    if ( !gdef || !glyph_array || !class_array )      return TT_Err_Invalid_Argument;    gcd = &gdef->GlyphClassDef;    /* We build a format 2 table */    gcd->ClassFormat = 2;    /* A GlyphClassDef table contains at most 5 different class values */    if ( ALLOC_ARRAY( gcd->Defined, 5, Bool ) )      return error;    gcd->cd.cd2.ClassRangeCount  = 0;    gcd->cd.cd2.ClassRangeRecord = NULL;    start      = glyph_array[0];    curr_class = class_array[0];    curr_glyph = start;    if ( curr_class >= 5 )    {      error = TT_Err_Invalid_Argument;      goto Fail4;    }    glyph_count--;    for ( n = 0; n <= glyph_count; n++ )    {      if ( curr_glyph == glyph_array[n] && curr_class == class_array[n] )      {        if ( n == glyph_count )        {          if ( ( error = Make_ClassRange( gcd, start,                                          curr_glyph,                                          curr_class ) ) != TT_Err_Ok )            goto Fail3;        }        else        {          if ( curr_glyph == 0xFFFF )          {            error = TT_Err_Invalid_Argument;            goto Fail3;          }          else            curr_glyph++;        }      }      else      {        if ( ( error = Make_ClassRange( gcd, start,                                        curr_glyph - 1,                                        curr_class ) ) != TT_Err_Ok )          goto Fail3;        if ( curr_glyph > glyph_array[n] )        {          error = TT_Err_Invalid_Argument;          goto Fail3;        }        start      = glyph_array[n];        curr_class = class_array[n];        curr_glyph = start;        if ( curr_class >= 5 )        {          error = TT_Err_Invalid_Argument;          goto Fail3;        }        if ( n == glyph_count )        {          if ( ( error = Make_ClassRange( gcd, start,                                          curr_glyph,                                          curr_class ) ) != TT_Err_Ok )            goto Fail3;        }        else        {          if ( curr_glyph == 0xFFFF )          {            error = TT_Err_Invalid_Argument;            goto Fail3;          }          else            curr_glyph++;        }      }    }    /* now prepare the arrays for class values assigned during the lookup       process                                                            */    if ( ALLOC_ARRAY( gdef->NewGlyphClasses,                      gcd->cd.cd2.ClassRangeCount + 1, UShort* ) )      goto Fail2;    count = gcd->cd.cd2.ClassRangeCount;    gcrr  = gcd->cd.cd2.ClassRangeRecord;    ngc   = gdef->NewGlyphClasses;    /* We allocate arrays for all glyphs not covered by the class range       records.  Each element holds four class values.                  */    if ( gcrr[0].Start )    {      if ( ALLOC_ARRAY( ngc[0], gcrr[0].Start / 4 + 1, UShort ) )        goto Fail1;    }    for ( n = 1; n < count; n++ )    {      if ( gcrr[n].Start - gcrr[n - 1].End > 1 )        if ( ALLOC_ARRAY( ngc[n],                          ( gcrr[n].Start - gcrr[n - 1].End - 1 ) / 4 + 1,                          UShort ) )          goto Fail1;    }    if ( gcrr[count - 1].End != num_glyphs - 1 )    {      if ( ALLOC_ARRAY( ngc[count],                        ( num_glyphs - gcrr[count - 1].End - 1 ) / 4 + 1,                        UShort ) )        goto Fail1;    }    gdef->LastGlyph = num_glyphs - 1;    gdef->MarkAttachClassDef_offset = 0L;    gdef->MarkAttachClassDef.loaded = FALSE;    return TT_Err_Ok;  Fail1:    for ( n = 0; n < count; n++ )      FREE( ngc[n] );  Fail2:    FREE( gdef->NewGlyphClasses );  Fail3:    FREE( gcd->cd.cd2.ClassRangeRecord );  Fail4:    FREE( gcd->Defined );    return error;  }  static void  Free_NewGlyphClasses( TTO_GDEFHeader*  gdef )  {    UShort**  ngc;    UShort    n, count;    if ( gdef->NewGlyphClasses )    {      count = gdef->GlyphClassDef.cd.cd2.ClassRangeCount + 1;      ngc   = gdef->NewGlyphClasses;      for ( n = 0; n < count; n++ )        FREE( ngc[n] );      FREE( ngc );    }  }  TT_Error  Add_Glyph_Property( TTO_GDEFHeader*  gdef,                                UShort           glyphID,                                UShort           property )  {    TT_Error               error;    UShort                 class, new_class, index;    UShort                 byte, bits, mask;    UShort                 array_index, glyph_index;    TTO_ClassRangeRecord*  gcrr;    UShort**               ngc;    error = Get_Class( &gdef->GlyphClassDef, glyphID, &class, &index );    if ( error && error != TTO_Err_Not_Covered )      return error;    /* we don't accept glyphs covered in `GlyphClassDef' */    if ( !error )      return TTO_Err_Not_Covered;    switch ( property )    {    case 0:      new_class = UNCLASSIFIED_GLYPH;      break;    case TTO_BASE_GLYPH:      new_class = SIMPLE_GLYPH;      break;    case TTO_LIGATURE:      new_class = LIGATURE_GLYPH;      break;    case TTO_MARK:      new_class = MARK_GLYPH;      break;    case TTO_COMPONENT:      new_class = COMPONENT_GLYPH;      break;    default:      return TT_Err_Invalid_Argument;    }    gcrr = gdef->GlyphClassDef.cd.cd2.ClassRangeRecord;    ngc  = gdef->NewGlyphClasses;    if ( glyphID < gcrr[index].Start )    {      array_index = 0;      if ( index == 0 )        glyph_index = glyphID;      else        glyph_index = glyphID - gcrr[index - 1].End - 1;    }    else    {      array_index = index + 1;      glyph_index = glyphID - gcrr[index].End - 1;    }    byte  = ngc[array_index][glyph_index / 4 + 1];    bits  = byte >> ( 16 - ( glyph_index % 4 + 1 ) * 4 );    class = bits & 0x000F;    /* we don't overwrite existing entries */    if ( !class )    {      bits = new_class << ( 16 - ( glyph_index % 4 + 1 ) * 4 );      mask = ~( 0x000F << ( 16 - ( glyph_index % 4 + 1 ) * 4 ) );      ngc[array_index][glyph_index / 4 + 1] &= mask;      ngc[array_index][glyph_index / 4 + 1] |= bits;    }    return TT_Err_Ok;  }/* END */

⌨️ 快捷键说明

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