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

📄 harfbuzz-gsub.c

📁 Pango is a library for layout and rendering of text, with an emphasis on internationalization. Pang
💻 C
📖 第 1 页 / 共 5 页
字号:
}static void  Free_ChainSubClassRule( HB_ChainSubClassRule*  cscr ){  FREE( cscr->SubstLookupRecord );  FREE( cscr->Lookahead );  FREE( cscr->Input );  FREE( cscr->Backtrack );}/* SubClassSet */static HB_Error  Load_ChainSubClassSet(		   HB_ChainContextSubstFormat2*  ccsf2,		   HB_ChainSubClassSet*          cscs,		   HB_Stream                      stream ){  HB_Error error;  HB_UShort               n = 0, m, count;  HB_UInt                cur_offset, new_offset, base_offset;  HB_ChainSubClassRule*  cscr;  base_offset = FILE_Pos();  if ( ACCESS_Frame( 2L ) )    return error;  count = cscs->ChainSubClassRuleCount = GET_UShort();  FORGET_Frame();  cscs->ChainSubClassRule = NULL;  if ( ALLOC_ARRAY( cscs->ChainSubClassRule, count,		    HB_ChainSubClassRule ) )    return error;  cscr = cscs->ChainSubClassRule;  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_ChainSubClassRule( ccsf2, &cscr[n],					   stream ) ) != HB_Err_Ok )      goto Fail;    (void)FILE_Seek( cur_offset );  }  return HB_Err_Ok;Fail:  for ( m = 0; m < n; m++ )    Free_ChainSubClassRule( &cscr[m] );  FREE( cscr );  return error;}static void  Free_ChainSubClassSet( HB_ChainSubClassSet*  cscs ){  HB_UShort               n, count;  HB_ChainSubClassRule*  cscr;  if ( cscs->ChainSubClassRule )  {    count = cscs->ChainSubClassRuleCount;    cscr  = cscs->ChainSubClassRule;    for ( n = 0; n < count; n++ )      Free_ChainSubClassRule( &cscr[n] );    FREE( cscr );  }}/* ChainContextSubstFormat2 */static HB_Error  Load_ChainContextSubst2(		   HB_ChainContextSubstFormat2*  ccsf2,		   HB_Stream                      stream ){  HB_Error error;  HB_UShort              n = 0, m, count;  HB_UInt               cur_offset, new_offset, base_offset;  HB_UInt               backtrack_offset, input_offset, lookahead_offset;  HB_ChainSubClassSet*  cscs;  base_offset = FILE_Pos() - 2;  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( &ccsf2->Coverage, stream ) ) != HB_Err_Ok )    return error;  (void)FILE_Seek( cur_offset );  if ( ACCESS_Frame( 8L ) )    goto Fail5;  backtrack_offset = GET_UShort();  input_offset     = GET_UShort();  lookahead_offset = GET_UShort();  /* `ChainSubClassSetCount' is the upper limit for input class values,     thus we read it now to make an additional safety check. No limit     is known or needed for the other two class definitions          */  count = ccsf2->ChainSubClassSetCount = GET_UShort();  FORGET_Frame();  if ( ( error = _HB_OPEN_Load_EmptyOrClassDefinition( &ccsf2->BacktrackClassDef, 65535,						       backtrack_offset, base_offset,						       stream ) ) != HB_Err_Ok )      goto Fail5;  if ( ( error = _HB_OPEN_Load_EmptyOrClassDefinition( &ccsf2->InputClassDef, count,						       input_offset, base_offset,						       stream ) ) != HB_Err_Ok )      goto Fail4;  if ( ( error = _HB_OPEN_Load_EmptyOrClassDefinition( &ccsf2->LookaheadClassDef, 65535,						       lookahead_offset, base_offset,						       stream ) ) != HB_Err_Ok )    goto Fail3;  ccsf2->ChainSubClassSet   = NULL;  ccsf2->MaxBacktrackLength = 0;  ccsf2->MaxInputLength     = 0;  ccsf2->MaxLookaheadLength = 0;  if ( ALLOC_ARRAY( ccsf2->ChainSubClassSet, count, HB_ChainSubClassSet ) )    goto Fail2;  cscs = ccsf2->ChainSubClassSet;  for ( n = 0; n < count; n++ )  {    if ( ACCESS_Frame( 2L ) )      goto Fail1;    new_offset = GET_UShort() + base_offset;    FORGET_Frame();    if ( new_offset != base_offset )      /* not a NULL offset */    {      cur_offset = FILE_Pos();      if ( FILE_Seek( new_offset ) ||	   ( error = Load_ChainSubClassSet( ccsf2, &cscs[n],					    stream ) ) != HB_Err_Ok )	goto Fail1;      (void)FILE_Seek( cur_offset );    }    else    {      /* we create a ChainSubClassSet table with no entries */      ccsf2->ChainSubClassSet[n].ChainSubClassRuleCount = 0;      ccsf2->ChainSubClassSet[n].ChainSubClassRule      = NULL;    }  }  return HB_Err_Ok;Fail1:  for ( m = 0; m < n; m++ )    Free_ChainSubClassSet( &cscs[m] );  FREE( cscs );Fail2:  _HB_OPEN_Free_ClassDefinition( &ccsf2->LookaheadClassDef );Fail3:  _HB_OPEN_Free_ClassDefinition( &ccsf2->InputClassDef );Fail4:  _HB_OPEN_Free_ClassDefinition( &ccsf2->BacktrackClassDef );Fail5:  _HB_OPEN_Free_Coverage( &ccsf2->Coverage );  return error;}static void  Free_ChainContextSubst2( HB_ChainContextSubstFormat2*  ccsf2 ){  HB_UShort              n, count;  HB_ChainSubClassSet*  cscs;  if ( ccsf2->ChainSubClassSet )  {    count = ccsf2->ChainSubClassSetCount;    cscs  = ccsf2->ChainSubClassSet;    for ( n = 0; n < count; n++ )      Free_ChainSubClassSet( &cscs[n] );    FREE( cscs );  }  _HB_OPEN_Free_ClassDefinition( &ccsf2->LookaheadClassDef );  _HB_OPEN_Free_ClassDefinition( &ccsf2->InputClassDef );  _HB_OPEN_Free_ClassDefinition( &ccsf2->BacktrackClassDef );  _HB_OPEN_Free_Coverage( &ccsf2->Coverage );}/* ChainContextSubstFormat3 */static HB_Error  Load_ChainContextSubst3(		   HB_ChainContextSubstFormat3*  ccsf3,		   HB_Stream                      stream ){  HB_Error error;  HB_UShort               n, nb = 0, ni =0, nl = 0, m, count;  HB_UShort               backtrack_count, input_count, lookahead_count;  HB_UInt                cur_offset, new_offset, base_offset;  HB_Coverage*           b;  HB_Coverage*           i;  HB_Coverage*           l;  HB_SubstLookupRecord*  slr;  base_offset = FILE_Pos() - 2L;  if ( ACCESS_Frame( 2L ) )    return error;  ccsf3->BacktrackGlyphCount = GET_UShort();  FORGET_Frame();  ccsf3->BacktrackCoverage = NULL;  backtrack_count = ccsf3->BacktrackGlyphCount;  if ( ALLOC_ARRAY( ccsf3->BacktrackCoverage, backtrack_count,		    HB_Coverage ) )    return error;  b = ccsf3->BacktrackCoverage;  for ( nb = 0; nb < backtrack_count; nb++ )  {    if ( ACCESS_Frame( 2L ) )      goto Fail4;    new_offset = GET_UShort() + base_offset;    FORGET_Frame();    cur_offset = FILE_Pos();    if ( FILE_Seek( new_offset ) ||	 ( error = _HB_OPEN_Load_Coverage( &b[nb], stream ) ) != HB_Err_Ok )      goto Fail4;    (void)FILE_Seek( cur_offset );  }  if ( ACCESS_Frame( 2L ) )    goto Fail4;  ccsf3->InputGlyphCount = GET_UShort();  FORGET_Frame();  ccsf3->InputCoverage = NULL;  input_count = ccsf3->InputGlyphCount;  if ( ALLOC_ARRAY( ccsf3->InputCoverage, input_count, HB_Coverage ) )    goto Fail4;  i = ccsf3->InputCoverage;  for ( ni = 0; ni < input_count; ni++ )  {    if ( ACCESS_Frame( 2L ) )      goto Fail3;    new_offset = GET_UShort() + base_offset;    FORGET_Frame();    cur_offset = FILE_Pos();    if ( FILE_Seek( new_offset ) ||	 ( error = _HB_OPEN_Load_Coverage( &i[ni], stream ) ) != HB_Err_Ok )      goto Fail3;    (void)FILE_Seek( cur_offset );  }  if ( ACCESS_Frame( 2L ) )    goto Fail3;  ccsf3->LookaheadGlyphCount = GET_UShort();  FORGET_Frame();  ccsf3->LookaheadCoverage = NULL;  lookahead_count = ccsf3->LookaheadGlyphCount;  if ( ALLOC_ARRAY( ccsf3->LookaheadCoverage, lookahead_count,		    HB_Coverage ) )    goto Fail3;  l = ccsf3->LookaheadCoverage;  for ( nl = 0; nl < lookahead_count; nl++ )  {    if ( ACCESS_Frame( 2L ) )      goto Fail2;    new_offset = GET_UShort() + base_offset;    FORGET_Frame();    cur_offset = FILE_Pos();    if ( FILE_Seek( new_offset ) ||	 ( error = _HB_OPEN_Load_Coverage( &l[nl], stream ) ) != HB_Err_Ok )      goto Fail2;    (void)FILE_Seek( cur_offset );  }  if ( ACCESS_Frame( 2L ) )    goto Fail2;  ccsf3->SubstCount = GET_UShort();  FORGET_Frame();  ccsf3->SubstLookupRecord = NULL;  count = ccsf3->SubstCount;  if ( ALLOC_ARRAY( ccsf3->SubstLookupRecord, count,		    HB_SubstLookupRecord ) )    goto Fail2;  slr = ccsf3->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:  for ( m = 0; m < nl; m++ )    _HB_OPEN_Free_Coverage( &l[m] );  FREE( l );Fail3:  for ( m = 0; m < ni; m++ )    _HB_OPEN_Free_Coverage( &i[m] );  FREE( i );Fail4:  for ( m = 0; m < nb; m++ )    _HB_OPEN_Free_Coverage( &b[m] );  FREE( b );  return error;}static void  Free_ChainContextSubst3( HB_ChainContextSubstFormat3*  ccsf3 ){  HB_UShort      n, count;  HB_Coverage*  c;  FREE( ccsf3->SubstLookupRecord );  if ( ccsf3->LookaheadCoverage )  {    count = ccsf3->LookaheadGlyphCount;    c     = ccsf3->LookaheadCoverage;    for ( n = 0; n < count; n++ )      _HB_OPEN_Free_Coverage( &c[n] );    FREE( c );  }  if ( ccsf3->InputCoverage )  {    count = ccsf3->InputGlyphCount;    c     = ccsf3->InputCoverage;    for ( n = 0; n < count; n++ )      _HB_OPEN_Free_Coverage( &c[n] );    FREE( c );  }  if ( ccsf3->BacktrackCoverage )  {    count = ccsf3->BacktrackGlyphCount;    c     = ccsf3->BacktrackCoverage;    for ( n = 0; n < count; n++ )      _HB_OPEN_Free_Coverage( &c[n] );    FREE( c );  }}/* ChainContextSubst */static HB_Error  Load_ChainContextSubst( HB_GSUB_SubTable* st,					 HB_Stream         stream ){  HB_Error error;  HB_ChainContextSubst*  ccs = &st->chain;  if ( ACCESS_Frame( 2L ) )    return error;  ccs->SubstFormat = GET_UShort();  FORGET_Frame();  switch ( ccs->SubstFormat ) {    case 1:  return Load_ChainContextSubst1( &ccs->ccsf.ccsf1, stream );    case 2:  return Load_ChainContextSubst2( &ccs->ccsf.ccsf2, stream );    case 3:  return Load_ChainContextSubst3( &ccs->ccsf.ccsf3, stream );    default: return ERR(HB_Err_Invalid_SubTable_Format);  }  return HB_Err_Ok;               /* never reached */}static void  Free_ChainContextSubst( HB_GSUB_SubTable* st ){  HB_ChainContextSubst*  ccs = &st->chain;  switch ( ccs->SubstFormat ) {    case 1:  Free_ChainContextSubst1( &ccs->ccsf.ccsf1 ); break;    case 2:  Free_ChainContextSubst2( &ccs->ccsf.ccsf2 ); break;    case 3:  Free_ChainContextSubst3( &ccs->ccsf.ccsf3 ); break;    default:							  break;  }}static HB_Error  Lookup_ChainContextSubst1( HB_GSUBHeader*               gsub,					    HB_ChainContextSubstFormat1* ccsf1,					    HB_Buffer                    buffer,					    HB_UShort                     flags,					    HB_UShort                     context_length,					    int                           nesting_level ){  HB_UShort          index, property;  HB_UShort          i, j, k, num_csr;  HB_UShort          bgc, igc, lgc;  HB_Error           error;  HB_ChainSubRule*  csr;  HB_ChainSubRule   curr_csr;  HB_GDEFHeader*    gdef;  gdef = gsub->gdef;  if ( CHECK_Property( gdef, IN_CURITEM(), flags, &property ) )    return error;  error = _HB_OPEN_Coverage_Index( &ccsf1->Coverage, IN_CURGLYPH(), &index );  if ( error )    return error;  csr     = ccsf1->ChainSubRuleSet[index].ChainSubRule;  num_csr = ccsf1->ChainSubRuleSet[index].ChainSubRuleCount;  for ( k = 0; k < num_csr; k++ )  {    curr_csr = csr[k];    bgc      = curr_csr.BacktrackGlyphCount;    igc      = curr_csr.InputGlyphCount;    lgc      = curr_csr.LookaheadGlyphCount;    if ( context_length != 0xFFFF && context_length < igc )      goto next_chainsubrule;    /* check whether context is too long; it is a first guess only */    if ( bgc > buffer->out_pos || buffer->in_pos + igc + lgc > buffer->in_length )      goto next_chainsubrule;    if ( bgc )    {      /* since we don't know in advance the number of glyphs to inspect,	 we search backwards for matches in the backtrack glyph array    */      for ( i = 0, j = buffer->out_pos - 1; i < bgc; i++, j-- )      {	while ( CHECK_Property( gdef, OUT_ITEM( j ), flags, &property ) )	{	  if ( error && error != HB_Err_Not_Covered )	    return error;	  if ( j + 1 == bgc - i )	    goto next_chainsubrule;	  j--;	}	/* In OpenType 1.3, it is undefined whether the offsets of	   backtrack glyphs is in logical order or not.  Version 1.4	   will clarify this:	     Logical order -      a  b  c  d  e  f  g  h  i  j					      i	     Input offsets -                  0  1	     Backtrack offsets -  3  2  1  0	     Lookahead offsets -                    0  1  2  3           */	if ( OUT_GLYPH( j ) != curr_csr.Backtrack[i] )	  goto next_chainsubrule;      }    }    /* Start at 1 because [0] is implied */    for ( i = 1, j = buffer->in_pos + 1; i < igc; i++, j++ )    {      while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )      {	if ( error && error != HB_Err_Not_Covered )	  return error;	if ( j + igc - i + lgc == (HB_Int)buffer->in_length )	  goto next_chainsubrule;	j++;      }      if ( IN_GLYPH( j ) != curr_csr.Input[i - 1] )	  goto next_chainsubrule;    }    /* we are starting to check for lookahead glyphs right after the       last context glyph                                            */    for ( i = 0; i < lgc; i++, j++ )    {      while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )      {	if ( error && error != HB_Err_Not_Covered )	  return error;	if ( j + lgc - i == (HB_Int)buffer->in_length )	  goto next_chainsubrule;	j++;      }      if ( IN_GLYPH( j ) != curr_csr.Lookahead[i] )	goto next_chainsubrule;    }    return Do_ContextSubst( gsub, igc,			    curr_csr.SubstCount,			    curr_csr.SubstLookupRecord,			    buffer,			    nesting_level );  next_chainsubrule:    ;  }  return HB_Err_Not_Covered;}static HB_Error  Lookup_ChainContextSubst2( HB_GSUBHeader*               gsub,					    HB_ChainContextSubstFormat2* ccsf2,					    HB_Buffer                    buffer,					    HB_UShort                     flags,					    HB_UShort                     context_length,					    int                           nesting_level ){  HB_UShort              index, property;  HB_Error               error;  HB_UShort              i, j, k; 

⌨️ 快捷键说明

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