所学来自百问网
目录
1.文字系统
1.1 公共函数的封装
#ifndef __COMMON_H
#define __COMMON_H
typedef struct Region{
int iLeftUpX;
int iLeftUpY;
int iWidth;
int iHeigh;
}Region,*PRegion;
#ifndef NULL
#define NULL (void *)0
#endif
#endif
1.2 数据结构的抽象
#ifndef __FONT_MANAGER_H
#define __FONT_MANAGER_H
#include<common.h>
// 对字体的数据结构的抽象
// 该结构体支持固定的大小的字符文件(framebuffer)和freetype
typedef struct FontBitMap
{
Region tRegion;
// 当前字符的X、Y基点
int iCurOriginX;
int iCurOriginY;
// 下一个字符的X、Y基点
int iNextOriginX;
int iNextOriginY;
unsigned char *pucByffer; // 位图
}FontBitMap,*PFontBitMap;
// 字库的操作结果体
typedef struct FontOpr
{
char *name; //字库的名称
int (*FontInit)(char *aFineName);//初始化函数 用于获取字库类型
int (*SetFontSize)(int iFontSize);//获取字体的大小
int (*GetFontBitMap)(unsigned int dwCode,PFontBitMap ptFontBitMap);//获取字符的点阵
struct FontOpr *ptNext;//链表
}FontOpr,*PFontOpr;
void RegisterFont(PFontOpr ptFontOpr);
void FontsRegister(void);
int SetectAndInitFont(char *aFontOprName,char *aFoneFileName);
int SetFontSize(int iFontSize);
int GetFontBitMap(unsigned int dwCode, PFontBitMap ptFontBitMap);
#endif
1.3 底层的管理
#include <font_manager.h>
#include <string.h>
static PFontOpr g_ptFonts = NULL;
static PFontOpr g_ptDefaulFontOpr = NULL;
// 添加字库
void RegisterFont(PFontOpr ptFontOpr)
{
ptFontOpr->ptNext = g_ptFonts;
g_ptFonts = ptFontOpr;
}
// 对freetype进行注册
void FontsRegister(void)
{
extern void FreetypeRegister(void);
FreetypeRegister();
}
// 选择字库并初始化
int SetectAndInitFont(char *aFontOprName,char *aFoneFileName)
{
PFontOpr ptTmp = g_ptFonts;
while(ptTmp)
{
if(strcmp(ptTmp->name,aFontOprName) == 0)
break;
ptTmp = ptTmp->ptNext;
}
if(!ptTmp)
return -1;
g_ptDefaulFontOpr = ptTmp;
return ptTmp->FontInit(aFoneFileName);
}
// 设置字体大小
int SetFontSize(int iFontSize)
{
return g_ptDefaulFontOpr->SetFontSize(iFontSize);
}
// 获取位图
int GetFontBitMap(unsigned int dwCode, PFontBitMap ptFontBitMap)
{
return g_ptDefaulFontOpr->GetFontBitMap(dwCode,ptFontBitMap);
}
1.4 freetype的实现
#include <font_manager.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <linux/fb.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <wchar.h>
#include <sys/ioctl.h>
#include <ft2build.h>
#include FT_FREETYPE_H
#include FT_GLYPH_H
static FT_Face g_tface;
static int g_iDefaultFontSize = 12;
// 初始化
static int FreeTypeFontInit(char *aFineName)
{
FT_Library library;
int error;
error = FT_Init_FreeType( &library ); /* initialize library */
if(error)
{
printf("FT_Init_FreeType err\n");
return -1;
}
error = FT_New_Face(library, aFineName, 0, &g_tface); /* create face object */
if(error)
{
printf("FT_New_Face err\n");
return -1;
}
FT_Set_Pixel_Sizes(g_tface, g_iDefaultFontSize, 0);
return 0;
}
// 设置字符大小
static int FreeTypeSetFontSize(int iFontSize)
{
FT_Set_Pixel_Sizes(g_tface, iFontSize, 0);
return 0;
}
// 获取位图
static int FreeTypeGetFontBitMap(unsigned int dwCode,PFontBitMap ptFontBitMap)
{
int error;
FT_Vector pen;
FT_GlyphSlot slot = g_tface->glyph;
pen.x = ptFontBitMap->iCurOriginX * 64; /* 单位: 1/64像素 */
pen.y = ptFontBitMap->iCurOriginY * 64; /* 单位: 1/64像素 */
/* 转换:transformation */
FT_Set_Transform(g_tface, 0, &pen);
/* 加载位图: load glyph image into the slot (erase previous one) */
error = FT_Load_Char(g_tface, dwCode, FT_LOAD_RENDER);
if (error)
{
printf("FT_Load_Char error\n");
return -1;
}
ptFontBitMap->pucByffer = slot->bitmap.buffer;
ptFontBitMap->tRegion.iLeftUpX = slot->bitmap_left;
ptFontBitMap->tRegion.iLeftUpY = ptFontBitMap->iCurOriginY*2 - slot->bitmap_top;
ptFontBitMap->tRegion.iWidth = slot->bitmap.width;
ptFontBitMap->tRegion.iHeigh = slot->bitmap.rows;
ptFontBitMap->iNextOriginX = ptFontBitMap->iCurOriginX + slot->advance.x / 64;
ptFontBitMap->iNextOriginY = ptFontBitMap->iCurOriginY;
return 0;
}
static FontOpr g_tFreetypeOpr = {
.name = "freetype",
.FontInit = FreeTypeFontInit,
.SetFontSize = FreeTypeSetFontSize,
.GetFontBitMap = FreeTypeGetFontBitMap,
};
// 注册字库
void FreetypeRegister(void)
{
RegisterFont(&g_tFreetypeOpr);
}
1.5 测试
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <linux/fb.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <sys/ioctl.h>
#include <disp_manager.h>
#include <stdlib.h>
#include <font_manager.h>
#define FONTDATAMAX 4096
static const unsigned char fontdata_8x16[FONTDATAMAX] = {
/* 0 0x00 '^@' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
/* 1 0x01 '^A' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7e, /* 01111110 */
0x81, /* 10000001 */
0xa5, /* 10100101 */
0x81, /* 10000001 */
0x81, /* 10000001 */
0xbd, /* 10111101 */
0x99, /* 10011001 */
0x81, /* 10000001 */
0x81, /* 10000001 */
0x7e, /* 01111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
... ...
}
/**********************************************************************
* 函数名称: lcd_put_ascii
* 功能描述: 在LCD指定位置上显示一个8*16的字符
* 输入参数: x坐标,y坐标,ascii码
* 输出参数: 无
* 返 回 值: 无
* 修改日期 版本号 修改人 修改内容
* -----------------------------------------------
* 2020/05/12 V1.0 zh(angenao) 创建
***********************************************************************/
void lcd_put_ascii(int x, int y, unsigned char c)
{
unsigned char *dots = (unsigned char *)&fontdata_8x16[c*16];
int i, b;
unsigned char byte;
for (i = 0; i < 16; i++)
{
byte = dots[i];
for (b = 7; b >= 0; b--)
{
if (byte & (1<<b))
{
/* show */
PutPixel(x+7-b, y+i, 0xffffff); /* 白 */
}
else
{
/* hide */
PutPixel(x+7-b, y+i, 0); /* 黑 */
}
}
}
}
int main(int argc, char **argv)
{
PDispBuff ptBuffer;
int error;
int i = 0;
FontBitMap tFontBitMap;
char *str = "www.100ask.net";
int lcd_x;
int lcd_y;
int font_size;
if(argc != 5)
{
printf("Usage: %s <font_file> <lcd_x> <lcd_y> <font_size>\n",argv[0]);
return -1;
}
lcd_x = strtol(argv[2],NULL,0);
lcd_y = strtol(argv[3],NULL,0);
font_size = strtol(argv[4],NULL,0);
DisplayInit();
SelectDefaultDisplay("fb");
InitDefaultDisplay();
ptBuffer = GetDisplayBuffer();
FontsRegister();
error = SetectAndInitFont("freetype",argv[1]);
if(error)
{
printf("SetectAndInitFont err\n");
return -1;
}
SetFontSize(font_size);
while(str[i])
{
// 获得位图
tFontBitMap.iCurOriginX = lcd_x;
tFontBitMap.iCurOriginY = lcd_y;
error = GetFontBitMap(str[i], &tFontBitMap);
if(error)
{
printf("GetFontBitMap err\n");
return -1;
}
// 绘制
DrawFontBitMap(&tFontBitMap,0xff0000);
FlushDisplayRegion(&tFontBitMap.tRegion,ptBuffer);
lcd_x = tFontBitMap.iNextOriginX;
lcd_y = tFontBitMap.iNextOriginY;
i++;
}
return 0;
}