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

📄 harfbuzz-gpos.c

📁 Pango is a library for layout and rendering of text, with an emphasis on internationalization. Pang
💻 C
📖 第 1 页 / 共 5 页
字号:
			    HB_UShort            format2 ){  HB_UShort     n, count;  HB_PairSet*  ps;  if ( ppf1->PairSet )  {    count = ppf1->PairSetCount;    ps    = ppf1->PairSet;    for ( n = 0; n < count; n++ )      Free_PairSet( &ps[n], format1, format2 );    FREE( ps );  }}/* PairPosFormat2 */static HB_Error  Load_PairPos2( HB_PairPosFormat2*  ppf2,				HB_UShort            format1,				HB_UShort            format2,				HB_Stream            stream ){  HB_Error  error;  HB_UShort          m, n, k, count1, count2;  HB_UInt           cur_offset, new_offset1, new_offset2, base_offset;  HB_Class1Record*  c1r;  HB_Class2Record*  c2r;  base_offset = FILE_Pos() - 8L;  if ( ACCESS_Frame( 8L ) )    return error;  new_offset1 = GET_UShort() + base_offset;  new_offset2 = GET_UShort() + base_offset;  /* `Class1Count' and `Class2Count' are the upper limits for class     values, thus we read it now to make additional safety checks.  */  count1 = ppf2->Class1Count = GET_UShort();  count2 = ppf2->Class2Count = GET_UShort();  FORGET_Frame();  cur_offset = FILE_Pos();  if ( FILE_Seek( new_offset1 ) ||       ( error = _HB_OPEN_Load_ClassDefinition( &ppf2->ClassDef1, count1,				       stream ) ) != HB_Err_Ok )    return error;  if ( FILE_Seek( new_offset2 ) ||       ( error = _HB_OPEN_Load_ClassDefinition( &ppf2->ClassDef2, count2,				       stream ) ) != HB_Err_Ok )    goto Fail3;  (void)FILE_Seek( cur_offset );  ppf2->Class1Record = NULL;  if ( ALLOC_ARRAY( ppf2->Class1Record, count1, HB_Class1Record ) )    goto Fail2;  c1r = ppf2->Class1Record;  for ( m = 0; m < count1; m++ )  {    c1r[m].Class2Record = NULL;    if ( ALLOC_ARRAY( c1r[m].Class2Record, count2, HB_Class2Record ) )      goto Fail1;    c2r = c1r[m].Class2Record;    for ( n = 0; n < count2; n++ )    {      if ( format1 )      {	error = Load_ValueRecord( &c2r[n].Value1, format1,				  base_offset, stream );	if ( error )	  goto Fail0;      }      if ( format2 )      {	error = Load_ValueRecord( &c2r[n].Value2, format2,				  base_offset, stream );	if ( error )	{	  if ( format1 )	    Free_ValueRecord( &c2r[n].Value1, format1 );	  goto Fail0;	}      }    }    continue;  Fail0:    for ( k = 0; k < n; k++ )    {      if ( format1 )	Free_ValueRecord( &c2r[k].Value1, format1 );      if ( format2 )	Free_ValueRecord( &c2r[k].Value2, format2 );    }    goto Fail1;  }  return HB_Err_Ok;Fail1:  for ( k = 0; k < m; k++ )  {    c2r = c1r[k].Class2Record;    for ( n = 0; n < count2; n++ )    {      if ( format1 )	Free_ValueRecord( &c2r[n].Value1, format1 );      if ( format2 )	Free_ValueRecord( &c2r[n].Value2, format2 );    }    FREE( c2r );  }  FREE( c1r );Fail2:  _HB_OPEN_Free_ClassDefinition( &ppf2->ClassDef2 );Fail3:  _HB_OPEN_Free_ClassDefinition( &ppf2->ClassDef1 );  return error;}static void  Free_PairPos2( HB_PairPosFormat2*  ppf2,			    HB_UShort            format1,			    HB_UShort            format2 ){  HB_UShort          m, n, count1, count2;  HB_Class1Record*  c1r;  HB_Class2Record*  c2r;  if ( ppf2->Class1Record )  {    c1r    = ppf2->Class1Record;    count1 = ppf2->Class1Count;    count2 = ppf2->Class2Count;    for ( m = 0; m < count1; m++ )    {      c2r = c1r[m].Class2Record;      for ( n = 0; n < count2; n++ )      {	if ( format1 )	  Free_ValueRecord( &c2r[n].Value1, format1 );	if ( format2 )	  Free_ValueRecord( &c2r[n].Value2, format2 );      }      FREE( c2r );    }    FREE( c1r );    _HB_OPEN_Free_ClassDefinition( &ppf2->ClassDef2 );    _HB_OPEN_Free_ClassDefinition( &ppf2->ClassDef1 );  }}static HB_Error  Load_PairPos( HB_GPOS_SubTable* st,			       HB_Stream     stream ){  HB_Error  error;  HB_PairPos*     pp = &st->pair;  HB_UShort         format1, format2;  HB_UInt          cur_offset, new_offset, base_offset;  base_offset = FILE_Pos();  if ( ACCESS_Frame( 8L ) )    return error;  pp->PosFormat = GET_UShort();  new_offset    = GET_UShort() + base_offset;  format1 = pp->ValueFormat1 = GET_UShort();  format2 = pp->ValueFormat2 = GET_UShort();  FORGET_Frame();  cur_offset = FILE_Pos();  if ( FILE_Seek( new_offset ) ||       ( error = _HB_OPEN_Load_Coverage( &pp->Coverage, stream ) ) != HB_Err_Ok )    return error;  (void)FILE_Seek( cur_offset );  switch ( pp->PosFormat )  {  case 1:    error = Load_PairPos1( &pp->ppf.ppf1, format1, format2, stream );    if ( error )      goto Fail;    break;  case 2:    error = Load_PairPos2( &pp->ppf.ppf2, format1, format2, stream );    if ( error )      goto Fail;    break;  default:    return ERR(HB_Err_Invalid_SubTable_Format);  }  return HB_Err_Ok;Fail:  _HB_OPEN_Free_Coverage( &pp->Coverage );  return error;}static void  Free_PairPos( HB_GPOS_SubTable* st ){  HB_UShort  format1, format2;  HB_PairPos*     pp = &st->pair;  format1 = pp->ValueFormat1;  format2 = pp->ValueFormat2;  switch ( pp->PosFormat )  {  case 1:    Free_PairPos1( &pp->ppf.ppf1, format1, format2 );    break;  case 2:    Free_PairPos2( &pp->ppf.ppf2, format1, format2 );    break;  default:    break;  }  _HB_OPEN_Free_Coverage( &pp->Coverage );}static HB_Error  Lookup_PairPos1( GPOS_Instance*       gpi,				  HB_PairPosFormat1*  ppf1,				  HB_Buffer           buffer,				  HB_UInt             first_pos,				  HB_UShort            index,				  HB_UShort            format1,				  HB_UShort            format2 ){  HB_Error              error;  HB_UShort             numpvr, glyph2;  HB_PairValueRecord*  pvr;  if ( index >= ppf1->PairSetCount )     return ERR(HB_Err_Invalid_SubTable);  pvr = ppf1->PairSet[index].PairValueRecord;  if ( !pvr )    return ERR(HB_Err_Invalid_SubTable);  glyph2 = IN_CURGLYPH();  for ( numpvr = ppf1->PairSet[index].PairValueCount;	numpvr;	numpvr--, pvr++ )  {    if ( glyph2 == pvr->SecondGlyph )    {      error = Get_ValueRecord( gpi, &pvr->Value1, format1,			       POSITION( first_pos ) );      if ( error )	return error;      return Get_ValueRecord( gpi, &pvr->Value2, format2,			      POSITION( buffer->in_pos ) );    }  }  return HB_Err_Not_Covered;}static HB_Error  Lookup_PairPos2( GPOS_Instance*       gpi,				  HB_PairPosFormat2*  ppf2,				  HB_Buffer           buffer,				  HB_UInt             first_pos,				  HB_UShort            format1,				  HB_UShort            format2 ){  HB_Error           error;  HB_UShort          cl1 = 0, cl2 = 0; /* shut compiler up */  HB_Class1Record*  c1r;  HB_Class2Record*  c2r;  error = _HB_OPEN_Get_Class( &ppf2->ClassDef1, IN_GLYPH( first_pos ),		     &cl1, NULL );  if ( error && error != HB_Err_Not_Covered )    return error;  error = _HB_OPEN_Get_Class( &ppf2->ClassDef2, IN_CURGLYPH(),		     &cl2, NULL );  if ( error && error != HB_Err_Not_Covered )    return error;  c1r = &ppf2->Class1Record[cl1];  if ( !c1r )    return ERR(HB_Err_Invalid_SubTable);  c2r = &c1r->Class2Record[cl2];  error = Get_ValueRecord( gpi, &c2r->Value1, format1, POSITION( first_pos ) );  if ( error )    return error;  return Get_ValueRecord( gpi, &c2r->Value2, format2, POSITION( buffer->in_pos ) );}static HB_Error  Lookup_PairPos( GPOS_Instance*    gpi,				 HB_GPOS_SubTable* st,				 HB_Buffer        buffer,				 HB_UShort         flags,				 HB_UShort         context_length,				 int               nesting_level ){  HB_Error         error;  HB_UShort        index, property;  HB_UInt         first_pos;  HB_GPOSHeader*  gpos = gpi->gpos;  HB_PairPos*     pp = &st->pair;  HB_UNUSED(nesting_level);  if ( buffer->in_pos >= buffer->in_length - 1 )    return HB_Err_Not_Covered;           /* Not enough glyphs in stream */  if ( context_length != 0xFFFF && context_length < 2 )    return HB_Err_Not_Covered;  if ( CHECK_Property( gpos->gdef, IN_CURITEM(), flags, &property ) )    return error;  error = _HB_OPEN_Coverage_Index( &pp->Coverage, IN_CURGLYPH(), &index );  if ( error )    return error;  /* second glyph */  first_pos = buffer->in_pos;  (buffer->in_pos)++;  while ( CHECK_Property( gpos->gdef, IN_CURITEM(),			  flags, &property ) )  {    if ( error && error != HB_Err_Not_Covered )      return error;    if ( buffer->in_pos == buffer->in_length )      {	buffer->in_pos = first_pos;        return HB_Err_Not_Covered;      }    (buffer->in_pos)++;  }  switch ( pp->PosFormat )  {  case 1:    error = Lookup_PairPos1( gpi, &pp->ppf.ppf1, buffer,			     first_pos, index,			     pp->ValueFormat1, pp->ValueFormat2 );    break;  case 2:    error = Lookup_PairPos2( gpi, &pp->ppf.ppf2, buffer, first_pos,			     pp->ValueFormat1, pp->ValueFormat2 );    break;  default:    return ERR(HB_Err_Invalid_SubTable_Format);  }  /* if we don't have coverage for the second glyph don't skip it for     further lookups but reset in_pos back to the first_glyph and let     the caller in Do_String_Lookup increment in_pos */  if ( error == HB_Err_Not_Covered )      buffer->in_pos = first_pos;  /* adjusting the `next' glyph */  if ( pp->ValueFormat2 )    (buffer->in_pos)++;  return error;}/* LookupType 3 *//* CursivePosFormat1 */static HB_Error  Load_CursivePos( HB_GPOS_SubTable* st,				  HB_Stream        stream ){  HB_Error  error;  HB_CursivePos*  cp = &st->cursive;  HB_UShort             n, m, count;  HB_UInt              cur_offset, new_offset, base_offset;  HB_EntryExitRecord*  eer;  base_offset = FILE_Pos();  if ( ACCESS_Frame( 4L ) )    return error;  cp->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( &cp->Coverage, stream ) ) != HB_Err_Ok )    return error;  (void)FILE_Seek( cur_offset );  if ( ACCESS_Frame( 2L ) )    goto Fail2;  count = cp->EntryExitCount = GET_UShort();  FORGET_Frame();  cp->EntryExitRecord = NULL;  if ( ALLOC_ARRAY( cp->EntryExitRecord, count, HB_EntryExitRecord ) )    goto Fail2;  eer = cp->EntryExitRecord;  for ( n = 0; n < count; n++ )  {    HB_UInt entry_offset;    if ( ACCESS_Frame( 2L ) )      return error;    entry_offset = new_offset = GET_UShort();    FORGET_Frame();    if ( new_offset )    {      new_offset += base_offset;      cur_offset = FILE_Pos();      if ( FILE_Seek( new_offset ) ||	   ( error = Load_Anchor( &eer[n].EntryAnchor,				  stream ) ) != HB_Err_Ok )	goto Fail1;      (void)FILE_Seek( cur_offset );    }    else      eer[n].EntryAnchor.PosFormat   = 0;    if ( ACCESS_Frame( 2L ) )      return error;    new_offset = GET_UShort();    FORGET_Frame();    if ( new_offset )    {      new_offset += base_offset;      cur_offset = FILE_Pos();      if ( FILE_Seek( new_offset ) ||	   ( error = Load_Anchor( &eer[n].ExitAnchor,				  stream ) ) != HB_Err_Ok )      {	if ( entry_offset )	  Free_Anchor( &eer[n].EntryAnchor );	goto Fail1;      }      (void)FILE_Seek( cur_offset );    }    else      eer[n].ExitAnchor.PosFormat   = 0;  }  return HB_Err_Ok;Fail1:  for ( m = 0; m < n; m++ )  {    Free_Anchor( &eer[m].EntryAnchor );    Free_Anchor( &eer[m].ExitAnchor );  }  FREE( eer );Fail2:  _HB_OPEN_Free_Coverage( &cp->Coverage );  return error;}static void  Free_CursivePos( HB_GPOS_SubTable* st ){  HB_UShort             n, count;  HB_CursivePos*  cp = &st->cursive;  HB_EntryExitRecord*  eer;  if ( cp->EntryExitRecord )  {    count = cp->EntryExitCount;    eer   = cp->EntryExitRecord;    for ( n = 0; n < count; n++ )    {      Free_Anchor( &eer[n].EntryAnchor );      Free_Anchor( &eer[n].ExitAnchor );    }    FREE( eer );  }  _HB_OPEN_Free_Coverage( &cp->Coverage );}static HB_Error  Lookup_CursivePos( GPOS_Instance*    gpi,				    HB_GPOS_SubTable* st,				    HB_Buffer        buffer,				    HB_UShort         flags,				    HB_UShort         context_length,				    int               nesting_level ){  HB_UShort        index, property;  HB_Error         error;  HB_GPOSHeader*  gpos = gpi->gpos;  HB_CursivePos*  cp = &st->cursive;  HB_EntryExitRecord*  eer;  HB_Fixed                entry_x, entry_y;  HB_Fixed                exit_x, exit_y;  HB_UNUSED(nesting_level);  if ( context_length != 0xFFFF && context_length < 1 )  {    gpi->last = 0xFFFF;    return HB_Err_Not_Covered;  }  /* Glyphs not having the right GDEF properties will be ignored, i.e.,     gpi->last won't be reset (contrary to user defined properties). */  if ( CHECK_Property( gpos->gdef, IN_CURITEM(), flags, &property ) )    return error;  /* We don't handle mark glyphs here.  According to Andrei, this isn't     possible, but who knows...                                         */  if ( property == HB_GDEF_MARK )  {    gpi->last = 0xFFFF;    return HB_Err_Not_Covered;  }  error = _HB_OPEN_Coverage_Index( &cp->Coverage, IN_CURGLYPH(), &index );  if ( error )  {    gpi->last = 0xFFFF;

⌨️ 快捷键说明

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