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

📄 harfbuzz-gdef.c

📁 Pango is a library for layout and rendering of text, with an emphasis on internationalization. Pang
💻 C
📖 第 1 页 / 共 2 页
字号:
    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 ) ) != HB_Err_Ok )      goto Fail1;    (void)FILE_Seek( cur_offset );  }  lcl->loaded = TRUE;  return HB_Err_Ok;Fail1:  for ( m = 0; m < n; m++ )    Free_LigGlyph( &lg[m] );  FREE( lg );Fail2:  _HB_OPEN_Free_Coverage( &lcl->Coverage );  return error;}static void  Free_LigCaretList( HB_LigCaretList*  lcl ){  HB_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] );    FREE( lg );  }  _HB_OPEN_Free_Coverage( &lcl->Coverage );}/*********** * GDEF API ***********/static HB_UShort  Get_New_Class( HB_GDEFHeader*  gdef,				 HB_UShort        glyphID,				 HB_UShort        index ){  HB_UShort              glyph_index, array_index, count;  HB_UShort              byte, bits;    HB_ClassRangeRecord*  gcrr;  HB_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;}HB_Error  HB_GDEF_Get_Glyph_Property( HB_GDEFHeader*  gdef,				      HB_UShort        glyphID,				      HB_UShort*       property ){  HB_UShort class = 0, index = 0; /* shut compiler up */  HB_Error  error;  if ( !gdef || !property )    return ERR(HB_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 HB_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 )  {  default:  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 HB_Err_Ok;}static HB_Error  Make_ClassRange( HB_ClassDefinition*  cd,				  HB_UShort             start,				  HB_UShort             end,				  HB_UShort             class ){  HB_Error               error;  HB_UShort              index;  HB_ClassDefFormat2*   cdf2;  HB_ClassRangeRecord*  crr;  cdf2 = &cd->cd.cd2;  if ( REALLOC_ARRAY( cdf2->ClassRangeRecord,		      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 HB_Err_Ok;}HB_Error  HB_GDEF_Build_ClassDefinition( HB_GDEFHeader*  gdef,					 HB_UShort        num_glyphs,					 HB_UShort        glyph_count,					 HB_UShort*       glyph_array,					 HB_UShort*       class_array ){  HB_UShort              start, curr_glyph, curr_class;  HB_UShort              n, m, count;  HB_Error               error;  HB_ClassDefinition*   gcd;  HB_ClassRangeRecord*  gcrr;  HB_UShort**            ngc;  if ( !gdef || !glyph_array || !class_array )    return ERR(HB_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, HB_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 = ERR(HB_Err_Invalid_Argument);    goto Fail4;  }  glyph_count--;  for ( n = 0; n < glyph_count + 1; 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 ) ) != HB_Err_Ok )	  goto Fail3;      }      else      {	if ( curr_glyph == 0xFFFF )	{	  error = ERR(HB_Err_Invalid_Argument);	  goto Fail3;	}	else	  curr_glyph++;      }    }    else    {      if ( ( error = Make_ClassRange( gcd, start,				      curr_glyph - 1,				      curr_class ) ) != HB_Err_Ok )	goto Fail3;      if ( curr_glyph > glyph_array[n] )      {	error = ERR(HB_Err_Invalid_Argument);	goto Fail3;      }      start      = glyph_array[n];      curr_class = class_array[n];      curr_glyph = start;      if ( curr_class >= 5 )      {	error = ERR(HB_Err_Invalid_Argument);	goto Fail3;      }      if ( n == glyph_count )      {	if ( ( error = Make_ClassRange( gcd, start,					curr_glyph,					curr_class ) ) != HB_Err_Ok )	  goto Fail3;      }      else      {	if ( curr_glyph == 0xFFFF )	{	  error = ERR(HB_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, HB_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, HB_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,			    HB_UShort ) )	    goto Fail1;      }      if ( gcrr[count - 1].End != num_glyphs - 1 )      {	if ( ALLOC_ARRAY( ngc[count],			  ( num_glyphs - gcrr[count - 1].End + 2 ) / 4,			  HB_UShort ) )	    goto Fail1;      }  }  else if ( num_glyphs > 0 )  {      if ( ALLOC_ARRAY( ngc[count],			( num_glyphs + 3 ) / 4,			HB_UShort ) )	  goto Fail2;  }        gdef->LastGlyph = num_glyphs - 1;  gdef->MarkAttachClassDef_offset = 0L;  gdef->MarkAttachClassDef.loaded = FALSE;  gcd->loaded = TRUE;  return HB_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 ){  HB_UShort**  ngc;  HB_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 );  }}HB_INTERNAL HB_Error_HB_GDEF_Add_Glyph_Property( HB_GDEFHeader* gdef,			     HB_UShort      glyphID,			     HB_UShort      property ){  HB_Error               error;  HB_UShort              class, new_class, index = 0; /* shut compiler up */  HB_UShort              byte, bits, mask;  HB_UShort              array_index, glyph_index, count;  HB_ClassRangeRecord*  gcrr;  HB_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 ERR(HB_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 HB_Err_Ok;}HB_INTERNAL HB_Error_HB_GDEF_Check_Property( HB_GDEFHeader* gdef,			 HB_GlyphItem   gitem,			 HB_UShort      flags,			 HB_UShort*     property ){  HB_Error  error;  if ( gdef )  {    HB_UShort basic_glyph_class;    HB_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;    }  } else {      *property = 0;  }  return HB_Err_Ok;}HB_INTERNAL HB_Error_HB_GDEF_LoadMarkAttachClassDef_From_LookupFlags( HB_GDEFHeader* gdef,						  HB_Stream      stream,						  HB_Lookup*     lo,						  HB_UShort      num_lookups){  HB_Error   error = HB_Err_Ok;  HB_UShort  i;  /* We now check the LookupFlags for values larger than 0xFF to find     out whether we need to load the `MarkAttachClassDef' field of the     GDEF table -- this hack is necessary for OpenType 1.2 tables since     the version field of the GDEF table hasn't been incremented.     For constructed GDEF tables, we only load it if     `MarkAttachClassDef_offset' is not zero (nevertheless, a build of     a constructed mark attach table is not supported currently).       */  if ( gdef &&       gdef->MarkAttachClassDef_offset && !gdef->MarkAttachClassDef.loaded )  {    for ( i = 0; i < num_lookups; i++ )    {      if ( lo[i].LookupFlag & HB_LOOKUP_FLAG_IGNORE_SPECIAL_MARKS )      {	if ( FILE_Seek( gdef->MarkAttachClassDef_offset ) ||	     ( error = _HB_OPEN_Load_ClassDefinition( &gdef->MarkAttachClassDef,					     256, stream ) ) != HB_Err_Ok )	  goto Done;	break;      }    }  }Done:  return error;}/* END */

⌨️ 快捷键说明

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