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

📄 harfbuzz-gpos.c

📁 GTK+-2.0源码之pango-1.15.6.tar.gz
💻 C
📖 第 1 页 / 共 5 页
字号:
  FT_ULong      cur_offset, new_offset, base_offset;  HB_PairSet*  ps;  base_offset = FILE_Pos() - 8L;  if ( ACCESS_Frame( 2L ) )    return error;  count = ppf1->PairSetCount = GET_UShort();  FORGET_Frame();  ppf1->PairSet = NULL;  if ( ALLOC_ARRAY( ppf1->PairSet, count, HB_PairSet ) )    return error;  ps = ppf1->PairSet;  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_PairSet( &ps[n], format1,				 format2, stream ) ) != FT_Err_Ok )      goto Fail;    (void)FILE_Seek( cur_offset );  }  return FT_Err_Ok;Fail:  for ( m = 0; m < n; m++ )    Free_PairSet( &ps[m], format1, format2, memory );  FREE( ps );  return error;}static void  Free_PairPos1( HB_PairPosFormat1*  ppf1,			    FT_UShort            format1,			    FT_UShort            format2,			    FT_Memory            memory ){  FT_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, memory );    FREE( ps );  }}/* PairPosFormat2 */static FT_Error  Load_PairPos2( HB_PairPosFormat2*  ppf2,				FT_UShort            format1,				FT_UShort            format2,				FT_Stream            stream ){  FT_Error  error;  FT_Memory memory = stream->memory;  FT_UShort          m, n, k, count1, count2;  FT_ULong           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 ) ) != FT_Err_Ok )    return error;  if ( FILE_Seek( new_offset2 ) ||       ( error = _HB_OPEN_Load_ClassDefinition( &ppf2->ClassDef2, count2,				       stream ) ) != FT_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, memory );	  goto Fail0;	}      }    }    continue;  Fail0:    for ( k = 0; k < n; k++ )    {      if ( format1 )	Free_ValueRecord( &c2r[k].Value1, format1, memory );      if ( format2 )	Free_ValueRecord( &c2r[k].Value2, format2, memory );    }    goto Fail1;  }  return FT_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, memory );      if ( format2 )	Free_ValueRecord( &c2r[n].Value2, format2, memory );    }    FREE( c2r );  }  FREE( c1r );Fail2:  _HB_OPEN_Free_ClassDefinition( &ppf2->ClassDef2, memory );Fail3:  _HB_OPEN_Free_ClassDefinition( &ppf2->ClassDef1, memory );  return error;}static void  Free_PairPos2( HB_PairPosFormat2*  ppf2,			    FT_UShort            format1,			    FT_UShort            format2,			    FT_Memory            memory ){  FT_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, memory );	if ( format2 )	  Free_ValueRecord( &c2r[n].Value2, format2, memory );      }      FREE( c2r );    }    FREE( c1r );    _HB_OPEN_Free_ClassDefinition( &ppf2->ClassDef2, memory );    _HB_OPEN_Free_ClassDefinition( &ppf2->ClassDef1, memory );  }}static FT_Error  Load_PairPos( HB_GPOS_SubTable* st,			       FT_Stream     stream ){  FT_Error  error;  FT_Memory memory = stream->memory;  HB_PairPos*     pp = &st->pair;  FT_UShort         format1, format2;  FT_ULong          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 ) ) != FT_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 HB_Err_Invalid_GPOS_SubTable_Format;  }  return FT_Err_Ok;Fail:  _HB_OPEN_Free_Coverage( &pp->Coverage, memory );  return error;}static void  Free_PairPos( HB_GPOS_SubTable* st,			   FT_Memory     memory ){  FT_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, memory );    break;  case 2:    Free_PairPos2( &pp->ppf.ppf2, format1, format2, memory );    break;  }  _HB_OPEN_Free_Coverage( &pp->Coverage, memory );}static FT_Error  Lookup_PairPos1( GPOS_Instance*       gpi,				  HB_PairPosFormat1*  ppf1,				  HB_Buffer           buffer,				  FT_UShort            first_pos,				  FT_UShort            index,				  FT_UShort            format1,				  FT_UShort            format2 ){  FT_Error              error;  FT_UShort             numpvr, glyph2;  HB_PairValueRecord*  pvr;  if ( index >= ppf1->PairSetCount )     return HB_Err_Invalid_GPOS_SubTable;  pvr = ppf1->PairSet[index].PairValueRecord;  if ( !pvr )    return HB_Err_Invalid_GPOS_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 FT_Error  Lookup_PairPos2( GPOS_Instance*       gpi,				  HB_PairPosFormat2*  ppf2,				  HB_Buffer           buffer,				  FT_UShort            first_pos,				  FT_UShort            format1,				  FT_UShort            format2 ){  FT_Error           error;  FT_UShort          cl1, cl2;  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 HB_Err_Invalid_GPOS_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 FT_Error  Lookup_PairPos( GPOS_Instance*    gpi,				 HB_GPOS_SubTable* st,				 HB_Buffer        buffer,				 FT_UShort         flags,				 FT_UShort         context_length,				 int               nesting_level ){  FT_Error         error;  FT_UShort        index, property, first_pos;  HB_GPOSHeader*  gpos = gpi->gpos;  HB_PairPos*     pp = &st->pair;  FT_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 )      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 HB_Err_Invalid_GPOS_SubTable_Format;  }  /* adjusting the `next' glyph */  if ( pp->ValueFormat2 )    (buffer->in_pos)++;  return error;}/* LookupType 3 *//* CursivePosFormat1 */static FT_Error  Load_CursivePos( HB_GPOS_SubTable* st,				  FT_Stream        stream ){  FT_Error  error;  FT_Memory memory = stream->memory;  HB_CursivePos*  cp = &st->cursive;  FT_UShort             n, m, count;  FT_ULong              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 ) ) != FT_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++ )  {    FT_ULong 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 ) ) != FT_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 ) ) != FT_Err_Ok )      {	if ( entry_offset )	  Free_Anchor( &eer[n].EntryAnchor, memory );	goto Fail1;      }      (void)FILE_Seek( cur_offset );    }    else      eer[n].ExitAnchor.PosFormat   = 0;  }  return FT_Err_Ok;Fail1:  for ( m = 0; m < n; m++ )  {    Free_Anchor( &eer[m].EntryAnchor, memory );    Free_Anchor( &eer[m].ExitAnchor, memory );  }  FREE( eer );Fail2:  _HB_OPEN_Free_Coverage( &cp->Coverage, memory );  return error;}static void  Free_CursivePos( HB_GPOS_SubTable* st,			      FT_Memory        memory ){  FT_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, memory );      Free_Anchor( &eer[n].ExitAnchor, memory );    }    FREE( eer );

⌨️ 快捷键说明

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