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

📄 harfbuzz-gpos.c

📁 Pango is a library for layout and rendering of text, with an emphasis on internationalization. Pang
💻 C
📖 第 1 页 / 共 5 页
字号:
{  HB_UShort        m, n, count;  HB_ComponentRecord*  cr;  HB_Anchor*           lan;  if ( lat->ComponentRecord )  {    count = lat->ComponentCount;    cr    = lat->ComponentRecord;    for ( m = 0; m < count; m++ )    {      lan = cr[m].LigatureAnchor;      for ( n = 0; n < num_classes; n++ )	Free_Anchor( &lan[n] );      FREE( lan );    }    FREE( cr );  }}/* LigatureArray */static HB_Error  Load_LigatureArray( HB_LigatureArray*  la,				     HB_UShort           num_classes,				     HB_Stream           stream ){  HB_Error  error;  HB_UShort            n, m, count;  HB_UInt             cur_offset, new_offset, base_offset;  HB_LigatureAttach*  lat;  base_offset = FILE_Pos();  if ( ACCESS_Frame( 2L ) )    return error;  count = la->LigatureCount = GET_UShort();  FORGET_Frame();  la->LigatureAttach = NULL;  if ( ALLOC_ARRAY( la->LigatureAttach, count, HB_LigatureAttach ) )    return error;  lat = la->LigatureAttach;  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_LigatureAttach( &lat[n], num_classes,					stream ) ) != HB_Err_Ok )      goto Fail;    (void)FILE_Seek( cur_offset );  }  return HB_Err_Ok;Fail:  for ( m = 0; m < n; m++ )    Free_LigatureAttach( &lat[m], num_classes );  FREE( lat );  return error;}static void  Free_LigatureArray( HB_LigatureArray*  la,				 HB_UShort          num_classes ){  HB_UShort            n, count;  HB_LigatureAttach*  lat;  if ( la->LigatureAttach )  {    count = la->LigatureCount;    lat   = la->LigatureAttach;    for ( n = 0; n < count; n++ )      Free_LigatureAttach( &lat[n], num_classes );    FREE( lat );  }}/* MarkLigPosFormat1 */static HB_Error  Load_MarkLigPos( HB_GPOS_SubTable* st,				  HB_Stream        stream ){  HB_Error  error;  HB_MarkLigPos*  mlp = &st->marklig;  HB_UInt  cur_offset, new_offset, base_offset;  base_offset = FILE_Pos();  if ( ACCESS_Frame( 4L ) )    return error;  mlp->PosFormat = GET_UShort();  new_offset     = GET_UShort() + base_offset;  FORGET_Frame();  cur_offset = FILE_Pos();  if ( FILE_Seek( new_offset ) ||       ( error = _HB_OPEN_Load_Coverage( &mlp->MarkCoverage, stream ) ) != HB_Err_Ok )    return error;  (void)FILE_Seek( cur_offset );  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( &mlp->LigatureCoverage,				stream ) ) != HB_Err_Ok )    goto Fail3;  (void)FILE_Seek( cur_offset );  if ( ACCESS_Frame( 4L ) )    goto Fail2;  mlp->ClassCount = GET_UShort();  new_offset      = GET_UShort() + base_offset;  FORGET_Frame();  cur_offset = FILE_Pos();  if ( FILE_Seek( new_offset ) ||       ( error = Load_MarkArray( &mlp->MarkArray, stream ) ) != HB_Err_Ok )    goto Fail2;  (void)FILE_Seek( cur_offset );  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_LigatureArray( &mlp->LigatureArray, mlp->ClassCount,				     stream ) ) != HB_Err_Ok )    goto Fail1;  return HB_Err_Ok;Fail1:  Free_MarkArray( &mlp->MarkArray );Fail2:  _HB_OPEN_Free_Coverage( &mlp->LigatureCoverage );Fail3:  _HB_OPEN_Free_Coverage( &mlp->MarkCoverage );  return error;}static void  Free_MarkLigPos( HB_GPOS_SubTable* st ){  HB_MarkLigPos*  mlp = &st->marklig;  Free_LigatureArray( &mlp->LigatureArray, mlp->ClassCount );  Free_MarkArray( &mlp->MarkArray );  _HB_OPEN_Free_Coverage( &mlp->LigatureCoverage );  _HB_OPEN_Free_Coverage( &mlp->MarkCoverage );}static HB_Error  Lookup_MarkLigPos( GPOS_Instance*    gpi,				    HB_GPOS_SubTable* st,				    HB_Buffer        buffer,				    HB_UShort         flags,				    HB_UShort         context_length,				    int               nesting_level ){  HB_UShort        i, j, mark_index, lig_index, property, class;  HB_UShort        mark_glyph;  HB_Fixed           x_mark_value, y_mark_value, x_lig_value, y_lig_value;  HB_Error         error;  HB_GPOSHeader*  gpos = gpi->gpos;  HB_MarkLigPos*  mlp = &st->marklig;  HB_MarkArray*        ma;  HB_LigatureArray*    la;  HB_LigatureAttach*   lat;  HB_ComponentRecord*  cr;  HB_UShort             comp_index;  HB_Anchor*           mark_anchor;  HB_Anchor*           lig_anchor;  HB_Position    o;  HB_UNUSED(nesting_level);  if ( context_length != 0xFFFF && context_length < 1 )    return HB_Err_Not_Covered;  if ( flags & HB_LOOKUP_FLAG_IGNORE_LIGATURES )    return HB_Err_Not_Covered;  mark_glyph = IN_CURGLYPH();  if ( CHECK_Property( gpos->gdef, IN_CURITEM(), flags, &property ) )    return error;  error = _HB_OPEN_Coverage_Index( &mlp->MarkCoverage, mark_glyph, &mark_index );  if ( error )    return error;  /* now we search backwards for a non-mark glyph */  i = 1;  j = buffer->in_pos - 1;  while ( i <= buffer->in_pos )  {    error = HB_GDEF_Get_Glyph_Property( gpos->gdef, IN_GLYPH( j ),					&property );    if ( error )      return error;    if ( !( property == HB_GDEF_MARK || property & HB_LOOKUP_FLAG_IGNORE_SPECIAL_MARKS ) )      break;    i++;    j--;  }  /* Similar to Lookup_MarkBasePos(), I suspect that this assertion is     too strong, thus it is commented out.                             */#if 0  if ( property != HB_GDEF_LIGATURE )    return HB_Err_Not_Covered;#endif  if ( i > buffer->in_pos )    return HB_Err_Not_Covered;  error = _HB_OPEN_Coverage_Index( &mlp->LigatureCoverage, IN_GLYPH( j ),			  &lig_index );  if ( error )    return error;  ma = &mlp->MarkArray;  if ( mark_index >= ma->MarkCount )    return ERR(HB_Err_Invalid_SubTable);  class       = ma->MarkRecord[mark_index].Class;  mark_anchor = &ma->MarkRecord[mark_index].MarkAnchor;  if ( class >= mlp->ClassCount )    return ERR(HB_Err_Invalid_SubTable);  la = &mlp->LigatureArray;  if ( lig_index >= la->LigatureCount )    return ERR(HB_Err_Invalid_SubTable);  lat = &la->LigatureAttach[lig_index];  /* We must now check whether the ligature ID of the current mark glyph     is identical to the ligature ID of the found ligature.  If yes, we     can directly use the component index.  If not, we attach the mark     glyph to the last component of the ligature.                        */  if ( IN_LIGID( j ) == IN_LIGID( buffer->in_pos) )  {    comp_index = IN_COMPONENT( buffer->in_pos );    if ( comp_index >= lat->ComponentCount )      return HB_Err_Not_Covered;  }  else    comp_index = lat->ComponentCount - 1;  cr         = &lat->ComponentRecord[comp_index];  lig_anchor = &cr->LigatureAnchor[class];  error = Get_Anchor( gpi, mark_anchor, IN_CURGLYPH(),		      &x_mark_value, &y_mark_value );  if ( error )    return error;  error = Get_Anchor( gpi, lig_anchor, IN_GLYPH( j ),		      &x_lig_value, &y_lig_value );  if ( error )    return error;  /* anchor points are not cumulative */  o = POSITION( buffer->in_pos );  o->x_pos     = x_lig_value - x_mark_value;  o->y_pos     = y_lig_value - y_mark_value;  o->x_advance = 0;  o->y_advance = 0;  o->back      = i;  (buffer->in_pos)++;  return HB_Err_Ok;}/* LookupType 6 *//* Mark2Array */static HB_Error  Load_Mark2Array( HB_Mark2Array*  m2a,				  HB_UShort        num_classes,				  HB_Stream        stream ){  HB_Error  error;  HB_UShort         k, m, n, count;  HB_UInt          cur_offset, new_offset, base_offset;  HB_Mark2Record*  m2r;  HB_Anchor*       m2an;  base_offset = FILE_Pos();  if ( ACCESS_Frame( 2L ) )    return error;  count = m2a->Mark2Count = GET_UShort();  FORGET_Frame();  m2a->Mark2Record = NULL;  if ( ALLOC_ARRAY( m2a->Mark2Record, count, HB_Mark2Record ) )    return error;  m2r = m2a->Mark2Record;  for ( m = 0; m < count; m++ )  {    m2r[m].Mark2Anchor = NULL;    if ( ALLOC_ARRAY( m2r[m].Mark2Anchor, num_classes, HB_Anchor ) )      goto Fail;    m2an = m2r[m].Mark2Anchor;    for ( n = 0; n < num_classes; n++ )    {      if ( ACCESS_Frame( 2L ) )	goto Fail0;      new_offset = GET_UShort() + base_offset;      FORGET_Frame();      cur_offset = FILE_Pos();      if ( FILE_Seek( new_offset ) ||	   ( error = Load_Anchor( &m2an[n], stream ) ) != HB_Err_Ok )	goto Fail0;      (void)FILE_Seek( cur_offset );    }    continue;  Fail0:    for ( k = 0; k < n; k++ )      Free_Anchor( &m2an[k] );    goto Fail;  }  return HB_Err_Ok;Fail:  for ( k = 0; k < m; k++ )  {    m2an = m2r[k].Mark2Anchor;    for ( n = 0; n < num_classes; n++ )      Free_Anchor( &m2an[n] );    FREE( m2an );  }  FREE( m2r );  return error;}static void  Free_Mark2Array( HB_Mark2Array*  m2a,			      HB_UShort        num_classes ){  HB_UShort         m, n, count;  HB_Mark2Record*  m2r;  HB_Anchor*       m2an;  if ( m2a->Mark2Record )  {    count = m2a->Mark2Count;    m2r   = m2a->Mark2Record;    for ( m = 0; m < count; m++ )    {      m2an = m2r[m].Mark2Anchor;      for ( n = 0; n < num_classes; n++ )	Free_Anchor( &m2an[n] );      FREE( m2an );    }    FREE( m2r );  }}/* MarkMarkPosFormat1 */static HB_Error  Load_MarkMarkPos( HB_GPOS_SubTable* st,				   HB_Stream         stream ){  HB_Error  error;  HB_MarkMarkPos* mmp = &st->markmark;  HB_UInt  cur_offset, new_offset, base_offset;  base_offset = FILE_Pos();  if ( ACCESS_Frame( 4L ) )    return error;  mmp->PosFormat = GET_UShort();  new_offset     = GET_UShort() + base_offset;  FORGET_Frame();  cur_offset = FILE_Pos();  if ( FILE_Seek( new_offset ) ||       ( error = _HB_OPEN_Load_Coverage( &mmp->Mark1Coverage,				stream ) ) != HB_Err_Ok )    return error;  (void)FILE_Seek( cur_offset );  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( &mmp->Mark2Coverage,				stream ) ) != HB_Err_Ok )    goto Fail3;  (void)FILE_Seek( cur_offset );  if ( ACCESS_Frame( 4L ) )    goto Fail2;  mmp->ClassCount = GET_UShort();  new_offset      = GET_UShort() + base_offset;  FORGET_Frame();  cur_offset = FILE_Pos();  if ( FILE_Seek( new_offset ) ||       ( error = Load_MarkArray( &mmp->Mark1Array, stream ) ) != HB_Err_Ok )    goto Fail2;  (void)FILE_Seek( cur_offset );  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_Mark2Array( &mmp->Mark2Array, mmp->ClassCount,				  stream ) ) != HB_Err_Ok )    goto Fail1;  return HB_Err_Ok;Fail1:  Free_MarkArray( &mmp->Mark1Array );Fail2:  _HB_OPEN_Free_Coverage( &mmp->Mark2Coverage );Fail3:  _HB_OPEN_Free_Coverage( &mmp->Mark1Coverage );  return error;}static void  Free_MarkMarkPos( HB_GPOS_SubTable* st ){  HB_MarkMarkPos* mmp = &st->markmark;  Free_Mark2Array( &mmp->Mark2Array, mmp->ClassCount );  Free_MarkArray( &mmp->Mark1Array );  _HB_OPEN_Free_Coverage( &mmp->Mark2Coverage );  _HB_OPEN_Free_Coverage( &mmp->Mark1Coverage );}static HB_Error  Lookup_MarkMarkPos( GPOS_Instance*    gpi,				     HB_GPOS_SubTable* st,				     HB_Buffer        buffer,				     HB_UShort         flags,				     HB_UShort         context_length,				     int               nesting_level ){  HB_UShort        i, j, mark1_index, mark2_index, property, class;  HB_Fixed           x_mark1_value, y_mark1_value,		   x_mark2_value, y_mark2_value;  HB_Error         error;  HB_GPOSHeader*  gpos = gpi->gpos;  HB_MarkMarkPos* mmp = &st->markmark;  HB_MarkArray*    ma1;  HB_Mark2Array*   ma2;  HB_Mark2Record*  m2r;  HB_Anchor*       mark1_anchor;  HB_Anchor*       mark2_anchor;  HB_Position    o;  HB_UNUSED(nesting_level);  if ( context_length != 0xFFFF && context_length < 1 )    return HB_Err_Not_Covered;  if ( flags & HB_LOOKUP_FLAG_IGNORE_MARKS )    return HB_Err_Not_Covered;  if ( CHECK_Property( gpos->gdef, IN_CURITEM(),		       flags, &property ) )    return error;  error = _HB_OPEN_Coverage_Index( &mmp->Mark1Coverage, IN_CURGLYPH(),			  &mark1_index );  if ( error )    return error;  /* now we search backwards for a suitable mark glyph until a non-mark     glyph                                                */  if ( buffer->in_pos == 0 )    return HB_Err_Not_Covered;  i = 1;  j = buffer->in_pos - 1;  while ( i <= buffer->in_pos )  {    error = HB_GDEF_Get_Glyph_Property( gpos->gdef, IN_GLYPH( j ),					&property );    if ( error )      return error;    if ( !( property == HB_GDEF_MARK || property & HB_LOOKUP_FLAG_IGNORE_SPECIAL_MARKS ) )      return HB_Err_Not_Covered;    if ( flags & HB_LOOKUP_FLAG_IGNORE_SPECIAL_MARKS )    {      if ( property == (flags & 0xFF00) )        

⌨️ 快捷键说明

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