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

📄 ftxgpos.c

📁 字体缩放显示
💻 C
📖 第 1 页 / 共 5 页
字号:
    if ( format & HAVE_X_ID_ADVANCE )    {      if ( ACCESS_Frame( 2L ) )        goto Fail1;      vr->XIdAdvance = GET_UShort();      FORGET_Frame();    }    else      vr->XIdAdvance = 0;    if ( format & HAVE_Y_ID_ADVANCE )    {      if ( ACCESS_Frame( 2L ) )        goto Fail1;      vr->YIdAdvance = GET_UShort();      FORGET_Frame();    }    else      vr->YIdAdvance = 0;    return TT_Err_Ok;  Fail1:    Free_Device( &vr->YAdvanceDevice );  Fail2:    Free_Device( &vr->XAdvanceDevice );  Fail3:    Free_Device( &vr->YPlacementDevice );    return error;  }  static void  Free_ValueRecord( TTO_ValueRecord*  vr,                                 UShort            format )  {    if ( format & HAVE_Y_ADVANCE_DEVICE )      Free_Device( &vr->YAdvanceDevice );    if ( format & HAVE_X_ADVANCE_DEVICE )      Free_Device( &vr->XAdvanceDevice );    if ( format & HAVE_Y_PLACEMENT_DEVICE )      Free_Device( &vr->YPlacementDevice );    if ( format & HAVE_X_PLACEMENT_DEVICE )      Free_Device( &vr->XPlacementDevice );  }  static TT_Error  Get_ValueRecord( GPOS_Instance*    gpi,                                    TTO_ValueRecord*  vr,                                    UShort            format,                                    TTO_GPOS_Data*    gd )  {    TT_Pos           value;    Short            pixel_value;    TT_Error         error = TT_Err_Ok;    TTO_GPOSHeader*  gpos = gpi->gpos;    PInstance        ins;    UShort     x_ppem, y_ppem;    Fixed      x_scale, y_scale;    if ( !format )      return TT_Err_Ok;    ins = HANDLE_Instance( gpi->instance );    x_ppem  = ins->metrics.x_ppem;    y_ppem  = ins->metrics.y_ppem;    x_scale = TT_MulDiv( 0x10000,                         ins->metrics.x_scale1,                         ins->metrics.x_scale2 );    y_scale = TT_MulDiv( 0x10000,                         ins->metrics.y_scale1,                         ins->metrics.y_scale2 );    /* design units -> fractional pixel */    if ( format & HAVE_X_PLACEMENT )      gd->x_pos += x_scale * vr->XPlacement / 0x10000;    if ( format & HAVE_Y_PLACEMENT )      gd->y_pos += y_scale * vr->YPlacement / 0x10000;    if ( format & HAVE_X_ADVANCE )      gd->x_advance += x_scale * vr->XAdvance / 0x10000;    if ( format & HAVE_Y_ADVANCE )      gd->y_advance += y_scale * vr->YAdvance / 0x10000;    /* we use the device tables only if gpi->glyph.z is not NULL */    if ( gpi->glyph.z )    {      /* pixel -> fractional pixel */      if ( format & HAVE_X_PLACEMENT_DEVICE )      {        Get_Device( &vr->XPlacementDevice, x_ppem, &pixel_value );        gd->x_pos += pixel_value << 6;      }      if ( format & HAVE_Y_PLACEMENT_DEVICE )      {        Get_Device( &vr->YPlacementDevice, y_ppem, &pixel_value );        gd->y_pos += pixel_value << 6;      }      if ( format & HAVE_X_ADVANCE_DEVICE )      {        Get_Device( &vr->XAdvanceDevice, x_ppem, &pixel_value );        gd->x_advance += pixel_value << 6;      }      if ( format & HAVE_Y_ADVANCE_DEVICE )      {        Get_Device( &vr->YAdvanceDevice, y_ppem, &pixel_value );        gd->y_advance += pixel_value << 6;      }    }    /* values returned from mmfunc() are already in fractional pixels */    if ( format & HAVE_X_ID_PLACEMENT )    {      error = (gpos->mmfunc)( gpi->instance, vr->XIdPlacement,                              &value, gpos->data );      if ( error )        return error;      gd->x_pos += value;    }    if ( format & HAVE_Y_ID_PLACEMENT )    {      error = (gpos->mmfunc)( gpi->instance, vr->YIdPlacement,                              &value, gpos->data );      if ( error )        return error;      gd->y_pos += value;    }    if ( format & HAVE_X_ID_ADVANCE )    {      error = (gpos->mmfunc)( gpi->instance, vr->XIdAdvance,                              &value, gpos->data );      if ( error )        return error;      gd->x_advance += value;    }    if ( format & HAVE_Y_ID_ADVANCE )    {      error = (gpos->mmfunc)( gpi->instance, vr->YIdAdvance,                              &value, gpos->data );      if ( error )        return error;      gd->y_advance += value;    }    return error;  }  /* AnchorFormat1 */  /* AnchorFormat2 */  /* AnchorFormat3 */  /* AnchorFormat4 */  static TT_Error  Load_Anchor( TTO_Anchor*  an,                                PFace        input )  {    DEFINE_LOAD_LOCALS( input->stream );    ULong    cur_offset, new_offset, base_offset;    base_offset = FILE_Pos();    if ( ACCESS_Frame( 2L ) )      return error;    an->PosFormat = GET_UShort();    FORGET_Frame();    switch ( an->PosFormat )    {    case 1:      if ( ACCESS_Frame( 4L ) )        return error;      an->af.af1.XCoordinate = GET_Short();      an->af.af1.YCoordinate = GET_Short();      FORGET_Frame();      break;    case 2:      if ( ACCESS_Frame( 6L ) )        return error;      an->af.af2.XCoordinate = GET_Short();      an->af.af2.YCoordinate = GET_Short();      an->af.af2.AnchorPoint = GET_UShort();      FORGET_Frame();      break;    case 3:      if ( ACCESS_Frame( 6L ) )        return error;      an->af.af3.XCoordinate = GET_Short();      an->af.af3.YCoordinate = GET_Short();      new_offset = GET_UShort();      FORGET_Frame();      if ( new_offset )      {        new_offset += base_offset;        cur_offset = FILE_Pos();        if ( FILE_Seek( new_offset ) ||             ( error = Load_Device( &an->af.af3.XDeviceTable,                                    input ) ) != TT_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 = 0;      }      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 = Load_Device( &an->af.af3.YDeviceTable,                                    input ) ) != TT_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 = 0;      }      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 TTO_Err_Invalid_GPOS_SubTable_Format;    }    return TT_Err_Ok;  Fail:    Free_Device( &an->af.af3.XDeviceTable );    return error;  }  static void  Free_Anchor( TTO_Anchor*  an )  {    if ( an->PosFormat == 3 )    {      Free_Device( &an->af.af3.YDeviceTable );      Free_Device( &an->af.af3.XDeviceTable );    }  }  static TT_Error  Get_Anchor( GPOS_Instance*   gpi,                               TTO_Anchor*      an,                               TT_UShort        glyph_index,                               TT_Pos*          x_value,                               TT_Pos*          y_value )  {    TT_Error  error = TT_Err_Ok;    PInstance        ins;    PGlyph           glyph;    TTO_GPOSHeader*  gpos = gpi->gpos;    UShort           ap;    Short            pixel_value;    UShort           load_flags;    UShort           x_ppem, y_ppem;    Fixed            x_scale, y_scale;    ins = HANDLE_Instance( gpi->instance );    x_ppem  = ins->metrics.x_ppem;    y_ppem  = ins->metrics.y_ppem;    x_scale = TT_MulDiv( 0x10000,                         ins->metrics.x_scale1,                         ins->metrics.x_scale2 );    y_scale = TT_MulDiv( 0x10000,                         ins->metrics.y_scale1,                         ins->metrics.y_scale2 );    switch ( an->PosFormat )    {    case 0:      /* The special case of an empty AnchorTable */      return TTO_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 | TTLOAD_SCALE_GLYPH;      /* we use the glyph contour point only if gpi->glyph.z is not NULL */      if ( gpi->glyph.z )      {        error = (gpos->gfunc)( gpi->instance, gpi->glyph,                               glyph_index, load_flags );        if ( error )          return error;        glyph = HANDLE_Glyph( gpi->glyph );        ap    = an->af.af2.AnchorPoint;        /* if outline.n_points is set to zero by gfunc(), we use the           design coordinate value pair.  This can happen e.g. for           sbit glyphs                                               */        if ( !glyph->outline.n_points )          goto no_contour_point;        if ( ap >= glyph->outline.n_points )          return TTO_Err_Invalid_GPOS_SubTable;        *x_value = glyph->outline.points[ap].x;        *y_value = glyph->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:      /* we use the device tables only if gpi->glyph.z is not NULL */      if ( gpi->glyph.z )      {        Get_Device( &an->af.af3.XDeviceTable, x_ppem, &pixel_value );        *x_value = pixel_value << 6;        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->instance, an->af.af4.XIdAnchor,                              x_value, gpos->data );      if ( error )        return error;      error = (gpos->mmfunc)( gpi->instance, an->af.af4.YIdAnchor,                              y_value, gpos->data );      if ( error )        return error;      break;    }    return error;  }  /* MarkArray */  static TT_Error  Load_MarkArray ( TTO_MarkArray*  ma,                                    PFace           input )  {    DEFINE_LOAD_LOCALS( input->stream );    UShort           n, count;    ULong            cur_offset, new_offset, base_offset;    TTO_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, TTO_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, input ) ) != TT_Err_Ok )        goto Fail;      (void)FILE_Seek( cur_offset );    }    return TT_Err_Ok;  Fail:    for ( n = 0; n < count; n++ )      Free_Anchor( &mr[n].MarkAnchor );    FREE( mr );    return error;  }  static void  Free_MarkArray( TTO_MarkArray*  ma )  {    UShort           n, count;    TTO_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 */  TT_Error  Load_SinglePos( TTO_SinglePos*  sp,                            PFace           input )  {    DEFINE_LOAD_LOCALS( input->stream );    UShort            n, count, format;    ULong             cur_offset, new_offset, base_offset;    TTO_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 TTO_Err_Invalid_GPOS_SubTable;    cur_offset = FILE_Pos();    if ( FILE_Seek( new_offset ) ||         ( error = Load_Coverage( &sp->Coverage, input ) ) != TT_Err_Ok )      return error;    (void)FILE_Seek( cur_offset );    switch ( sp->PosFormat )    {    case 1:      error = Load_ValueRecord( &sp->spf.spf1.Value, format,                                base_offset, input );      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;

⌨️ 快捷键说明

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