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

📄 harfbuzz-gsub.c

📁 GTK+-2.0源码之pango-1.15.6.tar.gz
💻 C
📖 第 1 页 / 共 5 页
字号:
  HB_GDEFHeader*  gdef;  gdef = gsub->gdef;  if ( CHECK_Property( gdef, IN_CURITEM(), flags, &property ) )    return error;  error = _HB_OPEN_Coverage_Index( &csf1->Coverage, IN_CURGLYPH(), &index );  if ( error )    return error;  sr    = csf1->SubRuleSet[index].SubRule;  numsr = csf1->SubRuleSet[index].SubRuleCount;  for ( k = 0; k < numsr; k++ )  {    if ( context_length != 0xFFFF && context_length < sr[k].GlyphCount )      goto next_subrule;    if ( buffer->in_pos + sr[k].GlyphCount > buffer->in_length )      goto next_subrule;                        /* context is too long */    for ( i = 1, j = buffer->in_pos + 1; i < sr[k].GlyphCount; i++, j++ )    {      while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )      {	if ( error && error != HB_Err_Not_Covered )	  return error;	if ( j + sr[k].GlyphCount - i == (FT_Long)buffer->in_length )	  goto next_subrule;	j++;      }      if ( IN_GLYPH( j ) != sr[k].Input[i - 1] )	goto next_subrule;    }    return Do_ContextSubst( gsub, sr[k].GlyphCount,			    sr[k].SubstCount, sr[k].SubstLookupRecord,			    buffer,			    nesting_level );  next_subrule:    ;  }  return HB_Err_Not_Covered;}static FT_Error  Lookup_ContextSubst2( HB_GSUBHeader*          gsub,				       HB_ContextSubstFormat2* csf2,				       HB_Buffer               buffer,				       FT_UShort                flags,				       FT_UShort                context_length,				       int                      nesting_level ){  FT_UShort          index, property;  FT_Error           error;  FT_Memory          memory = gsub->memory;  FT_UShort          i, j, k, known_classes;  FT_UShort*         classes;  FT_UShort*         cl;  HB_SubClassSet*   scs;  HB_SubClassRule*  sr;  HB_GDEFHeader*    gdef;  gdef = gsub->gdef;  if ( CHECK_Property( gdef, IN_CURITEM(), flags, &property ) )    return error;  /* Note: The coverage table in format 2 doesn't give an index into	   anything.  It just lets us know whether or not we need to	   do any lookup at all.                                     */  error = _HB_OPEN_Coverage_Index( &csf2->Coverage, IN_CURGLYPH(), &index );  if ( error )    return error;  if ( ALLOC_ARRAY( classes, csf2->MaxContextLength, FT_UShort ) )    return error;  error = _HB_OPEN_Get_Class( &csf2->ClassDef, IN_CURGLYPH(),		     &classes[0], NULL );  if ( error && error != HB_Err_Not_Covered )    goto End;  known_classes = 0;  scs = &csf2->SubClassSet[classes[0]];  if ( !scs )  {    error = HB_Err_Invalid_GSUB_SubTable;    goto End;  }  for ( k = 0; k < scs->SubClassRuleCount; k++ )  {    sr  = &scs->SubClassRule[k];    if ( context_length != 0xFFFF && context_length < sr->GlyphCount )      goto next_subclassrule;    if ( buffer->in_pos + sr->GlyphCount > buffer->in_length )      goto next_subclassrule;                      /* context is too long */    cl   = sr->Class;    /* Start at 1 because [0] is implied */    for ( i = 1, j = buffer->in_pos + 1; i < sr->GlyphCount; i++, j++ )    {      while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )      {	if ( error && error != HB_Err_Not_Covered )	  goto End;	if ( j + sr->GlyphCount - i < (FT_Long)buffer->in_length )	  goto next_subclassrule;	j++;      }      if ( i > known_classes )      {	/* Keeps us from having to do this for each rule */	error = _HB_OPEN_Get_Class( &csf2->ClassDef, IN_GLYPH( j ), &classes[i], NULL );	if ( error && error != HB_Err_Not_Covered )	  goto End;	known_classes = i;      }      if ( cl[i - 1] != classes[i] )	goto next_subclassrule;    }    error = Do_ContextSubst( gsub, sr->GlyphCount,			     sr->SubstCount, sr->SubstLookupRecord,			     buffer,			     nesting_level );    goto End;  next_subclassrule:    ;  }  error = HB_Err_Not_Covered;End:  FREE( classes );  return error;}static FT_Error  Lookup_ContextSubst3( HB_GSUBHeader*          gsub,				       HB_ContextSubstFormat3* csf3,				       HB_Buffer               buffer,				       FT_UShort                flags,				       FT_UShort                context_length,				       int                      nesting_level ){  FT_Error         error;  FT_UShort        index, i, j, property;  HB_Coverage*    c;  HB_GDEFHeader*  gdef;  gdef = gsub->gdef;  if ( CHECK_Property( gdef, IN_CURITEM(), flags, &property ) )    return error;  if ( context_length != 0xFFFF && context_length < csf3->GlyphCount )    return HB_Err_Not_Covered;  if ( buffer->in_pos + csf3->GlyphCount > buffer->in_length )    return HB_Err_Not_Covered;         /* context is too long */  c    = csf3->Coverage;  for ( i = 1, j = buffer->in_pos + 1; i < csf3->GlyphCount; i++, j++ )  {    while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )    {      if ( error && error != HB_Err_Not_Covered )	return error;      if ( j + csf3->GlyphCount - i == (FT_Long)buffer->in_length )	return HB_Err_Not_Covered;      j++;    }    error = _HB_OPEN_Coverage_Index( &c[i], IN_GLYPH( j ), &index );    if ( error )      return error;  }  return Do_ContextSubst( gsub, csf3->GlyphCount,			  csf3->SubstCount, csf3->SubstLookupRecord,			  buffer,			  nesting_level );}static FT_Error  Lookup_ContextSubst( HB_GSUBHeader*    gsub,				      HB_GSUB_SubTable* st,				      HB_Buffer         buffer,				      FT_UShort          flags,				      FT_UShort          context_length,				      int                nesting_level ){  HB_ContextSubst*  cs = &st->context;  switch ( cs->SubstFormat )  {  case 1:    return Lookup_ContextSubst1( gsub, &cs->csf.csf1, buffer,				 flags, context_length, nesting_level );  case 2:    return Lookup_ContextSubst2( gsub, &cs->csf.csf2, buffer,				 flags, context_length, nesting_level );  case 3:    return Lookup_ContextSubst3( gsub, &cs->csf.csf3, buffer,				 flags, context_length, nesting_level );  default:    return HB_Err_Invalid_GSUB_SubTable_Format;  }  return FT_Err_Ok;               /* never reached */}/* LookupType 6 *//* ChainSubRule */static FT_Error  Load_ChainSubRule( HB_ChainSubRule*  csr,				    FT_Stream          stream ){  FT_Error error;  FT_Memory memory = stream->memory;  FT_UShort               n, count;  FT_UShort*              b;  FT_UShort*              i;  FT_UShort*              l;  HB_SubstLookupRecord*  slr;  if ( ACCESS_Frame( 2L ) )    return error;  csr->BacktrackGlyphCount = GET_UShort();  FORGET_Frame();  csr->Backtrack = NULL;  count = csr->BacktrackGlyphCount;  if ( ALLOC_ARRAY( csr->Backtrack, count, FT_UShort ) )    return error;  b = csr->Backtrack;  if ( ACCESS_Frame( count * 2L ) )    goto Fail4;  for ( n = 0; n < count; n++ )    b[n] = GET_UShort();  FORGET_Frame();  if ( ACCESS_Frame( 2L ) )    goto Fail4;  csr->InputGlyphCount = GET_UShort();  FORGET_Frame();  csr->Input = NULL;  count = csr->InputGlyphCount - 1;  /* only InputGlyphCount - 1 elements */  if ( ALLOC_ARRAY( csr->Input, count, FT_UShort ) )    goto Fail4;  i = csr->Input;  if ( ACCESS_Frame( count * 2L ) )    goto Fail3;  for ( n = 0; n < count; n++ )    i[n] = GET_UShort();  FORGET_Frame();  if ( ACCESS_Frame( 2L ) )    goto Fail3;  csr->LookaheadGlyphCount = GET_UShort();  FORGET_Frame();  csr->Lookahead = NULL;  count = csr->LookaheadGlyphCount;  if ( ALLOC_ARRAY( csr->Lookahead, count, FT_UShort ) )    goto Fail3;  l = csr->Lookahead;  if ( ACCESS_Frame( count * 2L ) )    goto Fail2;  for ( n = 0; n < count; n++ )    l[n] = GET_UShort();  FORGET_Frame();  if ( ACCESS_Frame( 2L ) )    goto Fail2;  csr->SubstCount = GET_UShort();  FORGET_Frame();  csr->SubstLookupRecord = NULL;  count = csr->SubstCount;  if ( ALLOC_ARRAY( csr->SubstLookupRecord, count, HB_SubstLookupRecord ) )    goto Fail2;  slr = csr->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( l );Fail3:  FREE( i );Fail4:  FREE( b );  return error;}static void  Free_ChainSubRule( HB_ChainSubRule*  csr,				FT_Memory          memory ){  FREE( csr->SubstLookupRecord );  FREE( csr->Lookahead );  FREE( csr->Input );  FREE( csr->Backtrack );}/* ChainSubRuleSet */static FT_Error  Load_ChainSubRuleSet( HB_ChainSubRuleSet*  csrs,				       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_ChainSubRule*  csr;  base_offset = FILE_Pos();  if ( ACCESS_Frame( 2L ) )    return error;  count = csrs->ChainSubRuleCount = GET_UShort();  FORGET_Frame();  csrs->ChainSubRule = NULL;  if ( ALLOC_ARRAY( csrs->ChainSubRule, count, HB_ChainSubRule ) )    return error;  csr = csrs->ChainSubRule;  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_ChainSubRule( &csr[n], stream ) ) != FT_Err_Ok )      goto Fail;    (void)FILE_Seek( cur_offset );  }  return FT_Err_Ok;Fail:  for ( m = 0; m < n; m++ )    Free_ChainSubRule( &csr[m], memory );  FREE( csr );  return error;}static void  Free_ChainSubRuleSet( HB_ChainSubRuleSet*  csrs,				   FT_Memory             memory ){  FT_UShort          n, count;  HB_ChainSubRule*  csr;  if ( csrs->ChainSubRule )  {    count = csrs->ChainSubRuleCount;    csr   = csrs->ChainSubRule;    for ( n = 0; n < count; n++ )      Free_ChainSubRule( &csr[n], memory );    FREE( csr );  }}/* ChainContextSubstFormat1 */static FT_Error  Load_ChainContextSubst1(		   HB_ChainContextSubstFormat1*  ccsf1,		   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_ChainSubRuleSet*  csrs;  base_offset = FILE_Pos() - 2L;  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( &ccsf1->Coverage, stream ) ) != FT_Err_Ok )    return error;  (void)FILE_Seek( cur_offset );  if ( ACCESS_Frame( 2L ) )    goto Fail2;  count = ccsf1->ChainSubRuleSetCount = GET_UShort();  FORGET_Frame();  ccsf1->ChainSubRuleSet = NULL;  if ( ALLOC_ARRAY( ccsf1->ChainSubRuleSet, count, HB_ChainSubRuleSet ) )    goto Fail2;  csrs = ccsf1->ChainSubRuleSet;  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_ChainSubRuleSet( &csrs[n], stream ) ) != FT_Err_Ok )      goto Fail1;    (void)FILE_Seek( cur_offset );  }  return FT_Err_Ok;Fail1:  for ( m = 0; m < n; m++ )    Free_ChainSubRuleSet( &csrs[m], memory );  FREE( csrs );Fail2:  _HB_OPEN_Free_Coverage( &ccsf1->Coverage, memory );  return error;}static void  Free_ChainContextSubst1( HB_ChainContextSubstFormat1*  ccsf1,				 FT_Memory                      memory ){  FT_UShort             n, count;  HB_ChainSubRuleSet*  csrs;  if ( ccsf1->ChainSubRuleSet )  {    count = ccsf1->ChainSubRuleSetCount;    csrs  = ccsf1->ChainSubRuleSet;    for ( n = 0; n < count; n++ )      Free_ChainSubRuleSet( &csrs[n], memory );    FREE( csrs );  }  _HB_OPEN_Free_Coverage( &ccsf1->Coverage, memory );}/* ChainSubClassRule */static FT_Error  Load_ChainSubClassRule(		   HB_ChainContextSubstFormat2*  ccsf2,		   HB_ChainSubClassRule*         cscr,		   FT_Stream                      stream ){  FT_Error error;  FT_Memory memory = stream->memory;  FT_UShort               n, count;  FT_UShort*              b;  FT_UShort*              i;  FT_UShort*              l;  HB_SubstLookupRecord*  slr;  FT_Bool*                d;  if ( ACCESS_Frame( 2L ) )    return error;  cscr->BacktrackGlyphCount = GET_UShort();  FORGET_Frame();  if ( cscr->BacktrackGlyphCount > ccsf2->MaxBacktrackLength )    ccsf2->MaxBacktrackLength = cscr->BacktrackGlyphCount;  cscr->Backtrack = NULL;  count = cscr->BacktrackGlyphCount;  if ( ALLOC_ARRAY( cscr->Backtrack, count, FT_UShort ) )    return error;  b = cscr->Backtrack;  d = ccsf2->BacktrackClassDef.Defined;  if ( ACCESS_Frame( count * 2L ) )    goto Fail4;  for ( n = 0; n < count; n++ )  {    b[n] = GET_UShort();    /* We check whether the specific class is used at all.  If not,       class 0 is used instead.                                     */    if ( !d[b[n]] )      b[n] = 0;  }  FORGET_Frame();  if ( ACCESS_Frame( 2L ) )    goto Fail4;  cscr->InputGlyphCount = GET_UShort();  FORGET_Frame();  if ( cscr->InputGlyphCount > ccsf2->MaxInputLength )    ccsf2->MaxInputLength = cscr->InputGlyphCount;  cscr->Input = NULL;  count = cscr->InputGlyphCount - 1; /* only InputGlyphCount - 1 elements */  if ( ALLOC_ARRAY( cscr->Input, count, FT_UShort ) )    goto Fail4;  i = cscr->Input;  d = ccsf2->InputClassDef.Defined;  if ( ACCESS_Frame( count * 2L ) )

⌨️ 快捷键说明

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