【电子量产工具】3.文字系统

前言

最近看了 电子量产工具 这个项目,本专栏是对该项目的一个总结。


一、文字系统分析

在这里插入图片描述
文字管理器下面有 两种 字体表示方式: 点阵字符freetype 字符,具有不同的特点和用途。

使用点阵字库显示英文字母、汉字时,大小固定,如果放大缩小则会模糊可能有锯齿出现,为了解决这个问题,引用矢量字体。

FreeType 字符使用矢量图形描述字体的轮廓和形状,可以按需缩放和变换以适应不同的显示分辨率和大小。FreeType 字符具有良好的平滑度和可扩展性,可以提供更高品质的字符显示效果。

这里主要 介绍使用 FreeType 来显示字符, 在写程序前 要先了解 FreeType 的一些基础知识。

二、使用freetype得到位图

① 初始化freetype库.

error = FT_Init_FreeType( &library );

② 加载字体文件,保存在&face 中。

FT_GlyphSlot slot;

error = FT_New_Face( library, argv[1], 0, &face );
slot = face->glyph;

③ 设置字体大小.

FT_Set_Pixel_Sizes(face, font_size, 0);

④ 根据编码值得到位图.

error = FT_Load_Char( face, chinese_str[0], FT_LOAD_RENDER );

三、结构体字体系统模块化

  1. 结构体模块化字体显示方式。
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;
  1. 结构体模块化位图。(包括基点坐标,下一个基点坐标等)
    在这里插入图片描述

四、底层 freetype

  1. 实现 FontOpr 结构体。
static FontOpr g_tFreetypeOpr = {
	.name          = "freetype",
	.FontInit      = FreeTypeFontInit,
	.SetFontSize   = FreeTypeSetFontSize,
	.GetFontBitMap = FreeTypeGetFontBitMap,		
};
  1. 初始化 freetype 字体显示。
static int FreeTypeFontInit(char *aFineName)				// aFineName 是字库名
{
    FT_Library    library;
    int error;
	error = FT_Init_FreeType( &library ); 						// 初始化               
	if (error)
	{
		printf("FT_Init_FreeType err\n");
		return -1;
	}
	
    error = FT_New_Face(library, aFineName, 0, &g_tFace );	   // 加载(打开)字体
	if (error)
	{
		printf("FT_New_Face err\n");
		return -1;
	}
	FT_Set_Pixel_Sizes(g_tFace, g_iDefaultFontSize, 0);		// 设置字体大小
	return 0;
}
  1. 设置字体大小就很简单了。
    在这里插入图片描述
  2. 获取位图。
/* 根据 dwCode 编码值,获取位图 ptFontBitMap */
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像素 */

	/* 如果不涉及旋转,不涉及多个文字一起显示,就不用调用FT_Set_Transform */
	FT_Set_Transform(g_tFace, 0, &pen); 

	/* 加载位图,根据编码值获取位图,保存在 g_tFace 中 */
	error = FT_Load_Char(g_tFace, dwCode, FT_LOAD_RENDER);
	if (error)
	{
		printf("FT_Load_Char error\n");
		return -1;
	}

	ptFontBitMap->pucBuffer = 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;
}

五、字体管理层

  1. 将设备注册入 链表。
    在这里插入图片描述

  2. 根据 name 找到目标设备。

int SelectAndInitFont(char *aFontOprName, char *aFontFileName)
{
	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(aFontFileName);			// 根据字库 初始化 framebuffer
}
  1. 向上层提供字体大小 , 获取位图。
    dwCode 是编码值,将位图保存在 函数参数 ptFontBitMap 中。
    在这里插入图片描述
  2. 要在 屏幕上显示出这些位图, 还需要写 绘制位图 函数。
void DrawFontBitMap(PFontBitMap ptFontBitMap, unsigned int dwColor)
{
    int i, j, p, q;
	int x = ptFontBitMap->tRegion.iLeftUpX;
	int y = ptFontBitMap->tRegion.iLeftUpY;
    int x_max = x + ptFontBitMap->tRegion.iWidth;
    int y_max = y + ptFontBitMap->tRegion.iHeigh;
	int width = ptFontBitMap->tRegion.iWidth;
	unsigned char *buffer = ptFontBitMap->pucBuffer;

    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);			// 描点函数
        }
    }
}

六、测试程序

  1. 在 main.c 函数中 ,因为字体 在 LCD 上显示,我们要 初始化显示系统并将其 注册入链表,找到需要的显示设备。
    在这里插入图片描述
  2. 通过字符编码值,找到位图,绘制位图,再改变坐标值。
    在这里插入图片描述

测试效果:

要显示 中文时,不要忘记使用 wchar_t

注意 : 如果想在代码中能直接使用 UNICODE 值,需要使用 wchar_t,宽字符。

#include <wchar.h>

wchar_t *str= L"你好hi";

在这里插入图片描述


总结

找 位图以及位图的坐标 是一个难点,要好好体会。
使用 freetype 库,在编译时要进行库链接。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

糖果罐子♡

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值