freetype显示中英文
freetype显示中英文
参考博客:
04.freetype显示中文_//查无此人的博客-CSDN博客_freetype 中文
freetype的安装与使用_explore_world的博客-CSDN博客_freetype安装
使用freetype来显示中文汉字和英文字符_mlove编程-CSDN博客
3.数码相框-通过freetype库实现矢量显示 - 诺谦 - 博客园 (cnblogs.com)
1 安装freetype
freetype-2.10.0.tar.gz
链接:https://pan.baidu.com/s/1RKOpPdyNfoAr_wPeo-m4nA
提取码:0jcy
./configure
make
sudo make install
安装完后会将freetype的头文件安装到/usr/local/include/freetype2目录下,库文件安装到/usr/local/lib目录下。
2 显示英文
完整代码:english.c
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <ft2build.h>
#include FT_FREETYPE_H
#define WIDTH 80/*打印的范围*/
#define HEIGHT 80
#define X 0/*文字坐标*/
#define Y 40
#define degrees (0.0)/*字体旋转的角度*/
/* origin is the upper left corner */
unsigned char image[HEIGHT][WIDTH];
/* Replace this function with something useful. */
void draw_bitmap( FT_Bitmap* bitmap, FT_Int x, FT_Int y)
{
FT_Int i, j, p, q;
FT_Int x_max = x + bitmap->width;
FT_Int y_max = y + bitmap->rows;
for ( i = x, p = 0; i < x_max; i++, p++ )
{
for ( j = y, q = 0; j < y_max; j++, q++ )
{
if ( i < 0 || j < 0 ||
i >= WIDTH || j >= HEIGHT )
continue;
image[j][i] |= bitmap->buffer[q * bitmap->width + p];
}
}
}
void show_image( void )
{
int i, j;
for ( i = 0; i < HEIGHT; i++ )
{
for ( j = 0; j < WIDTH; j++ )
putchar( image[i][j] == 0 ? ' '
: image[i][j] < 128 ? '+'
: '*' );
putchar( '\n' );
}
}
int main( int argc, char** argv )
{
FT_Library library;
FT_Face face;
FT_GlyphSlot slot;
FT_Matrix matrix; /* transformation matrix */
FT_Vector pen; /* untransformed origin */
FT_Error error;
char* text;
double angle;
int target_height;
int n, num_chars;
if ( argc != 1 )
{
fprintf ( stderr, "usage: %s font sample-text\n", argv[0] );
exit( 1 );
}
text = "ABC";/*需要显示的文本*/
num_chars = strlen( text );
angle = ( degrees / 360 ) * 3.14159 * 2;/*旋转degrees度*/
target_height = HEIGHT;
error = FT_Init_FreeType( &library ); /* initialize library */
/* error handling omitted */
error = FT_New_Face( library, "./msyh.ttc", 0, &face );/* create face object */
/* error handling omitted */
#if 0
/* use 50pt at 100dpi */
error = FT_Set_Char_Size( face, 50 * 64, 0, 30, 0 ); /* set character size */
/* error handling omitted */
#else
error = FT_Set_Pixel_Sizes( face, 24, 0);/*把字符像素设置为24*24像素, 0表示与另一个尺寸值相等*/
/* error handling omitted */
#endif
slot = face->glyph;
/*将角度转换成2*2的矩阵*/
matrix.xx = (FT_Fixed)( cos( angle ) * 0x10000L );
matrix.xy = (FT_Fixed)(-sin( angle ) * 0x10000L );
matrix.yx = (FT_Fixed)( sin( angle ) * 0x10000L );
matrix.yy = (FT_Fixed)( cos( angle ) * 0x10000L );
/*
*将该文字坐标转为笛卡尔坐标
*LCD的坐标原点是位于左上方
*笛卡尔坐标:表示坐标原点位于左下方(与LCD的y轴相反)
*所以转换之前填写坐标时,需要转换一下y轴值(总高度-y)
*转换成功后还需要转换回来(总高度-y)
*/
pen.x = X * 64;/*在坐标(X,Y)处显示*/
pen.y = ( target_height - Y ) * 64;/*target_height: LCD总高度*/
for ( n = 0; n < num_chars; n++ )
{
FT_Set_Transform( face, &matrix, &pen );
/*
*加载字形图像
*通过索引,从face中加载字形
*转为位图
*
*FT_LOAD_RENDER:表示直接将图像转为位图
*若想生成FT_RENDER_MODE_MONO(黑白图)类型,操作如下:FT_LOAD_RENDER | FT_LOAD_MONOCHROME
*生成出来的位图像素,每8个像素点便表示 face->glyph->bitmap->buffer[]里的一个字节.
*/
error = FT_Load_Char( face, text[n], FT_LOAD_RENDER );
if ( error )
continue;/* ignore errors */
/* now, draw to our target surface (convert position) */
draw_bitmap( &slot->bitmap,
slot->bitmap_left,
target_height - slot->bitmap_top );
/* increment pen position */
pen.x += slot->advance.x;
pen.y += slot->advance.y;
}
show_image();
FT_Done_Face ( face );
FT_Done_FreeType( library );
return 0;
}
/* EOF */
2.1编译运行
gcc -o english english.c -I /usr/local/include/freetype2/ -lfreetype -lm
-I:指定头文件目录
-lfreetype -lm:指定库文件
./english
3 增加中文显示功能
中文在unicode编码中是两个字符,英文是一个字符,如果这样写:char chin[]="韦东山g" 就会出现乱码。
原因如下:
0x97e6 0x4e1c 0x5c71 0x0067
韦东山g的unicode码,共占用了7个字节,所以chin数组有7个元素。而下面是一个一个元素输入进去转换再显示,所以0x97和0xe6就会被分开,认为是两个字符,所以出现了乱码。即使我们在程序上做处理,但是我们并不能分清哪些是中文(两个字符),哪些是英文(一个字符)。
如果用char存储汉字英文等,则还需要判断数据类型,而wchar_t刚好可以放一个unicode字符。
注意:wchar_t在windows占2byte,在linux占4bytes.
宽字符:wchar_t
头文件: #include<wchar.h>
通过**wcslen()**判断wchar_t数组大小
...
#include<wchar.h> //添加此行
...
void show_image( void )
{
int i, j;
for ( i = 0; i < HEIGHT; i++ )
{
printf("%02d",i);//添加此行(添加坐标打印信息)
...
}
}
int main( int argc,char** argv )
{
... ...
wchar_t *chinese_str=L"韦东山g"; //添加此行
... ...
for ( n = 0; n <wcslen(chinese_str); n++ ) //修改此行
{
FT_Set_Transform( face, 0, &pen ); //字体转换
/* load glyph image into the slot (erase previous one) */
error = FT_Load_Char( face, chinese_str[n], FT_LOAD_RENDER ); //修改此行
... ...
}
return 0;
}
完整代码:english_chinese.c
#include <stdio.h>
#include <string.h>
#include <math.h>
#include<wchar.h>
#include <ft2build.h>
#include FT_FREETYPE_H
#define WIDTH 80/*打印的范围*/
#define HEIGHT 80
#define X 0/*文字坐标*/
#define Y 40
#define degrees (0.0)/*字体旋转的角度*/
/* origin is the upper left corner */
unsigned char image[HEIGHT][WIDTH];
/* Replace this function with something useful. */
void draw_bitmap( FT_Bitmap* bitmap, FT_Int x, FT_Int y)
{
FT_Int i, j, p, q;
FT_Int x_max = x + bitmap->width;
FT_Int y_max = y + bitmap->rows;
for ( i = x, p = 0; i < x_max; i++, p++ )
{
for ( j = y, q = 0; j < y_max; j++, q++ )
{
if ( i < 0 || j < 0 ||
i >= WIDTH || j >= HEIGHT )
continue;
image[j][i] |= bitmap->buffer[q * bitmap->width + p];
}
}
}
void show_image( void )
{
int i, j;
for ( i = 0; i < HEIGHT; i++ )
{
printf("%02d",i);
for ( j = 0; j < WIDTH; j++ )
putchar( image[i][j] == 0 ? ' '
: image[i][j] < 128 ? '+'
: '*' );
putchar( '\n' );
}
}
int main( int argc, char** argv )
{
FT_Library library;
FT_Face face;
FT_GlyphSlot slot;
FT_Matrix matrix; /* transformation matrix */
FT_Vector pen; /* untransformed origin */
FT_Error error;
double angle;
int target_height;
int n;
wchar_t *chinese_str=L"韦东山g";
if ( argc != 1 )
{
fprintf ( stderr, "usage: %s font sample-text\n", argv[0] );
exit( 1 );
}
angle = ( degrees / 360 ) * 3.14159 * 2;/*旋转degrees度*/
target_height = HEIGHT;
error = FT_Init_FreeType( &library ); /* initialize library */
/* error handling omitted */
error = FT_New_Face( library, "./msyh.ttc", 0, &face );/* create face object */
/* error handling omitted */
#if 0
/* use 50pt at 100dpi */
error = FT_Set_Char_Size( face, 50 * 64, 0, 30, 0 ); /* set character size */
/* error handling omitted */
#else
error = FT_Set_Pixel_Sizes( face, 24, 0);/*把字符像素设置为24*24像素, 0表示与另一个尺寸值相等*/
/* error handling omitted */
#endif
slot = face->glyph;
/*将角度转换成2*2的矩阵*/
matrix.xx = (FT_Fixed)( cos( angle ) * 0x10000L );
matrix.xy = (FT_Fixed)(-sin( angle ) * 0x10000L );
matrix.yx = (FT_Fixed)( sin( angle ) * 0x10000L );
matrix.yy = (FT_Fixed)( cos( angle ) * 0x10000L );
/*
*将该文字坐标转为笛卡尔坐标
*LCD的坐标原点是位于左上方
*笛卡尔坐标:表示坐标原点位于左下方(与LCD的y轴相反)
*所以转换之前填写坐标时,需要转换一下y轴值(总高度-y)
*转换成功后还需要转换回来(总高度-y)
*/
pen.x = X * 64;/*在坐标(X,Y)处显示*/
pen.y = ( target_height - Y ) * 64;/*target_height: LCD总高度*/
for ( n = 0; n < wcslen(chinese_str); n++ )
{
FT_Set_Transform( face, &matrix, &pen );
/*
*加载字形图像
*通过索引,从face中加载字形
*转为位图
*
*FT_LOAD_RENDER:表示直接将图像转为位图
*若想生成FT_RENDER_MODE_MONO(黑白图)类型,操作如下:FT_LOAD_RENDER | FT_LOAD_MONOCHROME
*生成出来的位图像素,每8个像素点便表示 face->glyph->bitmap->buffer[]里的一个字节.
*/
error = FT_Load_Char( face, chinese_str[n], FT_LOAD_RENDER );
if ( error )
continue;/* ignore errors */
/* now, draw to our target surface (convert position) */
draw_bitmap( &slot->bitmap,
slot->bitmap_left,
target_height - slot->bitmap_top );
/* increment pen position */
pen.x += slot->advance.x;
pen.y += slot->advance.y;
}
show_image();
FT_Done_Face ( face );
FT_Done_FreeType( library );
return 0;
}
/* EOF */
3.1 编译运行
gcc -o english_chinese english_chinese.c -I /usr/local/include/freetype2/ -lfreetype -lm
./english_chinese

