本文所描述的只是freetype操作的简单封装,欢迎读者吐槽、完善!
/****************freetype.h********************/
-
#ifndef FREETYPE_H_
-
#define FREETYPE_H_
-
#include <ft2build.h>
-
#include <math.h>
-
#include FT_FREETYPE_H
-
#include <freetype/ftglyph.h>
-
-
typedef enum{
-
BITMAP_PIXEL_FORMAT_RGB1555 = 0,
-
}RGB_FORMAT_E;
-
-
typedef struct des_bitmap{
-
unsigned int width;
-
unsigned int height;
-
unsigned char* bitmap;
-
}Bitmap_info;
-
-
typedef struct create_bitmap{
-
unsigned int width;
-
unsigned int height;
-
unsigned int font_size;
-
//unsigned int font_color;
-
unsigned int font_left;
-
unsigned int font_top;
-
double font_angle;
-
}Bitmap_creat;
-
-
static Bitmap_creat creat_bitmap = {0,0,24,0,0,0.0};
-
-
class CFreeType2
-
{
-
public:
-
CFreeType2();
-
~CFreeType2();
-
static CFreeType2* GetInstance();
-
-
void Init(const char * fname, unsigned int font_size = 24);
-
void Done();
-
-
int SetFontSize(unsigned int font_size = 24);
-
int GetStringBitmap(char* str, Bitmap_info &bitmap_info,RGB_FORMAT_E format, Bitmap_creat* creat_info = &creat_bitmap);
-
-
//void bitMap_ForceTo1555(int &width, int &height, unsigned char** buff);
-
-
protected:
-
void draw_rgb1555( FT_Bitmap* bitmap,FT_Int x,FT_Int y);
-
int CreateSpace(unsigned int width, unsigned int height, RGB_FORMAT_E format);
-
-
private:
-
static CFreeType2* instance;
-
-
FT_Face face;
-
FT_Library library;
-
int font_size;
-
-
unsigned char* arrLine;
-
int cur_width;
-
int cur_height;
-
};
-
-
#endif
/****************freetype.cpp********************/
-
#include "freetype.h"
-
-
CFreeType2* CFreeType2::instance = NULL;
-
-
CFreeType2::CFreeType2()
-
{
-
font_size = 24;
-
-
cur_height = 0;
-
cur_width = 0;
-
arrLine = NULL;
-
}
-
-
CFreeType2::~CFreeType2()
-
{
-
if(instance != NULL)
-
{
-
delete instance;
-
instance = NULL;
-
}
-
-
if(arrLine != NULL)
-
{
-
delete[] arrLine;
-
arrLine = NULL;
-
}
-
}
-
-
CFreeType2* CFreeType2::GetInstance()
-
{
-
if(instance == NULL)
-
{
-
instance = new CFreeType2();
-
}
-
return instance;
-
}
-
-
void CFreeType2::Done()
-
{
-
FT_Done_Face(face);
-
FT_Done_FreeType(library);
-
}
-
-
void CFreeType2::Init(const char * fname, unsigned int font_size)
-
{
-
this->font_size = font_size;
-
-
if (FT_Init_FreeType( &library ))
-
fprintf(stderr,"FT_Init_FreeType failed");
-
-
if (FT_New_Face( library, fname, 0, &face ))
-
fprintf(stderr,"FT_New_Face failed (there is probably a problem with your font file)");
-
-
if(FT_Set_Char_Size( face,font_size<<6, 0, 96, 0))
-
fprintf(stderr,"FT_Set_Char_Size failed (there is probably a problem with your font file)");
-
}
-
-
int CFreeType2::SetFontSize(unsigned int font_size)
-
{
-
FT_Set_Char_Size( face,font_size<< 6, 0, 96, 0);
-
-
return 0;
-
}
-
-
-
-
void show_image( void )
-
{
-
// int i, j;
-
//
-
//
-
// for ( i = 0; i < cur_height; i++ )
-
// {
-
// for ( j = 0; j < cur_width; j++ )
-
// putchar( image[i][j] == 0 ? ' '
-
// : image[i][j] < 128 ? '+'
-
// : '*' );
-
// putchar( '\n' );
-
// }
-
}
-
-
/*
-
void CFreeType2::bitMap_ForceTo1555(int &width, int &height, unsigned char** buff)
-
{
-
width = cur_width;
-
height = cur_height;
-
int i, j;
-
FT_Short rgb1555;
-
-
//show_image();
-
*buff = (unsigned char*)malloc(cur_height * cur_width * 2);
-
-
memset(*buff, 0x0, cur_height * cur_width * 2);
-
for ( i = 0; i < cur_height; i++ )
-
{
-
for ( j = 0; j < cur_width; j++ ) {
-
//*(array+i*y+j)表示array[i][j]
-
//if(image[i][j] != 0) {
-
if(*(image+i*cur_width+j) != 0) {
-
//描边 占用原有字的边界
-
// if( image[i+1][j] == 0 || image[i][j+1] == 0
-
// || image[i-1][j] == 0 || image[i][j-1] == 0)
-
// {
-
// rgb1555 = (1<<15) | (0X0<<10) | (0X0<<5) | (0X0<<0);
-
// }
-
// else
-
// {
-
// rgb1555 = (1<<15) | (0X1F<<10) | (0X1F<<5) | (0X1F<<0);
-
// }
-
//复合
-
// rgb1555 = (1<<15) | ((0X1F & image[i][j])<<10) | ((0X1F & image[i][j])<<5) | ((0X1F & image[i][j])<<0);
-
-
//直接使用
-
//rgb1555 = (1<<15) | (image[i][j]<<10) | (image[i][j]<<5) | (image[i][j]<<0);
-
rgb1555 = (1<<15) | (*(image+i*cur_width+j)<<10) | (*(image+i*cur_width+j)<<5) | (*(image+i*cur_width+j)<<0);
-
-
memcpy(*buff + i*cur_width*2 + j*2, &rgb1555, sizeof(FT_Short));
-
-
}
-
else
-
{
-
//描外边
-
if(i == 0 || i>= cur_height-1)
-
{
-
rgb1555 = (0<<15) | (0<<10) | (0<<5) | (0<<0);
-
}
-
// else if(image[i+1][j] != 0 || image[i][j+1] != 0
-
// || image[i-1][j] != 0 || image[i][j-1] != 0)
-
else if(*(image+i*cur_width+j) != 0 || *(image+i*cur_width+j) != 0
-
|| *(image+i*cur_width+j) != 0 || *(image+i*cur_width+j) != 0)
-
-
{
-
rgb1555 = (1<<15) | (0X0<<10) | (0X0<<5) | (0X0<<0);
-
}
-
else
-
{
-
rgb1555 = (0<<15) | (0<<10) | (0<<5) | (0<<0);
-
}
-
-
memcpy(*buff + i*cur_width*2 + j*2, &rgb1555, sizeof(FT_Short));
-
}
-
}
-
}
-
#if 0
-
for(i=0; i<cur_height; i++)
-
{
-
for(j=0; j<cur_width*2; j+=2)
-
{
-
FT_Short rgb1555;
-
memcpy(&rgb1555, *buff + i*cur_width*2 + j, sizeof(FT_Short));
-
putchar( rgb1555 == 0 ? ' '
-
: rgb1555 < 128 ? '+'
-
: '*' );
-
}
-
printf("\n");
-
}
-
#endif
-
}
-
*/
-
-
/*****************************************************************************
-
Prototype : CFreeType2.CreateSpace
-
Description : 分配bitmap的存储空间
-
Input : unsigned int width
-
unsigned int height
-
RGB_FORMAT_E format
-
Output : None
-
Return Value : int
-
Calls :
-
Called By :
-
-
History :
-
1.Date : 2015/2/12
-
Author : donyj
-
Modification : Created function
-
-
*****************************************************************************/
-
int CFreeType2::CreateSpace(unsigned int width, unsigned int height, RGB_FORMAT_E format)
-
{
-
unsigned int bytes;
-
-
switch(format)
-
{
-
case BITMAP_PIXEL_FORMAT_RGB1555:
-
{
-
bytes = 2;
-
break;
-
}
-
// case BITMAP_PIXEL_FORMAT_GRAY_BIT8:
-
// {
-
// bytes = 1;
-
// break;
-
// }
-
default:
-
{
-
bytes = 2;
-
break;
-
}
-
}
-
-
//如果字符占用的内存变了,则重新分配,否则复用 malloc
-
if(cur_height != height || cur_width != width)
-
{
-
if(arrLine != NULL)
-
{
-
delete[] arrLine;
-
arrLine = NULL;
-
}
-
cur_width = width;
-
cur_height = height;
-
arrLine = new unsigned char[height*width*bytes];
-
}
-
memset(arrLine, 0x0, width*height*bytes);
-
-
return 0;
-
}
-
-
/*****************************************************************************
-
Prototype : CFreeType2.GetStringBitmap
-
Description : 根据字符串生成bitmap
-
Input : char* str
-
Bitmap_info &bitmap_info
-
RGB_FORMAT_E format
-
Bitmap_creat* creat_info
-
Output : None
-
Return Value : int
-
Calls :
-
Called By :
-
-
History :
-
1.Date : 2015/2/12
-
Author : donyj
-
Modification : Created function
-
-
*****************************************************************************/
-
int CFreeType2::GetStringBitmap(char* str, Bitmap_info &bitmap_info, RGB_FORMAT_E format, Bitmap_creat* creat_info)
-
{
-
FT_GlyphSlot slot;
-
FT_Matrix matrix; /* transformation matrix */
-
FT_Vector pen; /* untransformed origin */
-
FT_Error error;
-
-
double angle;
-
int map_height;
-
int n, str_len;
-
int ret;
-
-
str_len = strlen(str);
-
-
if(creat_info == NULL)
-
{
-
//开辟存储空间
-
ret = CreateSpace(str_len*font_size,font_size,format);
-
if(ret != 0)
-
{
-
printf("CreateSpace error!");
-
return -1;
-
}
-
-
angle = ( 0.0 / 360 ) * 3.14159 * 2; //字体旋转
-
map_height = cur_height;
-
-
/* use font_size at 96dpi */
-
error = FT_Set_Char_Size( face, font_size * 64, 0, 96, 0 );
-
if(error)
-
{
-
printf("FT_Set_Char_Size error!");
-
return -1;
-
}
-
-
/* the pen position in 26.6 cartesian space coordinates; */
-
/* start at (0,0) relative to the upper left corner */
-
pen.x = 0 * 64;//300 * 64;
-
pen.y = 0 * 64;//( target_height - 200 ) * 64;
-
}
-
else
-
{
-
if(creat_info->width < str_len*creat_info->font_size)
-
{
-
creat_info->width = str_len*creat_info->font_size;
-
}
-
if(creat_info->height < creat_info->font_size)
-
{
-
creat_info->height = creat_info->font_size;
-
}
-
//开辟存储空间
-
ret = CreateSpace(creat_info->width,creat_info->height,format);
-
if(ret != 0)
-
{
-
printf("CreateSpace error!");
-
return -1;
-
}
-
-
angle = ( creat_info->font_angle / 360 ) * 3.14159 * 2; //字体旋转
-
map_height = cur_height;
-
-
/* use font_size at 96dpi */
-
error = FT_Set_Char_Size( face, creat_info->font_size * 64, 0, 96, 0 );
-
if(error)
-
{
-
printf("FT_Set_Char_Size error!");
-
return -1;
-
}
-
-
/* the pen position in 26.6 cartesian space coordinates; */
-
/* start at (0,0) relative to the upper left corner */
-
pen.x = creat_info->font_left * 64;
-
pen.y = (map_height - creat_info->font_size - creat_info->font_top) * 64;
-
}
-
-
-
slot = face->glyph;
-
-
/* set up matrix */
-
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 );
-
-
-
for ( n = 0; n < str_len; n++ )
-
{
-
/* set transformation */
-
FT_Set_Transform( face, &matrix, &pen );
-
-
/* load glyph image into the slot (erase previous one) */
-
error = FT_Load_Char( face, str[n], FT_LOAD_RENDER );
-
if ( error )
-
continue; /* ignore errors */
-
/* now, draw to our target surface (convert position) */
-
switch(format)
-
{
-
case BITMAP_PIXEL_FORMAT_RGB1555:
-
{
-
draw_rgb1555( &slot->bitmap,
-
slot->bitmap_left,
-
map_height - slot->bitmap_top );
-
break;
-
}
-
-
default:
-
{
-
break;
-
}
-
}
-
-
/* increment pen position */
-
pen.x += slot->advance.x;
-
pen.y += slot->advance.y;
-
}
-
-
//赋值返回
-
bitmap_info.width = cur_width;
-
bitmap_info.height = cur_height;
-
bitmap_info.bitmap = arrLine;
-
-
return 0;
-
}
-
-
/*****************************************************************************
-
Prototype : CFreeType2.draw_rgb1555
-
Description : 填充bitmap rgb1555格式
-
Input : FT_Bitmap* bitmap
-
FT_Int x
-
FT_Int y
-
Output : None
-
Return Value : void
-
Calls :
-
Called By :
-
-
History :
-
1.Date : 2015/2/12
-
Author : donyj
-
Modification : Created function
-
-
*****************************************************************************/
-
void CFreeType2::draw_rgb1555( 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 >= cur_width || j >= cur_height )
-
continue;
-
unsigned short int rgb1555;
-
-
if(bitmap->buffer[q * bitmap->width + p] != 0) {
-
//描边 占用原有字的边界
-
// if( bitmap->buffer[(q+1) * bitmap->width + p] == 0 || bitmap->buffer[q * bitmap->width + (p+1)] == 0
-
// || bitmap->buffer[(q-1) * bitmap->width + p] == 0 || bitmap->buffer[q * bitmap->width + (p-1)] == 0)
-
// {
-
// rgb1555 = (1<<15) | (0X0<<10) | (0X0<<5) | (0X0<<0);
-
// }
-
// else
-
// {
-
// rgb1555 = (1<<15) | (0X1F<<10) | (0X1F<<5) | (0X1F<<0);
-
// }
-
//复合
-
// rgb1555 = (1<<15) | ((0X1F & bitmap->buffer[q * bitmap->width + p])<<10)
-
// | ((0X1F & bitmap->buffer[q * bitmap->width + p])<<5) | (bitmap->buffer[q * bitmap->width + p])<<0);
-
-
//直接使用
-
rgb1555 = (1<<15) | (bitmap->buffer[q * bitmap->width + p]<<10) | (bitmap->buffer[q * bitmap->width + p]<<5) | (bitmap->buffer[q * bitmap->width + p]<<0);
-
//rgb1555 = (1<<15) | (0X1F<<10) | (0X1F<<5) | (0X1F<<0);
-
-
}
-
else
-
{
-
//描外边
-
if(j == 0 || j>= cur_height-1)
-
{
-
rgb1555 = (1<<15) | (0<<10) | (0<<5) | (0<<0);
-
}
-
else if(bitmap->buffer[(q+1) * bitmap->width + p] != 0 || bitmap->buffer[q * bitmap->width + (p+1)] != 0
-
//|| bitmap->buffer[(q-1) * bitmap->width + p] != 0 || bitmap->buffer[q * bitmap->width + (p-1)] != 0
-
)
-
-
{
-
rgb1555 = (1<<15) | (0X0<<10) | (0X0<<5) | (0X0<<0);
-
}
-
else
-
{
-
rgb1555 = (0<<15) | (0<<10) | (0<<5) | (0<<0);
-
}
-
-
//rgb1555 = (0<<15) | (0<<10) | (0<<5) | (0<<0);
-
}
-
-
-
-
// if(tmp == '\0'){
-
// rgb1555 = (0<<15) | (0x0<<10) | (0x0<<5) | (0x0<<0);
-
// }else{
-
// rgb1555 = (1<<15) | (0x1F<<10) | (0x1F<<5) | (0x1F<<0);
-
// }
-
memcpy(arrLine+j*cur_width*2+2*i,&rgb1555,sizeof(rgb1555));
-
}
-
}
-
}
通过GetInstance()获取句柄来调用方法!暂时只实现了转换成rgb1555格式的bitmap。生成出来的字体不怎么好看,希望有人能指出,并且帮忙决解这个问题!
本文所有:Devile May Cry J QQ:384668960
阅读(2231) | 评论(0) | 转发(0) |