嵌入式应用开发之文字系统

目标

在这里插入图片描述
封装字体管理模块,通过freetype字体引擎得到字体信息,并显示到显示器。

代码及说明

font_manager.h

typedef struct FontInfo{
    Region tRegion;     //当前字符的region,LCD坐标系
    int iCurOriginX;
    int iCurOriginY;
    int iNextOriginX;
    int iNextOriginY;
    unsigned char *pucBuffer;
}FontInfo,*PFontInfo;

typedef struct FontOpr{
    char *name;
    int (*FontFileInit)(char * aFileName);
    int (*SetFontSize)(int iFontSize);
    int (*GetFontBitMap)(unsigned int dwCode, PFontInfo ptFontInfo);
    struct FontOpr *ptNext;
}FontOpr,*PFontOpr;

在头文件中定义两个结构体,FontInfo是字体信息,包括位图的位置、大小,当前字符origin位置,下个字符的origin,存有字符的位图数据;FontOpr是指通过字体引擎库可对字符执行的操作;

freetype.c

存放用freetype字体引擎实现字符操作的函数实现

//初始化freetype库,加载字体文件,设置默认字体大小
static int FreeTypeFontFileInit(char * aFileName)
//设置字体大小
static int FreeTypeSetFontSize(int iFontSize)
//得到位图
static int FreeTypeGetFontBitMap(unsigned int dwCode, PFontInfo ptFontInfo)
//将字符操作结构体注册到环形链表
void FreeTypeRegister(void)

font_manager.c

定义在可在主函数中调用的函数,完成结构体的注册及调用

//环形链表实现
void FontFilesRegister(PFontOpr ptFontOpr)
//如果有多个字体引擎库,依次注册多个字符操作结构体
void FontFilesInit(void)
//选择并初始化字体引擎库与字体文件,如freetype
int SelectAndInitFont(char *aFontOprName, char * aFontFileName)
//设置字体大小,自动调用已选择的字体引擎库中的函数实现
int SetFontSize(int iFontSize)
//获得位图
int GetFontBitMap(unsigned int dwCode, PFontInfo ptFontInfo)

测试

将显示系统与字体系统结合起来,需要再定义一个 DrawFontBitMap(&tFontInfo, color)函数,将得到的位图显示到显示器上;主函数只需要在循环中调用GetBitMap()->DrawBitMap()直到字符串写完即可
位图的数据格式

void DrawFontBitMap(PFontInfo ptFontBitMap, unsigned int dwcolor)
{

    int i, j, p, q;
	int x = ptFontBitMap->tRegion.iLeftUpX;
	int y = ptFontBitMap->tRegion.iRightUpy;
    int x_max = x + ptFontBitMap->tRegion.iWidth;
    int y_max = y + ptFontBitMap->tRegion.iHeight;

	int width = ptFontBitMap->tRegion.iWidth;
	unsigned char *buffer = ptFontBitMap->pucBuffer;
    //printf("x = %d, y = %d\n", x, y);

    for ( j = y, q = 0; j < y_max; j++, q++ )
    {
        for ( i = x, p = 0; i < x_max; i++, p++ )
        {
            if ( i < 0      || j < 0       ||
                i >= g_tDispBuff.iXres || j >= g_tDispBuff.iYres)
            continue;
			
			if (buffer[q * width + p])
            	PutPixel(i, j, dwcolor);
        }
    }
}

存在问题及解决

  • 显示汉字乱码问题->使用宽字符
wchar_t *str = L"再不学就找不到工作";
  • 坐标转换问题
  1. 按照韦东山老师之前讲解的课程,freetype使用的不是LCD坐标系,而是笛卡尔坐标系,应存在如下坐标转换代码,但是并没有发现,且显示正常
    /* 把LCD坐标转换为笛卡尔坐标 */
    int x = lcd_x;
    int y = var.yres - lcd_y;
  1. 在GetBitMap函数中,每次会把获得的位图信息保存在 ptFontInfo->tRegion结构体中,Y坐标在里面的转换没有搞明白
    ptFontInfo->tRegion.iLeftUpX     = slot->bitmap_left;
    ptFontInfo->tRegion.iRightUpy    = ptFontInfo->iCurOriginY * 2 - slot->bitmap_top;/*????*/

    ptFontInfo->tRegion.iHeight      = slot->bitmap.rows;
    ptFontInfo->tRegion.iWidth       = slot->bitmap.width;

    ptFontInfo->iNextOriginX        = ptFontInfo->iCurOriginX + slot->advance.x / 64;
    ptFontInfo->iNextOriginY        = ptFontInfo->iCurOriginY;  //同一水平线绘制,y值保持不变

用同样的环境跑了之前应用开发基础的代码,输入的坐标及字体大小都一样,显示结果如下:
对比图片
可以看出,虽然同样是输入坐标是(100,100),但是应用基础的代码是做了坐标转换以后求出来origin的值,再输入freetype,文字系统是把(100,100)直接作为origin输入了,所以会有以上差别,但是为什么其中的坐标转换不一样还没想清楚,也许是这样根本不需要坐标转换,在GetBitMap函数中y坐标的计算绕开了屏幕的iresY,也许这就是区别,没想明白,但是降低了代码耦合性。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值