代码中定义的坐标是(0,40),而实际上很多字都会超出一点。
freetype库中有这么一张图片:

字母的一部分会超出基线一点。
在汉字中,都在原点上面是没有问题的,但是一些英文字母比如g等,都会在基线下面,所以为了兼容所有语言文字,就会把字拉倒基线下面一点,如上图所示。
上图中,xMin表示该字符在x坐标最小处,同理xMax,yMax,yMin。
adevance是本字符的大小,下个字符的位置就是本字符的原点加上advance,程序如下:
pen.x += slot->advance.x; //pen是下个字符的原点信息
pen.y += slot->advance.y;
freetype2/ -lfreetype -lm`
./english_chinese
[外链图片转存中…(img-TCaQAtO0-1621067450132)]
代码中定义的坐标是(0,40),而实际上很多字都会超出一点。
freetype库中有这么一张图片:
[外链图片转存中…(img-lnJxtUGm-1621067450133)]
字母的一部分会超出基线一点。
在汉字中,都在原点上面是没有问题的,但是一些英文字母比如g等,都会在基线下面,所以为了兼容所有语言文字,就会把字拉倒基线下面一点,如上图所示。
上图中,xMin表示该字符在x坐标最小处,同理xMax,yMax,yMin。
adevance是本字符的大小,下个字符的位置就是本字符的原点加上advance,程序如下:
pen.x += slot->advance.x; //pen是下个字符的原点信息
pen.y += slot->advance.y;

浙公网安备 33010602011771号