pfrobjs.c

来自「奇趣公司比较新的qt/emd版本」· C语言 代码 · 共 577 行 · 第 1/2 页

C
577
字号
    pfr_glyph_done( &slot->glyph );  }  FT_LOCAL_DEF( FT_Error )  pfr_slot_load( FT_GlyphSlot  pfrslot,         /* PFR_Slot */                 FT_Size       pfrsize,         /* PFR_Size */                 FT_UInt       gindex,                 FT_Int32      load_flags )  {    PFR_Slot     slot    = (PFR_Slot)pfrslot;    PFR_Size     size    = (PFR_Size)pfrsize;    FT_Error     error;    PFR_Face     face    = (PFR_Face)pfrslot->face;    PFR_Char     gchar;    FT_Outline*  outline = &pfrslot->outline;    FT_ULong     gps_offset;    if ( gindex > 0 )      gindex--;    if ( !face || gindex >= face->phy_font.num_chars )    {      error = PFR_Err_Invalid_Argument;      goto Exit;    }    /* try to load an embedded bitmap */    if ( ( load_flags & ( FT_LOAD_NO_SCALE | FT_LOAD_NO_BITMAP ) ) == 0 )    {      error = pfr_slot_load_bitmap( slot, size, gindex );      if ( error == 0 )        goto Exit;    }    if ( load_flags & FT_LOAD_SBITS_ONLY )    {      error = PFR_Err_Invalid_Argument;      goto Exit;    }    gchar               = face->phy_font.chars + gindex;    pfrslot->format     = FT_GLYPH_FORMAT_OUTLINE;    outline->n_points   = 0;    outline->n_contours = 0;    gps_offset          = face->header.gps_section_offset;    /* load the glyph outline (FT_LOAD_NO_RECURSE isn't supported) */    error = pfr_glyph_load( &slot->glyph, face->root.stream,                            gps_offset, gchar->gps_offset, gchar->gps_size );    if ( !error )    {      FT_BBox            cbox;      FT_Glyph_Metrics*  metrics = &pfrslot->metrics;      FT_Pos             advance;      FT_Int             em_metrics, em_outline;      FT_Bool            scaling;      scaling = FT_BOOL( ( load_flags & FT_LOAD_NO_SCALE ) == 0 );      /* copy outline data */      *outline = slot->glyph.loader->base.outline;      outline->flags &= ~FT_OUTLINE_OWNER;      outline->flags |= FT_OUTLINE_REVERSE_FILL;      if ( size && pfrsize->metrics.y_ppem < 24 )        outline->flags |= FT_OUTLINE_HIGH_PRECISION;      /* compute the advance vector */      metrics->horiAdvance = 0;      metrics->vertAdvance = 0;      advance    = gchar->advance;      em_metrics = face->phy_font.metrics_resolution;      em_outline = face->phy_font.outline_resolution;      if ( em_metrics != em_outline )        advance = FT_MulDiv( advance, em_outline, em_metrics );      if ( face->phy_font.flags & PFR_PHY_VERTICAL )        metrics->vertAdvance = advance;      else        metrics->horiAdvance = advance;      pfrslot->linearHoriAdvance = metrics->horiAdvance;      pfrslot->linearVertAdvance = metrics->vertAdvance;      /* make-up vertical metrics(?) */      metrics->vertBearingX = 0;      metrics->vertBearingY = 0;#if 0 /* some fonts seem to be broken here! */      /* Apply the font matrix, if any.                 */      /* TODO: Test existing fonts with unusual matrix  */      /* whether we have to adjust Units per EM.        */      {        FT_Matrix font_matrix;        font_matrix.xx = face->log_font.matrix[0] << 8;        font_matrix.yx = face->log_font.matrix[1] << 8;        font_matrix.xy = face->log_font.matrix[2] << 8;        font_matrix.yy = face->log_font.matrix[3] << 8;        FT_Outline_Transform( outline, &font_matrix );      }#endif      /* scale when needed */      if ( scaling )      {        FT_Int      n;        FT_Fixed    x_scale = pfrsize->metrics.x_scale;        FT_Fixed    y_scale = pfrsize->metrics.y_scale;        FT_Vector*  vec     = outline->points;        /* scale outline points */        for ( n = 0; n < outline->n_points; n++, vec++ )        {          vec->x = FT_MulFix( vec->x, x_scale );          vec->y = FT_MulFix( vec->y, y_scale );        }        /* scale the advance */        metrics->horiAdvance = FT_MulFix( metrics->horiAdvance, x_scale );        metrics->vertAdvance = FT_MulFix( metrics->vertAdvance, y_scale );      }      /* compute the rest of the metrics */      FT_Outline_Get_CBox( outline, &cbox );      metrics->width        = cbox.xMax - cbox.xMin;      metrics->height       = cbox.yMax - cbox.yMin;      metrics->horiBearingX = cbox.xMin;      metrics->horiBearingY = cbox.yMax - metrics->height;    }  Exit:    return error;  }  /*************************************************************************/  /*************************************************************************/  /*****                                                               *****/  /*****                      KERNING METHOD                           *****/  /*****                                                               *****/  /*************************************************************************/  /*************************************************************************/  FT_LOCAL_DEF( FT_Error )  pfr_face_get_kerning( FT_Face     pfrface,        /* PFR_Face */                        FT_UInt     glyph1,                        FT_UInt     glyph2,                        FT_Vector*  kerning )  {    PFR_Face     face     = (PFR_Face)pfrface;    FT_Error     error    = PFR_Err_Ok;    PFR_PhyFont  phy_font = &face->phy_font;    FT_UInt32    code1, code2, pair;    kerning->x = 0;    kerning->y = 0;    if ( glyph1 > 0 )      glyph1--;    if ( glyph2 > 0 )      glyph2--;    /* convert glyph indices to character codes */    if ( glyph1 > phy_font->num_chars ||         glyph2 > phy_font->num_chars )      goto Exit;    code1 = phy_font->chars[glyph1].char_code;    code2 = phy_font->chars[glyph2].char_code;    pair  = PFR_KERN_INDEX( code1, code2 );    /* now search the list of kerning items */    {      PFR_KernItem  item   = phy_font->kern_items;      FT_Stream     stream = pfrface->stream;      for ( ; item; item = item->next )      {        if ( pair >= item->pair1 && pair <= item->pair2 )          goto FoundPair;      }      goto Exit;    FoundPair: /* we found an item, now parse it and find the value if any */      if ( FT_STREAM_SEEK( item->offset )                       ||           FT_FRAME_ENTER( item->pair_count * item->pair_size ) )        goto Exit;      {        FT_UInt    count       = item->pair_count;        FT_UInt    size        = item->pair_size;        FT_UInt    power       = (FT_UInt)ft_highpow2( (FT_UInt32)count );        FT_UInt    probe       = power * size;        FT_UInt    extra       = count - power;        FT_Byte*   base        = stream->cursor;        FT_Bool    twobytes    = FT_BOOL( item->flags & 1 );        FT_Bool    twobyte_adj = FT_BOOL( item->flags & 2 );        FT_Byte*   p;        FT_UInt32  cpair;        if ( extra > 0 )        {          p = base + extra * size;          if ( twobytes )            cpair = FT_NEXT_ULONG( p );          else            cpair = PFR_NEXT_KPAIR( p );          if ( cpair == pair )            goto Found;          if ( cpair < pair )          {            if ( twobyte_adj )              p += 2;            else              p++;            base = p;          }        }        while ( probe > size )        {          probe >>= 1;          p       = base + probe;          if ( twobytes )            cpair = FT_NEXT_ULONG( p );          else            cpair = PFR_NEXT_KPAIR( p );          if ( cpair == pair )            goto Found;          if ( cpair < pair )            base += probe;        }        p = base;        if ( twobytes )          cpair = FT_NEXT_ULONG( p );        else          cpair = PFR_NEXT_KPAIR( p );        if ( cpair == pair )        {          FT_Int  value;        Found:          if ( twobyte_adj )            value = FT_PEEK_SHORT( p );          else            value = p[0];          kerning->x = item->base_adj + value;        }      }      FT_FRAME_EXIT();    }  Exit:    return error;  }/* END */

⌨️ 快捷键说明

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