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

📄 harfbuzz-gpos.c

📁 Pango is a library for layout and rendering of text, with an emphasis on internationalization. Pang
💻 C
📖 第 1 页 / 共 5 页
字号:
    new_offset = GET_UShort();    FORGET_Frame();    if ( new_offset )    {      new_offset += base_offset;      cur_offset = FILE_Pos();      if ( FILE_Seek( new_offset ) ||	   ( error = _HB_OPEN_Load_Device( &an->af.af3.XDeviceTable,				  stream ) ) != HB_Err_Ok )	return error;      (void)FILE_Seek( cur_offset );    }    else    {      an->af.af3.XDeviceTable.StartSize  = 0;      an->af.af3.XDeviceTable.EndSize    = 0;      an->af.af3.XDeviceTable.DeltaValue = NULL;    }    if ( ACCESS_Frame( 2L ) )      goto Fail;    new_offset = GET_UShort();    FORGET_Frame();    if ( new_offset )    {      new_offset += base_offset;      cur_offset = FILE_Pos();      if ( FILE_Seek( new_offset ) ||	   ( error = _HB_OPEN_Load_Device( &an->af.af3.YDeviceTable,				  stream ) ) != HB_Err_Ok )	goto Fail;      (void)FILE_Seek( cur_offset );    }    else    {      an->af.af3.YDeviceTable.StartSize  = 0;      an->af.af3.YDeviceTable.EndSize    = 0;      an->af.af3.YDeviceTable.DeltaValue = NULL;    }    break;  case 4:    if ( ACCESS_Frame( 4L ) )      return error;    an->af.af4.XIdAnchor = GET_UShort();    an->af.af4.YIdAnchor = GET_UShort();    FORGET_Frame();    break;  default:    return ERR(HB_Err_Invalid_SubTable_Format);  }  return HB_Err_Ok;Fail:  _HB_OPEN_Free_Device( &an->af.af3.XDeviceTable );  return error;}static void  Free_Anchor( HB_Anchor*  an ){  if ( an->PosFormat == 3 )  {    _HB_OPEN_Free_Device( &an->af.af3.YDeviceTable );    _HB_OPEN_Free_Device( &an->af.af3.XDeviceTable );  }}static HB_Error  Get_Anchor( GPOS_Instance*   gpi,			     HB_Anchor*      an,			     HB_UShort        glyph_index,			     HB_Fixed*          x_value,			     HB_Fixed*          y_value ){  HB_Error  error = HB_Err_Ok;  FT_Outline       outline;  HB_GPOSHeader*  gpos = gpi->gpos;  HB_UShort        ap;  HB_Short         pixel_value;  HB_UShort        load_flags;  HB_UShort        x_ppem, y_ppem;  HB_16Dot16         x_scale, y_scale;  x_ppem  = gpi->font->size->metrics.x_ppem;  y_ppem  = gpi->font->size->metrics.y_ppem;  x_scale = gpi->font->size->metrics.x_scale;  y_scale = gpi->font->size->metrics.y_scale;  switch ( an->PosFormat )  {  case 0:    /* The special case of an empty AnchorTable */  default:    return HB_Err_Not_Covered;  case 1:    *x_value = x_scale * an->af.af1.XCoordinate / 0x10000;    *y_value = y_scale * an->af.af1.YCoordinate / 0x10000;    break;  case 2:    /* glyphs must be scaled */    load_flags = gpi->load_flags & ~FT_LOAD_NO_SCALE;    if ( !gpi->dvi )    {      error = (gpos->gfunc)( gpi->font, glyph_index, load_flags );      if ( error )	return error;      if ( gpi->font->glyph->format != ft_glyph_format_outline )	return ERR(HB_Err_Invalid_SubTable);      ap = an->af.af2.AnchorPoint;      outline = gpi->font->glyph->outline;      /* if n_points is set to zero, we use the design coordinate value pair.       * This can happen e.g. for sbit glyphs. */       if ( !outline.n_points )	goto no_contour_point;      if ( ap >= outline.n_points )	return ERR(HB_Err_Invalid_SubTable);      *x_value = outline.points[ap].x;      *y_value = outline.points[ap].y;    }    else    {    no_contour_point:      *x_value = x_scale * an->af.af3.XCoordinate / 0x10000;      *y_value = y_scale * an->af.af3.YCoordinate / 0x10000;    }    break;  case 3:    if ( !gpi->dvi )    {      _HB_OPEN_Get_Device( &an->af.af3.XDeviceTable, x_ppem, &pixel_value );      *x_value = pixel_value << 6;      _HB_OPEN_Get_Device( &an->af.af3.YDeviceTable, y_ppem, &pixel_value );      *y_value = pixel_value << 6;    }    else      *x_value = *y_value = 0;    *x_value += x_scale * an->af.af3.XCoordinate / 0x10000;    *y_value += y_scale * an->af.af3.YCoordinate / 0x10000;    break;  case 4:    error = (gpos->mmfunc)( gpi->font, an->af.af4.XIdAnchor,			    x_value, gpos->data );    if ( error )      return error;    error = (gpos->mmfunc)( gpi->font, an->af.af4.YIdAnchor,			    y_value, gpos->data );    if ( error )      return error;    break;  }  return error;}/* MarkArray */static HB_Error  Load_MarkArray ( HB_MarkArray*  ma,				  HB_Stream       stream ){  HB_Error  error;  HB_UShort        n, m, count;  HB_UInt         cur_offset, new_offset, base_offset;  HB_MarkRecord*  mr;  base_offset = FILE_Pos();  if ( ACCESS_Frame( 2L ) )    return error;  count = ma->MarkCount = GET_UShort();  FORGET_Frame();  ma->MarkRecord = NULL;  if ( ALLOC_ARRAY( ma->MarkRecord, count, HB_MarkRecord ) )    return error;  mr = ma->MarkRecord;  for ( n = 0; n < count; n++ )  {    if ( ACCESS_Frame( 4L ) )      goto Fail;    mr[n].Class = GET_UShort();    new_offset  = GET_UShort() + base_offset;    FORGET_Frame();    cur_offset = FILE_Pos();    if ( FILE_Seek( new_offset ) ||	 ( error = Load_Anchor( &mr[n].MarkAnchor, stream ) ) != HB_Err_Ok )      goto Fail;    (void)FILE_Seek( cur_offset );  }  return HB_Err_Ok;Fail:  for ( m = 0; m < n; m++ )    Free_Anchor( &mr[m].MarkAnchor );  FREE( mr );  return error;}static void  Free_MarkArray( HB_MarkArray*  ma ){  HB_UShort        n, count;  HB_MarkRecord*  mr;  if ( ma->MarkRecord )  {    count = ma->MarkCount;    mr    = ma->MarkRecord;    for ( n = 0; n < count; n++ )      Free_Anchor( &mr[n].MarkAnchor );    FREE( mr );  }}/* LookupType 1 *//* SinglePosFormat1 *//* SinglePosFormat2 */static HB_Error  Load_SinglePos( HB_GPOS_SubTable* st,				 HB_Stream       stream ){  HB_Error  error;  HB_SinglePos*   sp = &st->single;  HB_UShort         n, m, count, format;  HB_UInt          cur_offset, new_offset, base_offset;  HB_ValueRecord*  vr;  base_offset = FILE_Pos();  if ( ACCESS_Frame( 6L ) )    return error;  sp->PosFormat = GET_UShort();  new_offset    = GET_UShort() + base_offset;  format = sp->ValueFormat = GET_UShort();  FORGET_Frame();  if ( !format )    return ERR(HB_Err_Invalid_SubTable);  cur_offset = FILE_Pos();  if ( FILE_Seek( new_offset ) ||       ( error = _HB_OPEN_Load_Coverage( &sp->Coverage, stream ) ) != HB_Err_Ok )    return error;  (void)FILE_Seek( cur_offset );  switch ( sp->PosFormat )  {  case 1:    error = Load_ValueRecord( &sp->spf.spf1.Value, format,			      base_offset, stream );    if ( error )      goto Fail2;    break;  case 2:    if ( ACCESS_Frame( 2L ) )      goto Fail2;    count = sp->spf.spf2.ValueCount = GET_UShort();    FORGET_Frame();    sp->spf.spf2.Value = NULL;    if ( ALLOC_ARRAY( sp->spf.spf2.Value, count, HB_ValueRecord ) )      goto Fail2;    vr = sp->spf.spf2.Value;    for ( n = 0; n < count; n++ )    {      error = Load_ValueRecord( &vr[n], format, base_offset, stream );      if ( error )	goto Fail1;    }    break;  default:    return ERR(HB_Err_Invalid_SubTable_Format);  }  return HB_Err_Ok;Fail1:  for ( m = 0; m < n; m++ )    Free_ValueRecord( &vr[m], format );  FREE( vr );Fail2:  _HB_OPEN_Free_Coverage( &sp->Coverage );  return error;}static void  Free_SinglePos( HB_GPOS_SubTable* st ){  HB_UShort         n, count, format;  HB_SinglePos*   sp = &st->single;  HB_ValueRecord*  v;  format = sp->ValueFormat;  switch ( sp->PosFormat )  {  case 1:    Free_ValueRecord( &sp->spf.spf1.Value, format );    break;  case 2:    if ( sp->spf.spf2.Value )    {      count = sp->spf.spf2.ValueCount;      v     = sp->spf.spf2.Value;      for ( n = 0; n < count; n++ )	Free_ValueRecord( &v[n], format );      FREE( v );    }    break;  default:    break;  }  _HB_OPEN_Free_Coverage( &sp->Coverage );}static HB_Error  Lookup_SinglePos( 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_SinglePos*   sp = &st->single;  HB_UNUSED(nesting_level);  if ( context_length != 0xFFFF && context_length < 1 )    return HB_Err_Not_Covered;  if ( CHECK_Property( gpos->gdef, IN_CURITEM(), flags, &property ) )    return error;  error = _HB_OPEN_Coverage_Index( &sp->Coverage, IN_CURGLYPH(), &index );  if ( error )    return error;  switch ( sp->PosFormat )  {  case 1:    error = Get_ValueRecord( gpi, &sp->spf.spf1.Value,			     sp->ValueFormat, POSITION( buffer->in_pos ) );    if ( error )      return error;    break;  case 2:    if ( index >= sp->spf.spf2.ValueCount )      return ERR(HB_Err_Invalid_SubTable);    error = Get_ValueRecord( gpi, &sp->spf.spf2.Value[index],			     sp->ValueFormat, POSITION( buffer->in_pos ) );    if ( error )      return error;    break;  default:    return ERR(HB_Err_Invalid_SubTable);  }  (buffer->in_pos)++;  return HB_Err_Ok;}/* LookupType 2 *//* PairSet */static HB_Error  Load_PairSet ( HB_PairSet*  ps,				HB_UShort     format1,				HB_UShort     format2,				HB_Stream     stream ){  HB_Error  error;  HB_UShort             n, m, count;  HB_UInt              base_offset;  HB_PairValueRecord*  pvr;  base_offset = FILE_Pos();  if ( ACCESS_Frame( 2L ) )    return error;  count = ps->PairValueCount = GET_UShort();  FORGET_Frame();  ps->PairValueRecord = NULL;  if ( ALLOC_ARRAY( ps->PairValueRecord, count, HB_PairValueRecord ) )    return error;  pvr = ps->PairValueRecord;  for ( n = 0; n < count; n++ )  {    if ( ACCESS_Frame( 2L ) )      goto Fail;    pvr[n].SecondGlyph = GET_UShort();    FORGET_Frame();    if ( format1 )    {      error = Load_ValueRecord( &pvr[n].Value1, format1,				base_offset, stream );      if ( error )	goto Fail;    }    if ( format2 )    {      error = Load_ValueRecord( &pvr[n].Value2, format2,				base_offset, stream );      if ( error )      {	if ( format1 )	  Free_ValueRecord( &pvr[n].Value1, format1 );	goto Fail;      }    }  }  return HB_Err_Ok;Fail:  for ( m = 0; m < n; m++ )  {    if ( format1 )      Free_ValueRecord( &pvr[m].Value1, format1 );    if ( format2 )      Free_ValueRecord( &pvr[m].Value2, format2 );  }  FREE( pvr );  return error;}static void  Free_PairSet( HB_PairSet*  ps,			   HB_UShort     format1,			   HB_UShort     format2 ){  HB_UShort             n, count;  HB_PairValueRecord*  pvr;  if ( ps->PairValueRecord )  {    count = ps->PairValueCount;    pvr   = ps->PairValueRecord;    for ( n = 0; n < count; n++ )    {      if ( format1 )	Free_ValueRecord( &pvr[n].Value1, format1 );      if ( format2 )	Free_ValueRecord( &pvr[n].Value2, format2 );    }    FREE( pvr );  }}/* PairPosFormat1 */static HB_Error  Load_PairPos1( HB_PairPosFormat1*  ppf1,				HB_UShort            format1,				HB_UShort            format2,				HB_Stream            stream ){  HB_Error  error;  HB_UShort     n, m, count;  HB_UInt      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 ) ) != HB_Err_Ok )      goto Fail;    (void)FILE_Seek( cur_offset );  }  return HB_Err_Ok;Fail:  for ( m = 0; m < n; m++ )    Free_PairSet( &ps[m], format1, format2 );  FREE( ps );  return error;}static void  Free_PairPos1( HB_PairPosFormat1*  ppf1,			    HB_UShort            format1,

⌨️ 快捷键说明

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