Freetype 获取宋体(simsun.ttc)12-17号字的位图并打印输出

C/C++第三方开源库的介绍和相关讨论
回复
头像
523066680
Administrator
Administrator
帖子: 573
注册时间: 2016年07月19日 12:14
联系:

Freetype 获取宋体(simsun.ttc)12-17号字的位图并打印输出

帖子 523066680 »

编辑 523066680
日期 2016-12

打印宋体中的固定尺寸字号的位图(这种位图没有经过 Hint 处理,边界清晰,适合小字体时显示)
对于一个字体包含的位图信息,以及支持多少字号的位图,可以通过
face->num_fixed_sizes 查询支持的字号数目,通过 face->available_sizes[n] 遍历那些包含位图的字号的值。

注意代码保存为 UTF8 格式
// Code By: 523066680
// Date: 2016-12
// 提取位图,以终端点阵形式画出

#include <wchar.h>
#include <stdio.h>
#include <ft2build.h>
#include FT_FREETYPE_H

#define FONTSIZE 16
#define SLOT_H (FONTSIZE + FONTSIZE/6)
#define SLOT_W (FONTSIZE + FONTSIZE/6)

int winID;
FT_Library library;
FT_Face face;

FT_GlyphSlot slot;
FT_Error error;
FT_Outline outline;
FT_Bitmap bitmap;

wchar_t ustr[] = L"中文ab";

void LoadGlyph(long symbol);
void LoadChar(long symbol);
void err( char str[] );

void printBinary( unsigned char n )
{
unsigned char value;

for (unsigned char i = 0; i < 8; i++)
{
value = (n >> (7-i) ) & 1;
printf("%d", value );
}
}

void display(void)
{
int ybegin = 0;
int xbegin = 0;
int yi;
int xi;
int value;

int n_text = sizeof( ustr )/sizeof( ustr[0] ) - 1;

unsigned char image[SLOT_H][SLOT_W];

memset(image, 2, SLOT_H * SLOT_W );

LoadChar( ustr[0] );
bitmap = slot->bitmap;

int w_byte = bitmap.width / 8 + !!(bitmap.width % 8);

//容器高度 - (bearingY + baseline) 作为y起点
ybegin = SLOT_H - (slot->bitmap_top + FONTSIZE/6);
xi = 0;
yi = SLOT_H - ybegin; //上下反转

//将1bit深度的位图数据装载到容器(image)中
for (int row = 0; row < bitmap.rows; row++ )
{
yi --;

if ( ( yi < 0 ) || ( yi >= SLOT_H ) )
continue;

xi = slot->bitmap_left;

for (int wi = 0; wi < bitmap.width; wi++ ) //只提取width范围内的bits 多余的0不管
{
value = ( bitmap.buffer[ row*w_byte + wi/8 ] >> ( 7 - wi%8 ) ) & 0b1;
image[yi][xi+wi] = value;
}
}

//直接输出
for (int i = 0; i < bitmap.rows * w_byte; i++ )
{
printBinary( bitmap.buffer[i] );
if ( i % 2 == 1) printf("\n");
}
printf("\n");

//处理好的位图数据输出(再次反向)
for (int ny = 0; ny < SLOT_H; ny ++)
{
for (int nx = 0; nx < SLOT_W; nx ++)
{
printf("%d", image[SLOT_H-ny-1][nx] );
}
printf("\n");
}
}

void ftinit(void)
{
char* filename;
filename = "C:/windows/fonts/simsun.ttc";

error = FT_Init_FreeType( &library );
error = FT_New_Face( library, filename, 0, &face );
if (error) err("load font-face error\n");

error = FT_Set_Char_Size( face, FONTSIZE*64, 0, 0, 0 );
if (error) err("Set Char Size error\n");

printf("Font fixed sizes:");
for ( int i = 0; i < face->num_fixed_sizes; i++ )
{
printf("%d ", face->available_sizes[i].size /64);
}
printf("\n");
}

void LoadChar(long symbol)
{
//symbol可以是unicode编码值
//FT_UInt index = FT_Get_Char_Index(face, symbol);
error = FT_Load_Char( face, symbol, FT_LOAD_RENDER );
slot = face->glyph;
}

int main( int argc, char** argv )
{
ftinit();
display();

FT_Done_Face ( face );
FT_Done_FreeType( library );
return 0;
}

void err( char str[] )
{
printf("%s", str);
exit(0);
}
输出
Font fixed sizes:12 13 14 15 16 17
0000010000000000
0000010000000000
0000010000000000
0000010000000000
1111111111100000
1000010000100000
1000010000100000
1000010000100000
1000010000100000
1000010000100000
1111111111100000
1000010000100000
0000010000000000
0000010000000000
0000010000000000
0000010000000000

222222222222222222
222222222222222222
220000010000022222
220000010000022222
220000010000022222
220000010000022222
221111111111122222
221000010000122222
221000010000122222
221000010000122222
221000010000122222
221000010000122222
221111111111122222
221000010000122222
220000010000022222
220000010000022222
220000010000022222
220000010000022222
第一个输出是直接的点阵,在多个不同字符并排显示的时候可能高低不平。以及右边有多余的0是作为填充的。
第二个是装载到一个固定大小的容器中,并且移动到合适的位置上,适合多个字体并排。

在处理过程中将 Y 反过来处理了,因为在一些图形接口中渲染位图,上下是反过来的。
回复

在线用户

正浏览此版面之用户: 没有注册用户 和 1 访客