FreeType 控制台渲染字形轮廓笔记
项目里用到了FreeType解析字体,这里只为了更方便入手FreeType,简单读取字体文件,并在控制台绘制制定字符轮廓,以字符A为例:
初始化FreeType,加载字体文件
#include <freetype2/ft2build.h> #include FT_FREETYPE_H #include <iostream> #include <math.h> using namespace std;
FT_Library ft; FT_Face face; //初始化字体库 FT_Init_FreeType(&ft); //加载字体文件 if (FT_New_Face(ft, "/usr/share/fonts/truetype/liberation/LiberationMono-Bold.ttf", 0, &face)) { fprintf(stderr, "无法加载字体文件\n"); return 1; } // 设置字体尺寸 FT_Set_Pixel_Sizes(face, 64, 54); FT_UInt glyphIndex = FT_Get_Char_Index(face, 'A');//加载字符A //加载字形数据 FT_Load_Glyph(face, glyphIndex, FT_LOAD_DEFAULT);
渲染字体
FT_Bitmap下的buffer字段数据格式
FT_Bitmap结构体存储字体位图数据信息,比如宽width、高rows、字体每行大小pitch(字节单位),buffer 位图二位数据起始位置
typedef struct FT_Bitmap_ { unsigned int rows;//高 unsigned int width;//宽 int pitch;//每行占用字节数 unsigned char* buffer;//位图数据起始位置 unsigned short num_grays;//灰度级别的数量,仅在灰度位图中使用。 unsigned char pixel_mode;//像素模式,存储位图数据格式 unsigned char palette_mode; void* palette; } FT_Bitmap;
buffer是存储字体位图数据二维数组的起始位置,二维数组存储每一个字体像素数据.
获取每一个像素,可以通过以下方式遍历获取:
for(int y = 0; y < bitmap.rows; y++) { for(int x = 0; x < bitmap.width; x++) { uint8_t pix = bitmap.buffer[y * bitmap.width + x]; } }
这里的bitmap就是FT_Bitmap, bitmap.buffer中 y * bitmap.width 是定位到像素点所在行, x是定位到像素点所在列, 这样行列组合起来定位到一个像素点, buffer是一个二维数组。
FT_RENDER_MODE_MONO下访问像素
在遍历二维数组获取像素时,如果渲染模式是FT_RENDER_MODE_MONO需要注意一下, FT_RENDER_MODE_MONO是以bit(只有两种值0或1)方式存储的每一个像素,1bit=1像素,所以就不能用以上的方式获取像素点了因为:
uint8_t = 1字节
1字节 = 8bit
也就是1字节存储了8个像素点
内存中最小单位就是字节,为了获取bit,需要做一些位操作,这里大致在FT_RENDER_MODE_MONO模式下获取某一个像素操作如下:
1. 计算出bit(像素点)所在字节位置
2. 计算出字节中bit(像素点)在字节中偏移位置方便右移操作
3. 通过位操作获取到像素点
这里简单画了一下,希望理解的是对的,以下是完整代码:
for(int y = 0; y < bitmap.rows; y++) { for(int x = 0; x < bitmap.width; x++) { int startByte = (y * (bitmap.pitch) + (x / 8)); int bitOffset = 7 - (x % 8); uint8_t v = *(bitmap.buffer + startByte); cout << (int)((v >> bitOffset) & 0x1); } cout << endl; }
FT_RENDER_MODE_NORMAL
默认渲染模式,每个像素的值表示该位置的像素的灰度级别,其中0表示最暗的颜色(黑色),255表示最亮的颜色(白色)
//FT_RENDER_MODE_NORMAL //1像素:1字节 FT_Render_Glyph(face->glyph, FT_RENDER_MODE_NORMAL); FT_Bitmap bitmap = face->glyph->bitmap; for(int y = 0; y < bitmap.rows; y++) { for(int x = 0; x < bitmap.width; x++) { cout << format((bitmap.buffer[y * bitmap.width + x]), 3) << " "; } cout << endl; }
打印出每一个像素值内容,每个像素长度是三,000表示黑,255表示白
000000000000000000000000000000000000000090255255255255255255255255255255200000000000000000000000000000000000000000000 000000000000000000000000000000000000000188255255255255255255255255255255255043000000000000000000000000000000000000000 000000000000000000000000000000000000032254255255255255255255255255255255255141000000000000000000000000000000000000000 000000000000000000000000000000000000129255255255255255255255255255255255255233005000000000000000000000000000000000000 000000000000000000000000000000000002224255255255255255255253255255255255255255081000000000000000000000000000000000000 000000000000000000000000000000000070255255255255255255251168255255255255255255180000000000000000000000000000000000000 000000000000000000000000000000000168255255255255255255195084255255255255255255252025000000000000000000000000000000000 000000000000000000000000000000018248255255255255255255122015251255255255255255255120000000000000000000000000000000000 000000000000000000000000000000109255255255255255255255046000191255255255255255255217000000000000000000000000000000000 000000000000000000000000000000207255255255255255255223000000112255255255255255255255060000000000000000000000000000000 000000000000000000000000000050255255255255255255255142000000031255255255255255255255159000000000000000000000000000000 000000000000000000000000000148255255255255255255255059000000000204255255255255255255244012000000000000000000000000000 000000000000000000000000008238255255255255255255227001000000000118255255255255255255255099000000000000000000000000000 000000000000000000000000089255255255255255255255142000000000000032255255255255255255255197000000000000000000000000000 000000000000000000000000188255255255255255255255056000000000000000201255255255255255255255040000000000000000000000000 000000000000000000000032254255255255255255255225001000000000000000115255255255255255255255138000000000000000000000000 000000000000000000000129255255255255255255255140000000000000000000029254255255255255255255231004000000000000000000000 000000000000000000002224255255255255255255255053000000000000000000000198255255255255255255255078000000000000000000000 000000000000000000070255255255255255255255222000000000000000000000000112255255255255255255255176000000000000000000000 000000000000000000168255255255255255255255137000000000000000000000000027254255255255255255255251023000000000000000000 000000000000000018248255255255255255255255051000000000000000000000000000195255255255255255255255117000000000000000000 000000000000000109255255255255255255255255255255255255255255255255255255255255255255255255255255215000000000000000000 000000000000000207255255255255255255255255255255255255255255255255255255255255255255255255255255255057000000000000000 000000000000050255255255255255255255255255255255255255255255255255255255255255255255255255255255255156000000000000000 000000000000148255255255255255255255255255255255255255255255255255255255255255255255255255255255255242011000000000000 000000000007238255255255255255255255255255255255255255255255255255255255255255255255255255255255255255096000000000000 000000000089255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255194000000000000 000000000188255255255255255255255235003000000000000000000000000000000000000000128255255255255255255255255037000000000 000000031254255255255255255255255157000000000000000000000000000000000000000000046255255255255255255255255135000000000 000000128255255255255255255255255075000000000000000000000000000000000000000000000219255255255255255255255229003000000 000001224255255255255255255255242007000000000000000000000000000000000000000000000138255255255255255255255255075000000 000069255255255255255255255255167000000000000000000000000000000000000000000000000056255255255255255255255255173000000 000168255255255255255255255255086000000000000000000000000000000000000000000000000001229255255255255255255255250021000 017248255255255255255255255247012000000000000000000000000000000000000000000000000000149255255255255255255255255114000 109255255255255255255255255178000000000000000000000000000000000000000000000000000000067255255255255255255255255212000 207255255255255255255255255096000000000000000000000000000000000000000000000000000000004236255255255255255255255255054
为了方便分析,按空格分开,每三个字符是一字节,也就是一个uint8_t
000 000 000 000 000 000 000 000 000 000 000 000 000 090 255 255 255 255 255 255 255 255 255 255 200 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 188 255 255 255 255 255 255 255 255 255 255 255 043 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 032 254 255 255 255 255 255 255 255 255 255 255 255 141 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 129 255 255 255 255 255 255 255 255 255 255 255 255 233 005 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 002 224 255 255 255 255 255 255 253 255 255 255 255 255 255 081 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 070 255 255 255 255 255 255 251 168 255 255 255 255 255 255 180 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 168 255 255 255 255 255 255 195 084 255 255 255 255 255 255 252 025 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 018 248 255 255 255 255 255 255 122 015 251 255 255 255 255 255 255 120 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 109 255 255 255 255 255 255 255 046 000 191 255 255 255 255 255 255 217 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 207 255 255 255 255 255 255 223 000 000 112 255 255 255 255 255 255 255 060 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 050 255 255 255 255 255 255 255 142 000 000 031 255 255 255 255 255 255 255 159 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 148 255 255 255 255 255 255 255 059 000 000 000 204 255 255 255 255 255 255 244 012 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 008 238 255 255 255 255 255 255 227 001 000 000 000 118 255 255 255 255 255 255 255 099 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 089 255 255 255 255 255 255 255 142 000 000 000 000 032 255 255 255 255 255 255 255 197 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 188 255 255 255 255 255 255 255 056 000 000 000 000 000 201 255 255 255 255 255 255 255 040 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 032 254 255 255 255 255 255 255 225 001 000 000 000 000 000 115 255 255 255 255 255 255 255 138 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 129 255 255 255 255 255 255 255 140 000 000 000 000 000 000 029 254 255 255 255 255 255 255 231 004 000 000 000 000 000 000 000 000 000 000 000 000 000 002 224 255 255 255 255 255 255 255 053 000 000 000 000 000 000 000 198 255 255 255 255 255 255 255 078 000 000 000 000 000 000 000 000 000 000 000 000 000 070 255 255 255 255 255 255 255 222 000 000 000 000 000 000 000 000 112 255 255 255 255 255 255 255 176 000 000 000 000 000 000 000 000 000 000 000 000 000 168 255 255 255 255 255 255 255 137 000 000 000 000 000 000 000 000 027 254 255 255 255 255 255 255 251 023 000 000 000 000 000 000 000 000 000 000 000 018 248 255 255 255 255 255 255 255 051 000 000 000 000 000 000 000 000 000 195 255 255 255 255 255 255 255 117 000 000 000 000 000 000 000 000 000 000 000 109 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 215 000 000 000 000 000 000 000 000 000 000 000 207 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 057 000 000 000 000 000 000 000 000 000 050 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 156 000 000 000 000 000 000 000 000 000 148 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 242 011 000 000 000 000 000 000 000 007 238 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 096 000 000 000 000 000 000 000 089 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 194 000 000 000 000 000 000 000 188 255 255 255 255 255 255 255 235 003 000 000 000 000 000 000 000 000 000 000 000 000 000 128 255 255 255 255 255 255 255 255 037 000 000 000 000 000 031 254 255 255 255 255 255 255 255 157 000 000 000 000 000 000 000 000 000 000 000 000 000 000 046 255 255 255 255 255 255 255 255 135 000 000 000 000 000 128 255 255 255 255 255 255 255 255 075 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 219 255 255 255 255 255 255 255 229 003 000 000 000 001 224 255 255 255 255 255 255 255 242 007 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 138 255 255 255 255 255 255 255 255 075 000 000 000 069 255 255 255 255 255 255 255 255 167 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 056 255 255 255 255 255 255 255 255 173 000 000 000 168 255 255 255 255 255 255 255 255 086 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 001 229 255 255 255 255 255 255 255 250 021 000 017 248 255 255 255 255 255 255 255 247 012 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 149 255 255 255 255 255 255 255 255 114 000 109 255 255 255 255 255 255 255 255 178 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 067 255 255 255 255 255 255 255 255 212 000 207 255 255 255 255 255 255 255 255 096 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 004 236 255 255 255 255 255 255 255 255 054
FT_RENDER_MODE_LIGHT
没有平滑处理,相对来说没有FT_RENDER_MODE_NORMAL平滑
FT_Render_Glyph(face->glyph, FT_RENDER_MODE_LIGHT); FT_Bitmap bitmap = face->glyph->bitmap; for(int y = 0; y < bitmap.rows; y++) { for(int x = 0; x < bitmap.width; x++) { cout << (bitmap.buffer[y * bitmap.width + x] > 0 ? 1 : 0); } cout << endl; }
FT_RENDER_MODE_MONO
二值图,1像素=1bit
//1像素:1bit //字形渲染到位图中 FT_Render_Glyph(face->glyph, FT_RENDER_MODE_MONO); FT_Bitmap bitmap = face->glyph->bitmap; cout << bitmap.pitch << endl; for(int y = 0; y < bitmap.rows; y++) { for(int x = 0; x < bitmap.width; x++) { int startByte = (y * (bitmap.pitch) + (x / 8)); int bitOffset = 7 - (x % 8); uint8_t v = *(bitmap.buffer + startByte); cout << (int)((v >> bitOffset) & 0x1); } cout << endl; }
00000000000011111111100000000000 00000000000111111111100000000000 00000000000111111111110000000000 00000000000111111111110000000000 00000000001111111111110000000000 00000000001111111111111000000000 00000000001111110111111000000000 00000000011111110111111000000000 00000000011111100111111000000000 00000000011111100111111100000000 00000000111111100011111100000000 00000000111111100011111100000000 00000000111111000011111110000000 00000001111111000011111110000000 00000001111111000001111110000000 00000001111110000001111111000000 00000011111110000001111111000000 00000011111110000000111111000000 00000011111110000000111111100000 00000111111100000000111111100000 00000111111100000000111111100000 00000111111111111111111111110000 00001111111111111111111111110000 00001111111111111111111111110000 00001111111111111111111111111000 00011111111111111111111111111000 00011111111111111111111111111000 00011111110000000000001111111100 00111111110000000000000111111100 00111111110000000000000111111100 00111111100000000000000111111110 01111111100000000000000111111110 01111111100000000000000011111110 01111111000000000000000011111111 11111111000000000000000011111111 11111111000000000000000001111111
FT_RENDER_MODE_LCD_V
FT_Render_Glyph(face->glyph, FT_RENDER_MODE_LCD_V); FT_Bitmap bitmap = face->glyph->bitmap; for(int y = 0; y < bitmap.rows; y++) { for(int x = 0; x < bitmap.width; x++) { cout << (bitmap.buffer[y * bitmap.width + x] > 0 ? 1 : 0); } cout << endl; }
000000000000000000000000000000000 000000000001111111111000000000000 000000000001111111111000000000000 000000000001111111111000000000000 000000000001111111111100000000000 000000000001111111111100000000000 000000000001111111111100000000000 000000000001111111111100000000000 000000000011111111111100000000000 000000000011111111111100000000000 000000000011111111111100000000000 000000000011111111111100000000000 000000000011111111111100000000000 000000000011111111111110000000000 000000000011111111111110000000000 000000000011111111111110000000000 000000000011111111111110000000000 000000000111111111111110000000000 000000000111111111111110000000000 000000000111111111111110000000000 000000000111111111111110000000000 000000000111111111111110000000000 000000000111111111111110000000000 000000000111111111111111000000000 000000000111111111111111000000000 000000000111111111111111000000000 000000000111111111111111000000000 000000001111111111111111000000000 000000001111111101111111000000000 000000001111111101111111000000000 000000001111111101111111000000000 000000001111111101111111000000000 000000001111111101111111100000000 000000001111111101111111100000000 000000001111111001111111100000000 000000001111111001111111100000000 000000011111111001111111100000000 000000011111111001111111100000000 000000011111111001111111100000000 000000011111111001111111100000000 000000011111111000111111100000000 000000011111111000111111110000000 000000011111111000111111110000000 000000011111111000111111110000000 000000011111110000111111110000000 000000111111110000111111110000000 000000111111110000111111110000000 000000111111110000111111110000000 000000111111110000111111110000000 000000111111110000111111110000000 000000111111110000011111111000000 000000111111110000011111111000000 000000111111110000011111111000000 000000111111110000011111111000000 000001111111110000011111111000000 000001111111100000011111111000000 000001111111100000011111111000000 000001111111100000011111111000000 000001111111100000011111111000000 000001111111100000011111111000000 000001111111100000011111111100000 000001111111100000001111111100000 000001111111100000001111111100000 000001111111100000001111111100000 000011111111111111111111111100000 000011111111111111111111111100000 000011111111111111111111111100000 000011111111111111111111111100000 000011111111111111111111111100000 000011111111111111111111111110000 000011111111111111111111111110000 000011111111111111111111111110000 000011111111111111111111111110000 000111111111111111111111111110000 000111111111111111111111111110000 000111111111111111111111111110000 000111111111111111111111111110000 000111111111111111111111111110000 000111111111111111111111111111000 000111111111111111111111111111000 000111111111111111111111111111000 000111111111111111111111111111000 001111111111111111111111111111000 001111111111111111111111111111000 001111111111111111111111111111000 001111111111111111111111111111000 001111111110000000000011111111000 001111111100000000000011111111000 001111111100000000000011111111100 001111111100000000000011111111100 001111111100000000000011111111100 011111111100000000000011111111100 011111111100000000000011111111100 011111111100000000000011111111100 011111111100000000000001111111100 011111111100000000000001111111100 011111111100000000000001111111100 011111111100000000000001111111110 011111111000000000000001111111110 011111111000000000000001111111110 011111111000000000000001111111110 111111111000000000000001111111110 111111111000000000000001111111110 111111111000000000000001111111110 111111111000000000000001111111110 111111111000000000000000111111110 111111111000000000000000111111111 111111111000000000000000111111111 111111111000000000000000111111111 111111111000000000000000111111111 111111110000000000000000111111111 111111110000000000000000111111111 111111110000000000000000111111111 000000000000000000000000000000000
FT_RENDER_MODE_SDF
FT_Render_Glyph(face->glyph, FT_RENDER_MODE_SDF); FT_Bitmap bitmap = face->glyph->bitmap; for(int y = 0; y < bitmap.rows; y++) { for(int x = 0; x < bitmap.width; x++) { const char* asciiChars = "@%#*+=-:. "; int numChars = strlen(asciiChars); unsigned char intensity = bitmap.buffer[y * bitmap.width + x]; int index = intensity * numChars / 256; cout << index; } cout << endl; }
0000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000 0000000000000000111111111111111100000000000000000 0000000000000001112222222222221110000000000000000 0000000000000011222222222222222211000000000000000 0000000000000011223333333333333221100000000000000 0000000000000112233444444444433321100000000000000 0000000000000112334444444444443322100000000000000 0000000000000122334555555555544322110000000000000 0000000000001122344555555555544332110000000000000 0000000000001123344556666666554332210000000000000 0000000000001223345566655666554432211000000000000 0000000000011223345566655566554433211000000000000 0000000000011233445566555566655433221000000000000 0000000000011233445666554566655443221100000000000 0000000000112233455666554556655443321100000000000 0000000000112234455666544556665543322100000000000 0000000000112334456665544556665544322110000000000 0000000000122334556665544456665544332110000000000 0000000001122344556665544455666554332210000000000 0000000001123344566665444455666554432211000000000 0000000001223345566655443455666554433211000000000 0000000011223445566655433445666655433221000000000 0000000011233445666654433445566655433221100000000 0000000012233455666554433345566655443321100000000 0000000112234455666554433344566665443321100000000 0000000112334456666554333344556665543322110000000 0000000122334556666544444444556665544322110000000 0000001122344556765544444444556666544332110000000 0000001123344566765555555555556666554332210000000 0000001223345566766555555555566776554432211000000 0000011223445567776666666666666776654433211000000 0000011233445667666666666666666676655433221000000 0000012233455666665555555555555667655443221100000 0000112234455666655555555555555567665443321100000 0000112334456676554444444444445566665543322100000 0000122334556666554444444444444566765544322110000 0001122344556666554333333333344556766544332110000 0001123344566766544332222222344556666554332210000 0001223345566765544322222222334556676554432211000 0011223445566665543322111112334456676654433211000 0011233445566665543321100112234455666655433221000 0012233455555555443321100012233455555555443221100 0012234455555555443221100011233455555555443321100 0012234444444444433221000011233444444444443321100 0012233444444444333211000011223344444444433221100 0011223333333333332211000001122333333333332221000 0001122222222222222110000001122222222222222211000 0001112222222222211100000000111222222222221110000 0000011111111111111000000000011111111111111100000 0000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000