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

📄 harfbuzz-gdef.c

📁 GTK+-2.0源码之pango-1.15.6.tar.gz
💻 C
📖 第 1 页 / 共 2 页
字号:
{  FT_UShort        n, count;  HB_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( HB_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;  HB_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 = _HB_OPEN_Load_Coverage( &lcl->Coverage, stream ) ) != FT_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, HB_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 ) ) != FT_Err_Ok )      goto Fail1;    (void)FILE_Seek( cur_offset );  }  lcl->loaded = TRUE;  return FT_Err_Ok;Fail1:  for ( m = 0; m < n; m++ )    Free_LigGlyph( &lg[m], memory );  FREE( lg );Fail2:  _HB_OPEN_Free_Coverage( &lcl->Coverage, memory );  return error;}static void  Free_LigCaretList( HB_LigCaretList*  lcl,				FT_Memory           memory ){  FT_UShort      n, count;  HB_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 );  }  _HB_OPEN_Free_Coverage( &lcl->Coverage, memory );}/*********** * GDEF API ***********/static FT_UShort  Get_New_Class( HB_GDEFHeader*  gdef,				 FT_UShort        glyphID,				 FT_UShort        index ){  FT_UShort              glyph_index, array_index, count;  FT_UShort              byte, bits;    HB_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;}FT_Error  HB_GDEF_Get_Glyph_Property( HB_GDEFHeader*  gdef,				      FT_UShort        glyphID,				      FT_UShort*       property ){  FT_UShort class, index;  FT_Error  error;  if ( !gdef || !property )    return FT_Err_Invalid_Argument;  /* first, we check for mark attach classes */  if ( gdef->MarkAttachClassDef.loaded )  {    error = _HB_OPEN_Get_Class( &gdef->MarkAttachClassDef, glyphID, &class, &index );    if ( error && error != HB_Err_Not_Covered )      return error;    if ( !error )    {      *property = class << 8;      return FT_Err_Ok;    }  }  error = _HB_OPEN_Get_Class( &gdef->GlyphClassDef, glyphID, &class, &index );  if ( error && error != HB_Err_Not_Covered )    return error;  /* if we have a constructed class table, check whether additional     values have been assigned                                      */  if ( error == HB_Err_Not_Covered && gdef->NewGlyphClasses )    class = Get_New_Class( gdef, glyphID, index );  switch ( class )  {  case UNCLASSIFIED_GLYPH:    *property = 0;    break;  case SIMPLE_GLYPH:    *property = HB_GDEF_BASE_GLYPH;    break;  case LIGATURE_GLYPH:    *property = HB_GDEF_LIGATURE;    break;  case MARK_GLYPH:    *property = HB_GDEF_MARK;    break;  case COMPONENT_GLYPH:    *property = HB_GDEF_COMPONENT;    break;  }  return FT_Err_Ok;}static FT_Error  Make_ClassRange( HB_ClassDefinition*  cd,				  FT_UShort             start,				  FT_UShort             end,				  FT_UShort             class,				  FT_Memory             memory ){  FT_Error               error;  FT_UShort              index;  HB_ClassDefFormat2*   cdf2;  HB_ClassRangeRecord*  crr;  cdf2 = &cd->cd.cd2;  if ( REALLOC_ARRAY( cdf2->ClassRangeRecord,		      cdf2->ClassRangeCount,		      cdf2->ClassRangeCount + 1 ,		      HB_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 FT_Err_Ok;}FT_Error  HB_GDEF_Build_ClassDefinition( HB_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;  HB_ClassDefinition*   gcd;  HB_ClassRangeRecord*  gcrr;  FT_UShort**            ngc;  if ( !gdef || !glyph_array || !class_array )    return FT_Err_Invalid_Argument;  memory = gdef->memory;  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 = FT_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 ) ) != FT_Err_Ok )	  goto Fail3;      }      else      {	if ( curr_glyph == 0xFFFF )	{	  error = FT_Err_Invalid_Argument;	  goto Fail3;	}	else	  curr_glyph++;      }    }    else    {      if ( ( error = Make_ClassRange( gcd, start,				      curr_glyph - 1,				      curr_class,				      memory ) ) != FT_Err_Ok )	goto Fail3;      if ( curr_glyph > glyph_array[n] )      {	error = FT_Err_Invalid_Argument;	goto Fail3;      }      start      = glyph_array[n];      curr_class = class_array[n];      curr_glyph = start;      if ( curr_class >= 5 )      {	error = FT_Err_Invalid_Argument;	goto Fail3;      }      if ( n == glyph_count )      {	if ( ( error = Make_ClassRange( gcd, start,					curr_glyph,					curr_class,					memory ) ) != FT_Err_Ok )	  goto Fail3;      }      else      {	if ( curr_glyph == 0xFFFF )	{	  error = FT_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 FT_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( HB_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  _HB_GDEF_Add_Glyph_Property( HB_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;  HB_ClassRangeRecord*  gcrr;  FT_UShort**            ngc;  error = _HB_OPEN_Get_Class( &gdef->GlyphClassDef, glyphID, &class, &index );  if ( error && error != HB_Err_Not_Covered )    return error;  /* we don't accept glyphs covered in `GlyphClassDef' */  if ( !error )    return HB_Err_Not_Covered;  switch ( property )  {  case 0:    new_class = UNCLASSIFIED_GLYPH;    break;  case HB_GDEF_BASE_GLYPH:    new_class = SIMPLE_GLYPH;    break;  case HB_GDEF_LIGATURE:    new_class = LIGATURE_GLYPH;    break;  case HB_GDEF_MARK:    new_class = MARK_GLYPH;    break;  case HB_GDEF_COMPONENT:    new_class = COMPONENT_GLYPH;    break;  default:    return FT_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 FT_Err_Ok;}FT_Error  _HB_GDEF_Check_Property( HB_GDEFHeader*  gdef,			  HB_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 == HB_GLYPH_PROPERTIES_UNKNOWN )    {      error = HB_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 & HB_LOOKUP_FLAG_IGNORE_SPECIAL_MARKS  )      basic_glyph_class = HB_GDEF_MARK;    else      basic_glyph_class = *property;    /* Return Not_Covered, if, for example, basic_glyph_class     * is HB_GDEF_LIGATURE and LookFlags includes HB_LOOKUP_FLAG_IGNORE_LIGATURES     */    if ( flags & basic_glyph_class )      return HB_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 & HB_LOOKUP_FLAG_IGNORE_SPECIAL_MARKS;    if ( desired_attachment_class )    {      if ( basic_glyph_class == HB_GDEF_MARK &&	   *property != desired_attachment_class )	return HB_Err_Not_Covered;    }  }  return FT_Err_Ok;}/* END */

⌨️ 快捷键说明

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