FreeType 2字符的精确大小和精确位置

FreeType 2 character exact size and exact position

本文关键字:位置 FreeType 字符      更新时间:2023-10-16

用ttf字体做一些实验,并尝试使用著名的字体渲染库FreeType, version 2.5.3

我代码:

#include "ft2build.h"
#include FT_FREETYPE_H
#define FONTPATH "<font path here>"
const char* fontfile=FONTPATH "<fontname here>.TTF";
const int w=25;
const int h=25;
char* outbitmap;
int main() {
    outbitmap=new char[w*h];
    memset(outbitmap,0,w*h);
    FT_Library ftl;
    FT_Error err=FT_Init_FreeType(&ftl);
    FT_Face fface;
    err=FT_New_Face(ftl,fontfile,0,&fface);
    err=FT_Set_Pixel_Sizes(fface,w,h);
    FT_UInt ch;
    //ch=0x3042; //あ
    //ch='_';
    ch='|';
    FT_UInt chridx=FT_Get_Char_Index(fface,ch);
    err=FT_Load_Glyph(fface,chridx,FT_LOAD_DEFAULT);
    err=FT_Render_Glyph(fface->glyph,FT_RENDER_MODE_NORMAL);
    for(int y=0;y<fface->glyph->bitmap.rows;++y) {
        int outy=fface->glyph->bitmap.rows-fface->glyph->bitmap_top+y; //???how to get baseline position
        for(int x=0;x<fface->glyph->bitmap.width;++x) {
            int outx=fface->glyph->bitmap_left+x;
            outbitmap[outy*w+outx]=fface->glyph->bitmap.buffer[fface->glyph->bitmap.width*y+x];
        }
    }
    delete[] outbitmap;
    err=FT_Done_Face(fface);
    err=FT_Done_FreeType(ftl);
    return 0;
}

所以我有一些问题。假设我需要在正确的位置将一个字符呈现为固定大小的字节数组。字符大小必须符合输出位图的大小,不允许剪切。完全忽略字距也是可以的。

  1. 我指定字符宽度=高度=25。但对于'|',它给出face->glyph->bitmap.rows==26。我应该如何设置高度,以获得准确的25px输出,而不是26,任何正常字体?如果不是的话有可能,那么是否有任何方法可以精确地计算输出字符高度在像素之前FT_Render_Glyph。FT_Set_Pixel_Sizes的效果不够好,所以我有时会得到+1px

  2. 如何获得任何给定字体的基线位置?如果我有基线,我就可以放置角色在正确的位置。我没有1000x1000的屏幕,只有一个25x25的位图。

这是超级晚,但我刚刚发现如何做到这一点:

  1. (以像素为单位获取字符高度)。根据我的理解,设置字体大小(例如FT_Set_Char_Size)实际上只是定义了字体单位和像素单位之间的缩放(这解释得更多)。例如,72dpi下的12pt字体并不一定意味着字形是12像素高。但是,您可以获得一个边界框,我非常确定它将包含所选字体中的每个字形。我是这样做的:
<>之前//12 pt字体Double font_size = 12.0;//分辨率是指DPIDouble pixel_size = font_size * resolution/72;//以像素为单位的字体高度和宽度Int font_height = round((face->bbox);*pixel_size/face->units_per_EM);Int font_width = round((face->bbox);*pixel_size/face->units_per_EM);之前这就是我如何得到一个基线高度。这是所有象形文字的最大下降幅度。当与上述代码配对时,在此位置使用基线绘制字形应确保所有字形都适合边界框。<>之前//如果DPI不为72,将其转换为pixel_sizeDouble font_size = 12.0;//高度(以像素为单位)double baseline_height = abs(face->descender) * font_size/face->units_per_EM;之前

(其中face是您加载的字体)。

编辑:忘记考虑DPI,在我的应用程序中,我只是使用72,所以它取消了

没有人回答任何问题,所以张贴了一些变通办法,而不是我自己找到的答案。

对于问题1,在应用以下内容后,我可能可以接受它:

FT_Set_Pixel_Sizes(fface,w-1,h-1);

或者

FT_Set_Pixel_Sizes(fface,w-w%2,h-h%2);

问题2 I don't know yet .