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

简介: 【电子量产工具】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 库,在编译时要进行库链接。

相关文章
|
7月前
|
中间件
【电子量产工具】大纲分析
【电子量产工具】大纲分析
28 0
|
7月前
【电子量产工具】6. 业务系统
【电子量产工具】6. 业务系统
35 0
|
7天前
|
物联网 大数据
墨水屏电子纸标签/电子纸价签领域如何选择无线通信方案?
很多的厂家都知道,电子标签/电子价签的全套解决方案中,无线通信方案是最核心的,选对了这个方案,整个系统就会成功一半。
|
7月前
|
编解码 中间件 Linux
【电子量产工具】1.显示系统
【电子量产工具】1.显示系统
43 0
|
7月前
|
存储 UED
【电子量产工具】2.输入系统
【电子量产工具】2.输入系统
29 0
|
7月前
【电子量产工具】5.页面系统
【电子量产工具】5.页面系统
22 0
|
7月前
|
vr&ar
【电子量产工具】4. UI系统
【电子量产工具】4. UI系统
45 0
|
Ubuntu Windows
产品分享:Qt鸿途电子智慧白板(适合会议机、电子黑板、电子笔记、电子阅读器等场景),当前版本v1.0.0
使用Qt技术为基础,开发的windows/ubuntu/arm电子绘图板,主要为windows,支持触摸鼠标,可以定制跨平台。适合场景:1.会议机场景,办公室,会议室等等,2.教学场景,教室,自习室,课堂等等,3.电子笔记,手持终端等等,4.电子阅读器,作为笔记图层等等,各种其他场景…
产品分享:Qt鸿途电子智慧白板(适合会议机、电子黑板、电子笔记、电子阅读器等场景),当前版本v1.0.0
|
存储 安全 前端开发
基于单片机的多功能电子医药盒设计
基于单片机的多功能电子医药盒设计
205 0
基于单片机的多功能电子医药盒设计
硬件新品一周简报:加意Duux迷你空净、MAG P90磁动枪、Instrument 1智能乐器和“食光机+WIFI侠”
这一周,各式硬件新品的逐一登场让人应接不暇。笔者就为大家精选了本周国内外较为关注的硬件新品众筹和发布资讯。
297 0
硬件新品一周简报:加意Duux迷你空净、MAG P90磁动枪、Instrument 1智能乐器和“食光机+WIFI侠”