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

📄 harfbuzz-gsub.c

📁 Pango is a library for layout and rendering of text, with an emphasis on internationalization. Pang
💻 C
📖 第 1 页 / 共 5 页
字号:
  for ( m = 0; m < n; m++ )    Free_AlternateSet( &aset[m] );  FREE( aset );Fail2:  _HB_OPEN_Free_Coverage( &as->Coverage );  return error;}static void  Free_AlternateSubst( HB_GSUB_SubTable* st ){  HB_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] );    FREE( aset );  }  _HB_OPEN_Free_Coverage( &as->Coverage );}static HB_Error  Lookup_AlternateSubst( HB_GSUBHeader*    gsub,					HB_GSUB_SubTable* st,					HB_Buffer         buffer,					HB_UShort          flags,					HB_UShort          context_length,					int                nesting_level ){  HB_Error          error;  HB_UShort         index, value, alt_index, property;  HB_AlternateSubst* as = &st->alternate;  HB_GDEFHeader*     gdef = gsub->gdef;  HB_AlternateSet  aset;  HB_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;  value = aset.Alternate[alt_index];  if ( REPLACE_Glyph( buffer, value, nesting_level ) )    return error;  if ( gdef && gdef->NewGlyphClasses )  {    /* we inherit the old glyph class to the substituted glyph */    error = _HB_GDEF_Add_Glyph_Property( gdef, value, property );    if ( error && error != HB_Err_Not_Covered )      return error;  }  return HB_Err_Ok;}/* LookupType 4 *//* Ligature */static HB_Error  Load_Ligature( HB_Ligature*  l,				HB_Stream      stream ){  HB_Error error;  HB_UShort n, count;  HB_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, HB_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 HB_Err_Ok;}static void  Free_Ligature( HB_Ligature*  l ){  FREE( l->Component );}/* LigatureSet */static HB_Error  Load_LigatureSet( HB_LigatureSet*  ls,				   HB_Stream         stream ){  HB_Error error;  HB_UShort      n = 0, m, count;  HB_UInt       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 ) ) != HB_Err_Ok )      goto Fail;    (void)FILE_Seek( cur_offset );  }  return HB_Err_Ok;Fail:  for ( m = 0; m < n; m++ )    Free_Ligature( &l[m] );  FREE( l );  return error;}static void  Free_LigatureSet( HB_LigatureSet*  ls ){  HB_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] );    FREE( l );  }}/* LigatureSubstFormat1 */static HB_Error  Load_LigatureSubst( HB_GSUB_SubTable* st,				     HB_Stream         stream ){  HB_Error error;  HB_LigatureSubst*  ls = &st->ligature;  HB_UShort         n = 0, m, count;  HB_UInt          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 ) ) != HB_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 ) ) != HB_Err_Ok )      goto Fail1;    (void)FILE_Seek( cur_offset );  }  return HB_Err_Ok;Fail1:  for ( m = 0; m < n; m++ )    Free_LigatureSet( &lset[m] );  FREE( lset );Fail2:  _HB_OPEN_Free_Coverage( &ls->Coverage );  return error;}static void  Free_LigatureSubst( HB_GSUB_SubTable* st ){  HB_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] );    FREE( lset );  }  _HB_OPEN_Free_Coverage( &ls->Coverage );}static HB_Error  Lookup_LigatureSubst( HB_GSUBHeader*    gsub,				       HB_GSUB_SubTable* st,				       HB_Buffer         buffer,				       HB_UShort          flags,				       HB_UShort          context_length,				       int                nesting_level ){  HB_UShort      index, property;  HB_Error       error;  HB_UShort      numlig, i, j, is_mark, first_is_mark = FALSE;  HB_UShort*     c;  HB_LigatureSubst*  ls = &st->ligature;  HB_GDEFHeader*     gdef = gsub->gdef;  HB_Ligature*  lig;  HB_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 ERR(HB_Err_Invalid_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 == (HB_Int)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      {	HB_UShort ligID = _hb_buffer_allocate_ligid( buffer );	if ( ADD_String( buffer, i, 1, &lig->LigGlyph,			0xFFFF, ligID ) )	  return error;      }    }    else    {      HB_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 HB_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 HB_Error  Do_ContextSubst( HB_GSUBHeader*        gsub,				  HB_UShort              GlyphCount,				  HB_UShort              SubstCount,				  HB_SubstLookupRecord* subst,				  HB_Buffer             buffer,				  int                    nesting_level ){  HB_Error  error;  HB_UInt 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 )      {	if ( COPY_Glyph( buffer ) )	  return error;	i++;      }      else if ( error )	return error;    }    else    {      /* No substitution for this index */      if ( COPY_Glyph( buffer ) )	return error;      i++;    }  }  return HB_Err_Ok;}/* LookupType 5 *//* SubRule */static HB_Error  Load_SubRule( HB_SubRule*  sr,			       HB_Stream     stream ){  HB_Error error;  HB_UShort               n, count;  HB_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, HB_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 HB_Err_Ok;Fail1:  FREE( slr );Fail2:  FREE( i );  return error;}static void  Free_SubRule( HB_SubRule*  sr ){  FREE( sr->SubstLookupRecord );  FREE( sr->Input );}/* SubRuleSet */static HB_Error  Load_SubRuleSet( HB_SubRuleSet*  srs,				  HB_Stream        stream ){  HB_Error error;  HB_UShort     n = 0, m, count;  HB_UInt      cur_offset, new_offset, base_offset;  HB_SubRule*  sr;  base_offset = FILE_Pos();  if ( ACCESS_Frame( 2L ) )    return error;  count = srs->SubRuleCount = GET_UShort();  FORGET_Frame();  srs->SubRule = NULL;  if ( ALLOC_ARRAY( srs->SubRule, count, HB_SubRule ) )    return error;  sr = srs->SubRule;  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_SubRule( &sr[n], stream ) ) != HB_Err_Ok )      goto Fail;    (void)FILE_Seek( cur_offset );  }  return HB_Err_Ok;Fail:  for ( m = 0; m < n; m++ )    Free_SubRule( &sr[m] );  FREE( sr );  return error;}static void  Free_SubRuleSet( HB_SubRuleSet*  srs ){  HB_UShort     n, count;

⌨️ 快捷键说明

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