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

相关文章
|
9月前
|
中间件
【电子量产工具】大纲分析
【电子量产工具】大纲分析
38 0
|
9月前
【电子量产工具】6. 业务系统
【电子量产工具】6. 业务系统
53 0
|
2月前
|
物联网 大数据
墨水屏电子纸标签/电子纸价签领域如何选择无线通信方案?
很多的厂家都知道,电子标签/电子价签的全套解决方案中,无线通信方案是最核心的,选对了这个方案,整个系统就会成功一半。
|
9月前
|
编解码 中间件 Linux
【电子量产工具】1.显示系统
【电子量产工具】1.显示系统
58 0
|
9月前
【电子量产工具】5.页面系统
【电子量产工具】5.页面系统
27 0
|
9月前
|
存储 UED
【电子量产工具】2.输入系统
【电子量产工具】2.输入系统
39 0
|
9月前
|
vr&ar
【电子量产工具】4. UI系统
【电子量产工具】4. UI系统
56 0
|
Ubuntu Windows
产品分享:Qt鸿途电子智慧白板(适合会议机、电子黑板、电子笔记、电子阅读器等场景),当前版本v1.0.0
使用Qt技术为基础,开发的windows/ubuntu/arm电子绘图板,主要为windows,支持触摸鼠标,可以定制跨平台。适合场景:1.会议机场景,办公室,会议室等等,2.教学场景,教室,自习室,课堂等等,3.电子笔记,手持终端等等,4.电子阅读器,作为笔记图层等等,各种其他场景…
产品分享:Qt鸿途电子智慧白板(适合会议机、电子黑板、电子笔记、电子阅读器等场景),当前版本v1.0.0
|
存储 安全 前端开发
基于单片机的多功能电子医药盒设计
基于单片机的多功能电子医药盒设计
218 0
基于单片机的多功能电子医药盒设计
|
搜索推荐 物联网 芯片
应用速递 | 智能灯光控制面板方案
应用速递栏目:应用速递是面向IoT厂商推荐芯片开放社区(OCC)上的典型应用案例,便于IoT厂商精准获取方案,快速实现产品落地。
156 0
应用速递 | 智能灯光控制面板方案

热门文章

最新文章