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

📄 ftxgpos.c

📁 字体缩放显示
💻 C
📖 第 1 页 / 共 5 页
字号:
      if ( ALLOC_ARRAY( sp->spf.spf2.Value, count, TTO_ValueRecord ) )        goto Fail2;      vr = sp->spf.spf2.Value;      for ( n = 0; n < count; n++ )      {        error = Load_ValueRecord( &vr[n], format, base_offset, input );        if ( error )          goto Fail1;      }      break;    default:      return TTO_Err_Invalid_GPOS_SubTable_Format;    }    return TT_Err_Ok;  Fail1:    for ( n = 0; n < count; n++ )      Free_ValueRecord( &vr[n], format );    FREE( vr );  Fail2:    Free_Coverage( &sp->Coverage );    return error;  }  void  Free_SinglePos( TTO_SinglePos*  sp )  {    UShort            n, count, format;    TTO_ValueRecord*  v;    format = sp->ValueFormat;    switch ( sp->PosFormat )    {    case 1:      Free_ValueRecord( &sp->spf.spf1.Value, format );      break;    case 2:      if ( sp->spf.spf2.Value )      {        count = sp->spf.spf2.ValueCount;        v     = sp->spf.spf2.Value;        for ( n = 0; n < count; n++ )          Free_ValueRecord( &v[n], format );        FREE( v );      }      break;    }    Free_Coverage( &sp->Coverage );  }  static TT_Error  Lookup_SinglePos( GPOS_Instance*    gpi,                                     TTO_SinglePos*    sp,                                     TTO_GSUB_String*  in,                                     TTO_GPOS_Data*    out,                                     UShort            flags,                                     UShort            context_length )  {    UShort           index, property;    TT_Error         error;    TTO_GPOSHeader*  gpos = gpi->gpos;    if ( context_length != 0xFFFF && context_length < 1 )      return TTO_Err_Not_Covered;    if ( CHECK_Property( gpos->gdef, in->string[in->pos], flags, &property ) )      return error;    error = Coverage_Index( &sp->Coverage, in->string[in->pos], &index );    if ( error )      return error;    switch ( sp->PosFormat )    {    case 1:      error = Get_ValueRecord( gpi, &sp->spf.spf1.Value,                               sp->ValueFormat, &out[in->pos] );      if ( error )        return error;      break;    case 2:      if ( index >= sp->spf.spf2.ValueCount )        return TTO_Err_Invalid_GPOS_SubTable;      error = Get_ValueRecord( gpi, &sp->spf.spf2.Value[index],                               sp->ValueFormat, &out[in->pos] );      if ( error )        return error;      break;    default:      return TTO_Err_Invalid_GPOS_SubTable;    }    (in->pos)++;    return TT_Err_Ok;  }  /* LookupType 2 */  /* PairSet */  static TT_Error  Load_PairSet ( TTO_PairSet*  ps,                                  UShort        format1,                                  UShort        format2,                                  PFace         input )  {    DEFINE_LOAD_LOCALS( input->stream );    UShort                n, count;    ULong                 base_offset;    TTO_PairValueRecord*  pvr;    base_offset = FILE_Pos();    if ( ACCESS_Frame( 2L ) )      return error;    count = ps->PairValueCount = GET_UShort();        FORGET_Frame();    ps->PairValueRecord = NULL;    if ( ALLOC_ARRAY( ps->PairValueRecord, count, TTO_PairValueRecord ) )      return error;    pvr = ps->PairValueRecord;    for ( n = 0; n < count; n++ )    {      if ( ACCESS_Frame( 2L ) )        goto Fail;      pvr[n].SecondGlyph = GET_UShort();      FORGET_Frame();      if ( format1 )      {        error = Load_ValueRecord( &pvr[n].Value1, format1,                                  base_offset, input );        if ( error )          goto Fail;      }      if ( format2 )      {        error = Load_ValueRecord( &pvr[n].Value2, format2,                                  base_offset, input );        if ( error )          goto Fail;      }    }    return TT_Err_Ok;  Fail:    for ( n = 0; n < count; n++ )    {      if ( format1 )        Free_ValueRecord( &pvr[n].Value1, format1 );      if ( format2 )        Free_ValueRecord( &pvr[n].Value2, format2 );    }    FREE( pvr );    return error;  }  static void  Free_PairSet( TTO_PairSet*  ps,                             UShort        format1,                             UShort        format2 )  {    UShort                n, count;    TTO_PairValueRecord*  pvr;    if ( ps->PairValueRecord )    {      count = ps->PairValueCount;      pvr   = ps->PairValueRecord;      for ( n = 0; n < count; n++ )      {        if ( format1 )          Free_ValueRecord( &pvr[n].Value1, format1 );        if ( format2 )          Free_ValueRecord( &pvr[n].Value2, format2 );      }      FREE( pvr );    }  }  /* PairPosFormat1 */  static TT_Error  Load_PairPos1( TTO_PairPosFormat1*  ppf1,                                  UShort               format1,                                  UShort               format2,                                  PFace                input )  {    DEFINE_LOAD_LOCALS( input->stream );    UShort        n, count;    ULong         cur_offset, new_offset, base_offset;    TTO_PairSet*  ps;    base_offset = FILE_Pos() - 8L;    if ( ACCESS_Frame( 2L ) )      return error;    count = ppf1->PairSetCount = GET_UShort();    FORGET_Frame();    ppf1->PairSet = NULL;    if ( ALLOC_ARRAY( ppf1->PairSet, count, TTO_PairSet ) )      goto Fail;    ps = ppf1->PairSet;    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_PairSet( &ps[n], format1,                                   format2, input ) ) != TT_Err_Ok )        goto Fail;      (void)FILE_Seek( cur_offset );    }    return TT_Err_Ok;  Fail:    for ( n = 0; n < count; n++ )      Free_PairSet( &ps[n], format1, format2 );    FREE( ps );    return error;  }  static void  Free_PairPos1( TTO_PairPosFormat1*  ppf1,                              UShort               format1,                              UShort               format2 )  {    UShort        n, count;    TTO_PairSet*  ps;    if ( ppf1->PairSet )    {      count = ppf1->PairSetCount;      ps    = ppf1->PairSet;      for ( n = 0; n < count; n++ )        Free_PairSet( &ps[n], format1, format2 );      FREE( ps );    }  }  /* PairPosFormat2 */  static TT_Error  Load_PairPos2( TTO_PairPosFormat2*  ppf2,                                  UShort               format1,                                  UShort               format2,                                  PFace                input )  {    DEFINE_LOAD_LOCALS( input->stream );    UShort             m, n, count1, count2;    ULong              cur_offset, new_offset1, new_offset2, base_offset;    TTO_Class1Record*  c1r;    TTO_Class2Record*  c2r;    base_offset = FILE_Pos() - 8L;    if ( ACCESS_Frame( 8L ) )      return error;    new_offset1 = GET_UShort() + base_offset;    new_offset2 = GET_UShort() + base_offset;    /* `Class1Count' and `Class2Count' are the upper limits for class       values, thus we read it now to make additional safety checks.  */    count1 = ppf2->Class1Count = GET_UShort();    count2 = ppf2->Class2Count = GET_UShort();    FORGET_Frame();    cur_offset = FILE_Pos();    if ( FILE_Seek( new_offset1 ) ||         ( error = Load_ClassDefinition( &ppf2->ClassDef1, count1,                                         input ) ) != TT_Err_Ok )      return error;    if ( FILE_Seek( new_offset2 ) ||         ( error = Load_ClassDefinition( &ppf2->ClassDef2, count2,                                         input ) ) != TT_Err_Ok )      goto Fail2;    (void)FILE_Seek( cur_offset );    ppf2->Class1Record = NULL;    if ( ALLOC_ARRAY( ppf2->Class1Record, count1, TTO_Class1Record ) )      goto Fail1;    c1r = ppf2->Class1Record;    for ( m = 0; m < count1; m++ )    {      c1r[m].Class2Record = NULL;      if ( ALLOC_ARRAY( c1r[m].Class2Record, count2, TTO_Class2Record ) )        goto Fail1;      c2r = c1r[m].Class2Record;      for ( n = 0; n < count2; n++ )      {        if ( format1 )        {          error = Load_ValueRecord( &c2r[n].Value1, format1,                                    base_offset, input );          if ( error )            goto Fail1;        }        if ( format2 )        {          error = Load_ValueRecord( &c2r[n].Value2, format2,                                    base_offset, input );          if ( error )            goto Fail1;        }      }    }    return TT_Err_Ok;  Fail1:    for ( m = 0; m < count1; m++ )    {      c2r = c1r[m].Class2Record;      for ( n = 0; n < count2; n++ )      {        if ( format1 )          Free_ValueRecord( &c2r[n].Value1, format1 );        if ( format2 )          Free_ValueRecord( &c2r[n].Value2, format2 );      }      FREE( c2r );    }    FREE( c1r );    Free_ClassDefinition( &ppf2->ClassDef2 );  Fail2:    Free_ClassDefinition( &ppf2->ClassDef1 );    return error;  }  static void  Free_PairPos2( TTO_PairPosFormat2*  ppf2,                              UShort               format1,                              UShort               format2 )  {    UShort             m, n, count1, count2;    TTO_Class1Record*  c1r;    TTO_Class2Record*  c2r;    if ( ppf2->Class1Record )    {      c1r    = ppf2->Class1Record;      count1 = ppf2->Class1Count;      count2 = ppf2->Class2Count;      for ( m = 0; m < count1; m++ )      {        c2r = c1r[m].Class2Record;        for ( n = 0; n < count2; n++ )        {          if ( format1 )            Free_ValueRecord( &c2r[n].Value1, format1 );          if ( format2 )            Free_ValueRecord( &c2r[n].Value2, format2 );        }        FREE( c2r );      }      FREE( c1r );      Free_ClassDefinition( &ppf2->ClassDef2 );      Free_ClassDefinition( &ppf2->ClassDef1 );    }  }  TT_Error  Load_PairPos( TTO_PairPos*  pp,                          PFace         input )  {    DEFINE_LOAD_LOCALS( input->stream );    UShort            format1, format2;    ULong             cur_offset, new_offset, base_offset;    base_offset = FILE_Pos();    if ( ACCESS_Frame( 8L ) )      return error;    pp->PosFormat = GET_UShort();    new_offset    = GET_UShort() + base_offset;    format1 = pp->ValueFormat1 = GET_UShort();    format2 = pp->ValueFormat2 = GET_UShort();    FORGET_Frame();    cur_offset = FILE_Pos();    if ( FILE_Seek( new_offset ) ||         ( error = Load_Coverage( &pp->Coverage, input ) ) != TT_Err_Ok )      return error;    (void)FILE_Seek( cur_offset );    switch ( pp->PosFormat )    {    case 1:      error = Load_PairPos1( &pp->ppf.ppf1, format1, format2, input );      if ( error )        goto Fail;      break;    case 2:      error = Load_PairPos2( &pp->ppf.ppf2, format1, format2, input );      if ( error )        goto Fail;      break;    default:      return TTO_Err_Invalid_GPOS_SubTable_Format;    }    return TT_Err_Ok;  Fail:    Free_Coverage( &pp->Coverage );    return error;  }  void  Free_PairPos( TTO_PairPos*  pp )  {    UShort  format1, format2;    format1 = pp->ValueFormat1;    format2 = pp->ValueFormat2;    switch ( pp->PosFormat )    {    case 1:      Free_PairPos1( &pp->ppf.ppf1, format1, format2 );      break;    case 2:      Free_PairPos2( &pp->ppf.ppf2, format1, format2 );      break;    }    Free_Coverage( &pp->Coverage );  }  static TT_Error  Lookup_PairPos1( GPOS_Instance*       gpi,                                    TTO_PairPosFormat1*  ppf1,                                    TTO_GSUB_String*     in,                                    TTO_GPOS_Data*       out,                                    UShort               first_pos,                                    UShort               index,                                    UShort               format1,                                    UShort               format2 )  {    TT_Error              error;    UShort                numpvr, glyph2;    TTO_PairValueRecord*  pvr;    if ( index >= ppf1->PairSetCount )       return TTO_Err_Invalid_GPOS_SubTable;    pvr = ppf1->PairSet[index].PairValueRecord;

⌨️ 快捷键说明

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