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

📄 ftxgdef.c

📁 qt-x11-opensource-src-4.1.4.tar.gz源码
💻 C
📖 第 1 页 / 共 2 页
字号:
  {    FT_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], memory );      FREE( cv );    }  }  /* LigCaretList */  static FT_Error  Load_LigCaretList( TTO_LigCaretList*  lcl,                                      FT_Stream          stream )  {    FT_Memory memory = stream->memory;    FT_Error  error;    FT_UShort      m, n, count;    FT_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, stream ) ) != 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], stream ) ) != TT_Err_Ok )        goto Fail1;      (void)FILE_Seek( cur_offset );    }    lcl->loaded = TRUE;    return TT_Err_Ok;  Fail1:    for ( m = 0; m < n; m++ )      Free_LigGlyph( &lg[m], memory );    FREE( lg );  Fail2:    Free_Coverage( &lcl->Coverage, memory );    return error;  }  static void  Free_LigCaretList( TTO_LigCaretList*  lcl,				  FT_Memory           memory )  {    FT_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], memory );      FREE( lg );    }    Free_Coverage( &lcl->Coverage, memory );  }  /***********   * GDEF API   ***********/  static FT_UShort  Get_New_Class( TTO_GDEFHeader*  gdef,				   FT_UShort        glyphID,				   FT_UShort        index )  {    FT_UShort              glyph_index, array_index, count;    FT_UShort              byte, bits;        TTO_ClassRangeRecord*  gcrr;    FT_UShort**            ngc;    if ( glyphID >= gdef->LastGlyph )      return 0;    count = gdef->GlyphClassDef.cd.cd2.ClassRangeCount;    gcrr = gdef->GlyphClassDef.cd.cd2.ClassRangeRecord;    ngc  = gdef->NewGlyphClasses;    if ( index < count && glyphID < gcrr[index].Start )    {      array_index = index;      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];    bits = byte >> ( 16 - ( glyph_index % 4 + 1 ) * 4 );    return bits & 0x000F;  }  EXPORT_FUNC  FT_Error  TT_GDEF_Get_Glyph_Property( TTO_GDEFHeader*  gdef,                                        FT_UShort        glyphID,                                        FT_UShort*       property )  {    FT_UShort class, index;    FT_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 FT_Error  Make_ClassRange( TTO_ClassDefinition*  cd,                                    FT_UShort             start,                                    FT_UShort             end,                                    FT_UShort             class,				    FT_Memory             memory )  {    FT_Error               error;    FT_UShort              index;    TTO_ClassDefFormat2*   cdf2;    TTO_ClassRangeRecord*  crr;    cdf2 = &cd->cd.cd2;    if ( REALLOC_ARRAY( cdf2->ClassRangeRecord,			cdf2->ClassRangeCount,			cdf2->ClassRangeCount + 1 ,                        TTO_ClassRangeRecord ) )      return error;    cdf2->ClassRangeCount++;    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  FT_Error  TT_GDEF_Build_ClassDefinition( TTO_GDEFHeader*  gdef,                                           FT_UShort        num_glyphs,                                           FT_UShort        glyph_count,                                           FT_UShort*       glyph_array,                                           FT_UShort*       class_array )  {    FT_UShort              start, curr_glyph, curr_class;    FT_UShort              n, m, count;    FT_Error               error;    FT_Memory              memory = gdef->memory;    TTO_ClassDefinition*   gcd;    TTO_ClassRangeRecord*  gcrr;    FT_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, FT_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,					  memory ) ) != 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,					memory ) ) != 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,					  memory ) ) != 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, FT_UShort* ) )      goto Fail3;    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 ( count > 0 )    {	if ( gcrr[0].Start )	{	  if ( ALLOC_ARRAY( ngc[0], ( gcrr[0].Start + 3 ) / 4, FT_UShort ) )	    goto Fail2;	}	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 + 2 ) / 4,			      FT_UShort ) )	      goto Fail1;	}	if ( gcrr[count - 1].End != num_glyphs - 1 )	{	  if ( ALLOC_ARRAY( ngc[count],			    ( num_glyphs - gcrr[count - 1].End + 2 ) / 4,			    FT_UShort ) )	      goto Fail1;	}    }    else if ( num_glyphs > 0 )    {	if ( ALLOC_ARRAY( ngc[count],			  ( num_glyphs + 3 ) / 4,			  FT_UShort ) )	    goto Fail2;    }	    gdef->LastGlyph = num_glyphs - 1;    gdef->MarkAttachClassDef_offset = 0L;    gdef->MarkAttachClassDef.loaded = FALSE;    gcd->loaded = TRUE;    return TT_Err_Ok;  Fail1:    for ( m = 0; m < n; m++ )      FREE( ngc[m] );  Fail2:    FREE( gdef->NewGlyphClasses );  Fail3:    FREE( gcd->cd.cd2.ClassRangeRecord );  Fail4:    FREE( gcd->Defined );    return error;  }  static void  Free_NewGlyphClasses( TTO_GDEFHeader*  gdef,				     FT_Memory        memory )  {    FT_UShort**  ngc;    FT_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 );    }  }  FT_Error  Add_Glyph_Property( TTO_GDEFHeader*  gdef,                                FT_UShort        glyphID,                                FT_UShort        property )  {    FT_Error               error;    FT_UShort              class, new_class, index;    FT_UShort              byte, bits, mask;    FT_UShort              array_index, glyph_index, count;    TTO_ClassRangeRecord*  gcrr;    FT_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;    }    count = gdef->GlyphClassDef.cd.cd2.ClassRangeCount;    gcrr = gdef->GlyphClassDef.cd.cd2.ClassRangeRecord;    ngc  = gdef->NewGlyphClasses;    if ( index < count && glyphID < gcrr[index].Start )    {      array_index = index;      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];    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] &= mask;      ngc[array_index][glyph_index / 4] |= bits;    }    return TT_Err_Ok;  }  FT_Error  Check_Property( TTO_GDEFHeader*  gdef,			    OTL_GlyphItem    gitem,                            FT_UShort        flags,                            FT_UShort*       property )  {    FT_Error  error;    if ( gdef )    {      FT_UShort basic_glyph_class;      FT_UShort desired_attachment_class;      if ( gitem->gproperties == OTL_GLYPH_PROPERTIES_UNKNOWN )      {	error = TT_GDEF_Get_Glyph_Property( gdef, gitem->gindex, &gitem->gproperties );	if ( error )	  return error;      }      *property = gitem->gproperties;      /* If the glyph was found in the MarkAttachmentClass table,       * then that class value is the high byte of the result,       * otherwise the low byte contains the basic type of the glyph       * as defined by the GlyphClassDef table.       */      if ( *property & IGNORE_SPECIAL_MARKS  )	basic_glyph_class = TTO_MARK;      else	basic_glyph_class = *property;      /* Return Not_Covered, if, for example, basic_glyph_class       * is TTO_LIGATURE and LookFlags includes IGNORE_LIGATURES       */      if ( flags & basic_glyph_class )	return TTO_Err_Not_Covered;            /* The high byte of LookupFlags has the meaning       * "ignore marks of attachment type different than       * the attachment type specified."       */      desired_attachment_class = flags & IGNORE_SPECIAL_MARKS;      if ( desired_attachment_class )      {	if ( basic_glyph_class == TTO_MARK &&	     *property != desired_attachment_class )	  return TTO_Err_Not_Covered;      }    }    return TT_Err_Ok;  }/* END */

⌨️ 快捷键说明

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