FreeType 是一个开源的字体渲染库,用于将字体文件中的字符转换为位图或矢量图形。
先安装一下freetype开发包
sudo apt-get install libfreetype6-dev
基本使用流程
一、初始化 FreeType
#include <ft2build.h>
#include FT_FREETYPE_H
FT_Library library;
FT_Error error = FT_Init_FreeType(&library);
if (error) {
}
二、加载字体文件
FT_Face face;
error = FT_New_Face(library, "path/to/font.ttf", 0, &face);
if (error == FT_Err_Unknown_File_Format) {
} else if (error) {
}
三、设置字符大小
error = FT_Set_Pixel_Sizes(face, 0, 16);
四、加载和渲染字符
FT_UInt glyph_index = FT_Get_Char_Index(face, 'A');
error = FT_Load_Glyph(face, glyph_index, FT_LOAD_DEFAULT);
error = FT_Render_Glyph(face->glyph, FT_RENDER_MODE_NORMAL);
FT_Bitmap bitmap = face->glyph->bitmap;
unsigned char* buffer = bitmap.buffer;
int width = bitmap.width;
int rows = bitmap.rows;
int pitch = bitmap.pitch;
示例
#include "drm-core.h"
#include <ft2build.h>
#include <math.h>
#include FT_FREETYPE_H
#include FT_GLYPH_H
uint32_t color_table[6] = {RED,GREEN,BLUE,BLACK,WHITE,BLACK_BLUE};
uint32_t fcolor=RED;
void show_pixel(uint32_t x , uint32_t y , uint32_t color)
{
if(x > buf.width || y > buf.height)
printf("wrong set\n");
if(color!=0) buf.vaddr[ y*buf.width + x] = fcolor;
}
int utf_8_to_unicode_string(uint8_t *utf_8,uint16_t *word)
{
int len = 0;
int utf_8_size = strlen(utf_8);
int utf_8_len = 0;
uint16_t unicode[2];
while(utf_8_size > 0){
if(utf_8[utf_8_len] < 0x80){
unicode[0] = 0;
unicode[1] = utf_8[utf_8_len];
word[len] = (unicode[0]<<8) | unicode[1];
len ++;
utf_8_len ++;
utf_8_size--;
continue;
}
else if(utf_8[utf_8_len] > 0xc0 & utf_8[utf_8_len] <0xe0){
unicode[1] = (utf_8[utf_8_len+1]&0x3f) | ((utf_8[utf_8_len]<< 6)& 0xc0 );
unicode[0] = ((utf_8[utf_8_len]>>2) & 0x07) ;
word[len] = (unicode[0]<<8) | unicode[1];
len ++;
utf_8_len +=2;
utf_8_size -=2;
continue;
}
else if(utf_8[utf_8_len] > 0xe0 & utf_8[utf_8_len]<0xf0){
unicode[1] = (utf_8[utf_8_len+2]&0x3f) | ((utf_8[utf_8_len+1] << 6)& 0xc0);
unicode[0] = ((utf_8[utf_8_len+1]>>2)&0x0f) | ((utf_8[utf_8_len] <<4)& 0xf0) ;
word[len] = (unicode[0]<<8) | unicode[1];
len ++;
utf_8_len +=3;
utf_8_size -=3;
continue;
}
else
return -1;
}
return len;
}
void draw_bitmap( FT_Bitmap* bitmap,FT_Int x_ori,FT_Int y_ori)
{
FT_Int x, y;
FT_Int x_count, y_count;
unsigned char show;
uint32_t buffer_size = bitmap->width * bitmap->rows;
uint8_t buffer[buffer_size];
uint32_t color;
FT_Int x_max = x_ori + bitmap->width;
FT_Int y_max = y_ori + bitmap->rows;
memcpy(buffer,bitmap->buffer,buffer_size);
for ( y = y_ori, y_count = 0; y < y_max; y++, y_count++ ){
for ( x = x_ori, x_count = 0; x < x_max; x++, x_count++ ){
if ( x < 0 || y < 0 || x >= buf.width || y >= buf.height )
continue;
show = buffer[y_count * bitmap->width + x_count];
if(show > 0)
color = (show&0xff)|((show&0xff)<<8)|((show&0xff)<<16);
else
color=0;
show_pixel(x, y , color);
}
}
}
int freetype_set_char(FT_Face face , int lcd_x,int lcd_y ,int font_size,int angle_degree,uint16_t word)
{
FT_Matrix matrix;
FT_Vector pen;
int charIdx;
FT_GlyphSlot slot= face->glyph;;
double angle;
int error;
FT_Set_Pixel_Sizes(face, font_size, 0);
angle = (1.0 * angle_degree/360) * 3.14159 * 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 );
FT_Set_Transform(face, &matrix, 0);
error = FT_Load_Char( face, word, FT_LOAD_RENDER );
if (error){
printf("FT_Load_Char error\n");
return -1;
}
draw_bitmap( &slot->bitmap,lcd_x, lcd_y );
return 0;
}
int main(int argc, char **argv)
{
int i,j,count;
FT_Library library;
FT_Face face;
int error;
int font_size = 180;
int angle_degree = 0;
unsigned char str1[] = "创龙科技";
unsigned char str2[] = "电子发烧友论坛";
unsigned char str3[] = "TL3562开发板评测";
uint16_t unicode[20];
int unicode_size = 0;
int ret;
ret = drm_init();
if(ret < 0){
printf("drm init fail\n");
return -1;
}
error = FT_Init_FreeType( &library );
error = FT_New_Face( library, "file/simsun.ttc", 0, &face );
unicode_size = utf_8_to_unicode_string(str1,unicode);
fcolor=RED;
for(i = 0 ; i<unicode_size;i++)
freetype_set_char(face,(buf.width-font_size*unicode_size)/2+font_size*i,(buf.height-font_size)/2,font_size,angle_degree,unicode[i] );
fcolor=GREEN;
unicode_size = utf_8_to_unicode_string(str2,unicode);
for(i = 0 ; i<unicode_size;i++)
freetype_set_char(face,(buf.width-font_size/2*unicode_size)/2+font_size/2*i,(buf.height-font_size/2)/2 +font_size*0.8 ,font_size/2,angle_degree,unicode[i] );
fcolor=BLUE;
unicode_size = utf_8_to_unicode_string(str3,unicode);
for(i = 0 ; i<unicode_size;i++)
freetype_set_char(face,(buf.width-font_size/2*unicode_size)/2+font_size/2*i,(buf.height-font_size/2)/2 +font_size*1.3 ,font_size/2,angle_degree,unicode[i] );
getchar();
drm_exit();
return 0;
}
画点函数:
void show_pixel(uint32_t x , uint32_t y , uint32_t color)
编码转换函数
int utf_8_to_unicode_string(uint8_t *utf_8,uint16_t *word)
画位图函数
void draw_bitmap( FT_Bitmap* bitmap,FT_Int x_ori,FT_Int y_ori)
显示文字函数
int freetype_set_char(FT_Face face , int lcd_x,int lcd_y ,int font_size,int angle_degree,uint16_t word)
关于drm显示部分略
