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

📄 harfbuzz-gsub.c

📁 GTK+-2.0源码之pango-1.15.6.tar.gz
💻 C
📖 第 1 页 / 共 5 页
字号:
  (void)FILE_Seek( cur_offset );  if ( ACCESS_Frame( 2L ) )    goto Fail2;  count = as->AlternateSetCount = GET_UShort();  FORGET_Frame();  as->AlternateSet = NULL;  if ( ALLOC_ARRAY( as->AlternateSet, count, HB_AlternateSet ) )    goto Fail2;  aset = as->AlternateSet;  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_AlternateSet( &aset[n], stream ) ) != FT_Err_Ok )      goto Fail1;    (void)FILE_Seek( cur_offset );  }  return FT_Err_Ok;Fail1:  for ( m = 0; m < n; m++ )    Free_AlternateSet( &aset[m], memory );  FREE( aset );Fail2:  _HB_OPEN_Free_Coverage( &as->Coverage, memory );  return error;}static void  Free_AlternateSubst( HB_GSUB_SubTable* st,				  FT_Memory         memory ){  FT_UShort          n, count;  HB_AlternateSubst* as = &st->alternate;  HB_AlternateSet*  aset;  if ( as->AlternateSet )  {    count = as->AlternateSetCount;    aset  = as->AlternateSet;    for ( n = 0; n < count; n++ )      Free_AlternateSet( &aset[n], memory );    FREE( aset );  }  _HB_OPEN_Free_Coverage( &as->Coverage, memory );}static FT_Error  Lookup_AlternateSubst( HB_GSUBHeader*    gsub,					HB_GSUB_SubTable* st,					HB_Buffer         buffer,					FT_UShort          flags,					FT_UShort          context_length,					int                nesting_level ){  FT_Error          error;  FT_UShort         index, alt_index, property;  HB_AlternateSubst* as = &st->alternate;  HB_GDEFHeader*     gdef = gsub->gdef;  HB_AlternateSet  aset;  FT_UNUSED(nesting_level);  if ( context_length != 0xFFFF && context_length < 1 )    return HB_Err_Not_Covered;  if ( CHECK_Property( gdef, IN_CURITEM(), flags, &property ) )    return error;  error = _HB_OPEN_Coverage_Index( &as->Coverage, IN_CURGLYPH(), &index );  if ( error )    return error;  aset = as->AlternateSet[index];  /* we use a user-defined callback function to get the alternate index */  if ( gsub->altfunc )    alt_index = (gsub->altfunc)( buffer->out_pos, IN_CURGLYPH(),				 aset.GlyphCount, aset.Alternate,				 gsub->data );  else    alt_index = 0;  if ( ADD_Glyph( buffer, aset.Alternate[alt_index],		  0xFFFF, 0xFFFF ) )    return error;  if ( gdef && gdef->NewGlyphClasses )  {    /* we inherit the old glyph class to the substituted glyph */    error = _HB_GDEF_Add_Glyph_Property( gdef, aset.Alternate[alt_index],				property );    if ( error && error != HB_Err_Not_Covered )      return error;  }  return FT_Err_Ok;}/* LookupType 4 *//* Ligature */static FT_Error  Load_Ligature( HB_Ligature*  l,				FT_Stream      stream ){  FT_Error error;  FT_Memory memory = stream->memory;  FT_UShort n, count;  FT_UShort*  c;  if ( ACCESS_Frame( 4L ) )    return error;  l->LigGlyph       = GET_UShort();  l->ComponentCount = GET_UShort();  FORGET_Frame();  l->Component = NULL;  count = l->ComponentCount - 1;      /* only ComponentCount - 1 elements */  if ( ALLOC_ARRAY( l->Component, count, FT_UShort ) )    return error;  c = l->Component;  if ( ACCESS_Frame( count * 2L ) )  {    FREE( c );    return error;  }  for ( n = 0; n < count; n++ )    c[n] = GET_UShort();  FORGET_Frame();  return FT_Err_Ok;}static void  Free_Ligature( HB_Ligature*  l,			    FT_Memory      memory ){  FREE( l->Component );}/* LigatureSet */static FT_Error  Load_LigatureSet( HB_LigatureSet*  ls,				   FT_Stream         stream ){  FT_Error error;  FT_Memory memory = stream->memory;  FT_UShort      n = 0, m, count;  FT_ULong       cur_offset, new_offset, base_offset;  HB_Ligature*  l;  base_offset = FILE_Pos();  if ( ACCESS_Frame( 2L ) )    return error;  count = ls->LigatureCount = GET_UShort();  FORGET_Frame();  ls->Ligature = NULL;  if ( ALLOC_ARRAY( ls->Ligature, count, HB_Ligature ) )    return error;  l = ls->Ligature;  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_Ligature( &l[n], stream ) ) != FT_Err_Ok )      goto Fail;    (void)FILE_Seek( cur_offset );  }  return FT_Err_Ok;Fail:  for ( m = 0; m < n; m++ )    Free_Ligature( &l[m], memory );  FREE( l );  return error;}static void  Free_LigatureSet( HB_LigatureSet*  ls,			       FT_Memory         memory ){  FT_UShort      n, count;  HB_Ligature*  l;  if ( ls->Ligature )  {    count = ls->LigatureCount;    l     = ls->Ligature;    for ( n = 0; n < count; n++ )      Free_Ligature( &l[n], memory );    FREE( l );  }}/* LigatureSubstFormat1 */static FT_Error  Load_LigatureSubst( HB_GSUB_SubTable* st,				     FT_Stream         stream ){  FT_Error error;  FT_Memory memory = stream->memory;  HB_LigatureSubst*  ls = &st->ligature;  FT_UShort         n = 0, m, count;  FT_ULong          cur_offset, new_offset, base_offset;  HB_LigatureSet*  lset;  base_offset = FILE_Pos();  if ( ACCESS_Frame( 4L ) )    return error;  ls->SubstFormat = GET_UShort();             /* should be 1 */  new_offset      = GET_UShort() + base_offset;  FORGET_Frame();  cur_offset = FILE_Pos();  if ( FILE_Seek( new_offset ) ||       ( error = _HB_OPEN_Load_Coverage( &ls->Coverage, stream ) ) != FT_Err_Ok )    return error;  (void)FILE_Seek( cur_offset );  if ( ACCESS_Frame( 2L ) )    goto Fail2;  count = ls->LigatureSetCount = GET_UShort();  FORGET_Frame();  ls->LigatureSet = NULL;  if ( ALLOC_ARRAY( ls->LigatureSet, count, HB_LigatureSet ) )    goto Fail2;  lset = ls->LigatureSet;  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_LigatureSet( &lset[n], stream ) ) != FT_Err_Ok )      goto Fail1;    (void)FILE_Seek( cur_offset );  }  return FT_Err_Ok;Fail1:  for ( m = 0; m < n; m++ )    Free_LigatureSet( &lset[m], memory );  FREE( lset );Fail2:  _HB_OPEN_Free_Coverage( &ls->Coverage, memory );  return error;}static void  Free_LigatureSubst( HB_GSUB_SubTable* st,				 FT_Memory         memory ){  FT_UShort         n, count;  HB_LigatureSubst*  ls = &st->ligature;  HB_LigatureSet*  lset;  if ( ls->LigatureSet )  {    count = ls->LigatureSetCount;    lset  = ls->LigatureSet;    for ( n = 0; n < count; n++ )      Free_LigatureSet( &lset[n], memory );    FREE( lset );  }  _HB_OPEN_Free_Coverage( &ls->Coverage, memory );}static FT_Error  Lookup_LigatureSubst( HB_GSUBHeader*    gsub,				       HB_GSUB_SubTable* st,				       HB_Buffer         buffer,				       FT_UShort          flags,				       FT_UShort          context_length,				       int                nesting_level ){  FT_UShort      index, property;  FT_Error       error;  FT_UShort      numlig, i, j, is_mark, first_is_mark = FALSE;  FT_UShort*     c;  HB_LigatureSubst*  ls = &st->ligature;  HB_GDEFHeader*     gdef = gsub->gdef;  HB_Ligature*  lig;  FT_UNUSED(nesting_level);  if ( CHECK_Property( gdef, IN_CURITEM(), flags, &property ) )    return error;  if ( property == HB_GDEF_MARK || property & HB_LOOKUP_FLAG_IGNORE_SPECIAL_MARKS )    first_is_mark = TRUE;  error = _HB_OPEN_Coverage_Index( &ls->Coverage, IN_CURGLYPH(), &index );  if ( error )    return error;  if ( index >= ls->LigatureSetCount )     return HB_Err_Invalid_GSUB_SubTable;  lig = ls->LigatureSet[index].Ligature;  for ( numlig = ls->LigatureSet[index].LigatureCount;	numlig;	numlig--, lig++ )  {    if ( buffer->in_pos + lig->ComponentCount > buffer->in_length )      goto next_ligature;               /* Not enough glyphs in input */    c    = lig->Component;    is_mark = first_is_mark;    if ( context_length != 0xFFFF && context_length < lig->ComponentCount )      break;    for ( i = 1, j = buffer->in_pos + 1; i < lig->ComponentCount; i++, j++ )    {      while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )      {	if ( error && error != HB_Err_Not_Covered )	  return error;	if ( j + lig->ComponentCount - i == (FT_Long)buffer->in_length )	  goto next_ligature;	j++;      }      if ( !( property == HB_GDEF_MARK || property & HB_LOOKUP_FLAG_IGNORE_SPECIAL_MARKS ) )	is_mark = FALSE;      if ( IN_GLYPH( j ) != c[i - 1] )	goto next_ligature;    }    if ( gdef && gdef->NewGlyphClasses )    {      /* this is just a guess ... */      error = _HB_GDEF_Add_Glyph_Property( gdef, lig->LigGlyph,				  is_mark ? HB_GDEF_MARK : HB_GDEF_LIGATURE );      if ( error && error != HB_Err_Not_Covered )	return error;    }    if ( j == buffer->in_pos + i ) /* No input glyphs skipped */    {      /* We don't use a new ligature ID if there are no skipped	 glyphs and the ligature already has an ID.             */      if ( IN_LIGID( buffer->in_pos ) )      {	if ( ADD_String( buffer, i, 1, &lig->LigGlyph,			0xFFFF, 0xFFFF ) )	  return error;      }      else      {	FT_UShort ligID = hb_buffer_allocate_ligid( buffer );	if ( ADD_String( buffer, i, 1, &lig->LigGlyph,			0xFFFF, ligID ) )	  return error;      }    }    else    {      FT_UShort ligID = hb_buffer_allocate_ligid( buffer );      if ( ADD_Glyph( buffer, lig->LigGlyph,		      0xFFFF, ligID ) )	return error;      /* Now we must do a second loop to copy the skipped glyphs to	 `out' and assign component values to it.  We start with the	 glyph after the first component.  Glyphs between component	 i and i+1 belong to component i.  Together with the ligID	 value it is later possible to check whether a specific	 component value really belongs to a given ligature.         */      for ( i = 0; i < lig->ComponentCount - 1; i++ )      {	while ( CHECK_Property( gdef, IN_CURITEM(),				flags, &property ) )	  if ( ADD_Glyph( buffer, IN_CURGLYPH(),			  i, ligID ) )	    return error;	(buffer->in_pos)++;      }    }    return FT_Err_Ok;  next_ligature:    ;  }  return HB_Err_Not_Covered;}/* Do the actual substitution for a context substitution (either format   5 or 6).  This is only called after we've determined that the input   matches the subrule.                                                 */static FT_Error  Do_ContextSubst( HB_GSUBHeader*        gsub,				  FT_UShort              GlyphCount,				  FT_UShort              SubstCount,				  HB_SubstLookupRecord* subst,				  HB_Buffer             buffer,				  int                    nesting_level ){  FT_Error  error;  FT_UShort i, old_pos;  i = 0;  while ( i < GlyphCount )  {    if ( SubstCount && i == subst->SequenceIndex )    {      old_pos = buffer->in_pos;      /* Do a substitution */      error = GSUB_Do_Glyph_Lookup( gsub, subst->LookupListIndex, buffer,				    GlyphCount, nesting_level );      subst++;      SubstCount--;      i += buffer->in_pos - old_pos;      if ( error == HB_Err_Not_Covered )      {	/* XXX "can't happen" -- but don't count on it */	if ( ADD_Glyph( buffer, IN_CURGLYPH(),			0xFFFF, 0xFFFF ) )	  return error;	i++;      }      else if ( error )	return error;    }    else    {      /* No substitution for this index */      if ( ADD_Glyph( buffer, IN_CURGLYPH(),		      0xFFFF, 0xFFFF ) )	return error;      i++;    }  }  return FT_Err_Ok;}/* LookupType 5 *//* SubRule */static FT_Error  Load_SubRule( HB_SubRule*  sr,			       FT_Stream     stream ){  FT_Error error;  FT_Memory memory = stream->memory;  FT_UShort               n, count;  FT_UShort*              i;  HB_SubstLookupRecord*  slr;  if ( ACCESS_Frame( 4L ) )    return error;  sr->GlyphCount = GET_UShort();  sr->SubstCount = GET_UShort();  FORGET_Frame();  sr->Input = NULL;  count = sr->GlyphCount - 1;         /* only GlyphCount - 1 elements */  if ( ALLOC_ARRAY( sr->Input, count, FT_UShort ) )    return error;  i = sr->Input;  if ( ACCESS_Frame( count * 2L ) )    goto Fail2;  for ( n = 0; n < count; n++ )    i[n] = GET_UShort();  FORGET_Frame();  sr->SubstLookupRecord = NULL;  count = sr->SubstCount;  if ( ALLOC_ARRAY( sr->SubstLookupRecord, count, HB_SubstLookupRecord ) )    goto Fail2;  slr = sr->SubstLookupRecord;  if ( ACCESS_Frame( count * 4L ) )    goto Fail1;  for ( n = 0; n < count; n++ )  {    slr[n].SequenceIndex   = GET_UShort();    slr[n].LookupListIndex = GET_UShort();  }  FORGET_Frame();  return FT_Err_Ok;Fail1:  FREE( slr );Fail2:  FREE( i );  return error;}static void  Free_SubRule( HB_SubRule*  sr,			   FT_Memory     memory ){  FREE( sr->SubstLookupRecord );  FREE( sr->Input );}/* SubRuleSet */static FT_Error  Load_SubRuleSet( HB_SubRuleSet*  srs,				  FT_Stream        stream ){  FT_Error error;  FT_Memory memory = stream->memory;  FT_UShort     n = 0, m, count;  FT_ULong      cur_offset, new_offset, base_offset;

⌨️ 快捷键说明

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