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

📄 harfbuzz-gsub.c

📁 Pango is a library for layout and rendering of text, with an emphasis on internationalization. Pang
💻 C
📖 第 1 页 / 共 5 页
字号:
  HB_SubRule*  sr;  if ( srs->SubRule )  {    count = srs->SubRuleCount;    sr    = srs->SubRule;    for ( n = 0; n < count; n++ )      Free_SubRule( &sr[n] );    FREE( sr );  }}/* ContextSubstFormat1 */static HB_Error  Load_ContextSubst1( HB_ContextSubstFormat1*  csf1,				     HB_Stream                 stream ){  HB_Error error;  HB_UShort        n = 0, m, count;  HB_UInt         cur_offset, new_offset, base_offset;  HB_SubRuleSet*  srs;  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( &csf1->Coverage, stream ) ) != HB_Err_Ok )    return error;  (void)FILE_Seek( cur_offset );  if ( ACCESS_Frame( 2L ) )    goto Fail2;  count = csf1->SubRuleSetCount = GET_UShort();  FORGET_Frame();  csf1->SubRuleSet = NULL;  if ( ALLOC_ARRAY( csf1->SubRuleSet, count, HB_SubRuleSet ) )    goto Fail2;  srs = csf1->SubRuleSet;  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_SubRuleSet( &srs[n], stream ) ) != HB_Err_Ok )      goto Fail1;    (void)FILE_Seek( cur_offset );  }  return HB_Err_Ok;Fail1:  for ( m = 0; m < n; m++ )    Free_SubRuleSet( &srs[m] );  FREE( srs );Fail2:  _HB_OPEN_Free_Coverage( &csf1->Coverage );  return error;}static void  Free_ContextSubst1( HB_ContextSubstFormat1* csf1 ){  HB_UShort        n, count;  HB_SubRuleSet*  srs;  if ( csf1->SubRuleSet )  {    count = csf1->SubRuleSetCount;    srs   = csf1->SubRuleSet;    for ( n = 0; n < count; n++ )      Free_SubRuleSet( &srs[n] );    FREE( srs );  }  _HB_OPEN_Free_Coverage( &csf1->Coverage );}/* SubClassRule */static HB_Error  Load_SubClassRule( HB_ContextSubstFormat2*  csf2,				    HB_SubClassRule*         scr,				    HB_Stream                 stream ){  HB_Error error;  HB_UShort               n, count;  HB_UShort*              c;  HB_SubstLookupRecord*  slr;  HB_Bool*                d;  if ( ACCESS_Frame( 4L ) )    return error;  scr->GlyphCount = GET_UShort();  scr->SubstCount = GET_UShort();  if ( scr->GlyphCount > csf2->MaxContextLength )    csf2->MaxContextLength = scr->GlyphCount;  FORGET_Frame();  scr->Class = NULL;  count = scr->GlyphCount - 1;        /* only GlyphCount - 1 elements */  if ( ALLOC_ARRAY( scr->Class, count, HB_UShort ) )    return error;  c = scr->Class;  d = csf2->ClassDef.Defined;  if ( ACCESS_Frame( count * 2L ) )    goto Fail2;  for ( n = 0; n < count; n++ )  {    c[n] = GET_UShort();    /* We check whether the specific class is used at all.  If not,       class 0 is used instead.                                     */    if ( !d[c[n]] )      c[n] = 0;  }  FORGET_Frame();  scr->SubstLookupRecord = NULL;  count = scr->SubstCount;  if ( ALLOC_ARRAY( scr->SubstLookupRecord, count, HB_SubstLookupRecord ) )    goto Fail2;  slr = scr->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( c );  return error;}static void  Free_SubClassRule( HB_SubClassRule*  scr ){  FREE( scr->SubstLookupRecord );  FREE( scr->Class );}/* SubClassSet */static HB_Error  Load_SubClassSet( HB_ContextSubstFormat2*  csf2,				   HB_SubClassSet*          scs,				   HB_Stream                 stream ){  HB_Error error;  HB_UShort          n = 0, m, count;  HB_UInt           cur_offset, new_offset, base_offset;  HB_SubClassRule*  scr;  base_offset = FILE_Pos();  if ( ACCESS_Frame( 2L ) )    return error;  count = scs->SubClassRuleCount = GET_UShort();  FORGET_Frame();  scs->SubClassRule = NULL;  if ( ALLOC_ARRAY( scs->SubClassRule, count, HB_SubClassRule ) )    return error;  scr = scs->SubClassRule;  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_SubClassRule( csf2, &scr[n],				      stream ) ) != HB_Err_Ok )      goto Fail;    (void)FILE_Seek( cur_offset );  }  return HB_Err_Ok;Fail:  for ( m = 0; m < n; m++ )    Free_SubClassRule( &scr[m] );  FREE( scr );  return error;}static void  Free_SubClassSet( HB_SubClassSet*  scs ){  HB_UShort          n, count;  HB_SubClassRule*  scr;  if ( scs->SubClassRule )  {    count = scs->SubClassRuleCount;    scr   = scs->SubClassRule;    for ( n = 0; n < count; n++ )      Free_SubClassRule( &scr[n] );    FREE( scr );  }}/* ContextSubstFormat2 */static HB_Error  Load_ContextSubst2( HB_ContextSubstFormat2*  csf2,				     HB_Stream                 stream ){  HB_Error error;  HB_UShort         n = 0, m, count;  HB_UInt          cur_offset, new_offset, base_offset;  HB_SubClassSet*  scs;  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( &csf2->Coverage, stream ) ) != HB_Err_Ok )    return error;  (void)FILE_Seek( cur_offset );  if ( ACCESS_Frame( 4L ) )    goto Fail3;  new_offset = GET_UShort() + base_offset;  /* `SubClassSetCount' is the upper limit for class values, thus we     read it now to make an additional safety check.                 */  count = csf2->SubClassSetCount = GET_UShort();  FORGET_Frame();  cur_offset = FILE_Pos();  if ( FILE_Seek( new_offset ) ||       ( error = _HB_OPEN_Load_ClassDefinition( &csf2->ClassDef, count,				       stream ) ) != HB_Err_Ok )    goto Fail3;  (void)FILE_Seek( cur_offset );  csf2->SubClassSet      = NULL;  csf2->MaxContextLength = 0;  if ( ALLOC_ARRAY( csf2->SubClassSet, count, HB_SubClassSet ) )    goto Fail2;  scs = csf2->SubClassSet;  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_SubClassSet( csf2, &scs[n],				       stream ) ) != HB_Err_Ok )	goto Fail1;      (void)FILE_Seek( cur_offset );    }    else    {      /* we create a SubClassSet table with no entries */      csf2->SubClassSet[n].SubClassRuleCount = 0;      csf2->SubClassSet[n].SubClassRule      = NULL;    }  }  return HB_Err_Ok;Fail1:  for ( m = 0; m < n; m++ )    Free_SubClassSet( &scs[m] );  FREE( scs );Fail2:  _HB_OPEN_Free_ClassDefinition( &csf2->ClassDef );Fail3:  _HB_OPEN_Free_Coverage( &csf2->Coverage );  return error;}static void  Free_ContextSubst2( HB_ContextSubstFormat2*  csf2 ){  HB_UShort         n, count;  HB_SubClassSet*  scs;  if ( csf2->SubClassSet )  {    count = csf2->SubClassSetCount;    scs   = csf2->SubClassSet;    for ( n = 0; n < count; n++ )      Free_SubClassSet( &scs[n] );    FREE( scs );  }  _HB_OPEN_Free_ClassDefinition( &csf2->ClassDef );  _HB_OPEN_Free_Coverage( &csf2->Coverage );}/* ContextSubstFormat3 */static HB_Error  Load_ContextSubst3( HB_ContextSubstFormat3*  csf3,				     HB_Stream                 stream ){  HB_Error error;  HB_UShort               n = 0, m, count;  HB_UInt                cur_offset, new_offset, base_offset;  HB_Coverage*           c;  HB_SubstLookupRecord*  slr;  base_offset = FILE_Pos() - 2L;  if ( ACCESS_Frame( 4L ) )    return error;  csf3->GlyphCount = GET_UShort();  csf3->SubstCount = GET_UShort();  FORGET_Frame();  csf3->Coverage = NULL;  count = csf3->GlyphCount;  if ( ALLOC_ARRAY( csf3->Coverage, count, HB_Coverage ) )    return error;  c = csf3->Coverage;  for ( n = 0; n < count; n++ )  {    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( &c[n], stream ) ) != HB_Err_Ok )      goto Fail2;    (void)FILE_Seek( cur_offset );  }  csf3->SubstLookupRecord = NULL;  count = csf3->SubstCount;  if ( ALLOC_ARRAY( csf3->SubstLookupRecord, count,		    HB_SubstLookupRecord ) )    goto Fail2;  slr = csf3->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 < n; m++ )    _HB_OPEN_Free_Coverage( &c[m] );  FREE( c );  return error;}static void  Free_ContextSubst3( HB_ContextSubstFormat3*  csf3 ){  HB_UShort      n, count;  HB_Coverage*  c;  FREE( csf3->SubstLookupRecord );  if ( csf3->Coverage )  {    count = csf3->GlyphCount;    c     = csf3->Coverage;    for ( n = 0; n < count; n++ )      _HB_OPEN_Free_Coverage( &c[n] );    FREE( c );  }}/* ContextSubst */static HB_Error  Load_ContextSubst( HB_GSUB_SubTable* st,				    HB_Stream         stream ){  HB_Error error;  HB_ContextSubst*  cs = &st->context;  if ( ACCESS_Frame( 2L ) )    return error;  cs->SubstFormat = GET_UShort();  FORGET_Frame();  switch ( cs->SubstFormat )  {  case 1:  return Load_ContextSubst1( &cs->csf.csf1, stream );  case 2:  return Load_ContextSubst2( &cs->csf.csf2, stream );  case 3:  return Load_ContextSubst3( &cs->csf.csf3, stream );  default: return ERR(HB_Err_Invalid_SubTable_Format);  }  return HB_Err_Ok;               /* never reached */}static void  Free_ContextSubst( HB_GSUB_SubTable* st ){  HB_ContextSubst*  cs = &st->context;  switch ( cs->SubstFormat )  {  case 1:  Free_ContextSubst1( &cs->csf.csf1 ); break;  case 2:  Free_ContextSubst2( &cs->csf.csf2 ); break;  case 3:  Free_ContextSubst3( &cs->csf.csf3 ); break;  default:						break;  }}static HB_Error  Lookup_ContextSubst1( HB_GSUBHeader*          gsub,				       HB_ContextSubstFormat1* csf1,				       HB_Buffer               buffer,				       HB_UShort                flags,				       HB_UShort                context_length,				       int                      nesting_level ){  HB_UShort        index, property;  HB_UShort        i, j, k, numsr;  HB_Error         error;  HB_SubRule*     sr;  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 == (HB_Int)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 HB_Error  Lookup_ContextSubst2( HB_GSUBHeader*          gsub,				       HB_ContextSubstFormat2* csf2,				       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, known_classes;  HB_UShort*         classes;  HB_UShort*         cl;  HB_SubClassSet*   scs;  HB_SubClassRule*  sr;  HB_GDEFHeader*    gdef;  gdef = gsub->gdef;

⌨️ 快捷键说明

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