高通字库
版本 V1.1 · 更新于 2026-03

3. GUI自定义字库

3.1 GUI自定义字库概述

GT5G系列芯片是高通从传统固定字库芯片升级而来的新一代GUI资源芯片。与传统字库芯片只能使用出厂预置的固定字库不同,GT5G系列支持用户按需自定义配置字库资源,所有高通全系列字库均可在GT-HMI Designer中自由选用。

芯片支持三种字库类型:

  • 点阵字库:体积小、渲染快,适合小尺寸屏幕和资源受限的场景
  • 灰度字库:支持抗锯齿显示,文字边缘更平滑,适合中等分辨率屏幕
  • 矢量字库:支持任意缩放不失真,适合高分辨率屏幕和需要动态调整字号的场景

字库覆盖中文、拉丁文、日文、韩文、阿拉伯文、泰文等多语种,开发者只需在上位机中勾选所需的语种、字号和字库类型,编译后通过烧录器写入芯片即可。字库之外的剩余存储空间可用于存放图片素材或用户自定义数据。

视频教程:

3.2 字库资源烧录

第一步:在 GT-HMI Designer 中选择所需的字库(语种、字号、字库类型),编译生成 resource.bin

第二步:烧录步骤可参考本文 2.3 节。文件开始地址和缓冲区开始地址默认 0x000000 即可。如果需要烧录自定义的内容,可以将自定义内容与 resource.bin 合并在一起烧录,也可以在烧录 resource.bin 后单独烧录自定义内容,但是要在烧录时将文件开始地址偏移到 resource.bin 之后。

3.3 字库调用

1. 实现 SPI 读写的外部驱动函数:

/**
 * @brief 发送读取函数
 * @param sendbuf    发送数据的buff
 * @param sendlen    发送数据长度
 * @param receivebuf 读取数据的buff
 * @param receivelen 读取数据长度
 */
unsigned char gt_read_data(unsigned char * sendbuf, unsigned char sendlen,
                           unsigned char * receivebuf, unsigned int receivelen)
{
    unsigned int i;
    Rom_csL;  // 拉低片选cs,选中flash
    for(i = 0; i < sendlen; i++)
    {
        SPI1_ReadWriteByte(sendbuf[i]);  // 发送数据
    }
    for(i = 0; i < receivelen; i++)
    {
        receivebuf[i] = SPI1_ReadWriteByte(0x00);  // 接收数据,保存到receivebuf[]
    }
    Rom_csH;  // 拉高片选cs,空闲
    return 1;
}

/**
 * @brief SPI读取函数
 * @param address    地址
 * @param r_data_len 读取长度
 * @param p_rbuf     数据保存地址
 */
unsigned char r_dat_bat(unsigned long address, unsigned long r_data_len,
                         unsigned char *p_rbuf)
{
    #define _TX_DATA_LEN (4)
    unsigned char tx_buf[_TX_DATA_LEN] = {0};
    tx_buf[0] = 0x03;  // 读取数据的命令
    tx_buf[1] = (unsigned char)((address & 0xFF0000) >> 16);
    tx_buf[2] = (unsigned char)((address & 0x00FF00) >> 8);
    tx_buf[3] = (unsigned char)((address & 0x0000FF));
    return gt_read_data(tx_buf, _TX_DATA_LEN, p_rbuf, r_data_len);
}

2. 字库初始化: 在调用字库前调用 GT_Font_Init() 函数进行字库初始化。函数返回值大于 0,并且不等于 0xFF 代表字库芯片初始化成功。

int ret = GT_Font_Init();  // 字库芯片初始化函数,返回大于0且非FF的值代表字库芯片初始成功
if (ret <= 0)
{
    printf(">>>>>>>>>>>>>>>> GT_Font_Init error !!!\n");
    return -1;
}

3. SPI 通信验证: 如果字库初始化失败,可以使用以下示例验证 SPI 通信。如果 tmp_buf 里面的数据是 0x000xFF,就表示 SPI 读写函数的实现有问题。亦或者是有规律的一组数字,前三位的最后一位不在 12-19 范围内也不是 C9,就需要排查一下 SPI 时序。

uint8_t tmp_buf[8] = {0};
tmp_buf[0] = 0x9F;
gt_read_data(tmp_buf, 1, tmp_buf, 8);
for(int i = 0; i < 8; i++)
{
    printf("tmp_buf:%x\r\n", tmp_buf[i]);
}

4. 中文 16 点宋体调用示例:

// 中文
#define _USER_UNICODE_CHINESE 0  // 中文使用Unicode编码

#if _USER_UNICODE_CHINESE
unsigned int chinese_buf[] = {
    0x554A, 0x963F, 0x57C3,    // "啊阿埃" 的Unicode编码
    0x56FD, 0x5BB6, 0x4EBA,    // "国家人" 的Unicode编码
    0x946B, 0x6DFC, 0x61FF,    // "鑫淼懿" 的Unicode编码
};
#else
unsigned int chinese_buf[] = {
    0xB0A1, 0xB0A2, 0xB0A3,    // "啊阿埃" 的GBK编码
    0xB9FA, 0xBCD2, 0xC8CB,    // "国家人" 的GBK编码
    0xF6CE, 0xEDB5, 0xDCB2,    // "鑫淼懿" 的GBK编码
};
#endif

for(int i = 0; i < sizeof(chinese_buf)/sizeof(chinese_buf[0]); i++)
{
#if _USER_UNICODE_CHINESE
    // 使用Unicode编码直接调用中文字符
    GT_GetChinese(chinese_buf[i], GT_FAMILY_GB2312_16_ST, DZ_Data);
#else
    // 使用GBK编码调用中文字符
    GT_Set_Chinese_Charset_Type(1);
    GT_GetChinese(chinese_buf[i], GT_FAMILY_GB2312_16_ST, DZ_Data);
    GT_Set_Chinese_Charset_Type(0);  // 恢复库函数调用的编码模式
#endif
    fontDisplay_DZ(DZ_Data, x, y, 16, 16, 0x0000, 0xFFFF, 0);
    x += 20;
}
x = 50;
y += 30;

5. 英文调用示例:

memset(DZ_Data, 0, sizeof(DZ_Data));
for(int i = 0; i < sizeof(ascii_buf)/sizeof(ascii_buf[0]); i++)
{
    // 使用Unicode编码直接调用英文字符
    GT_GetASCII(ascii_buf[i], GT_FAMILY_ASCII_8x16, DZ_Data);
    fontDisplay_DZ(DZ_Data, x, y, 8, 16, 0x0000, 0xFFFF, 0);
    x += 20;
    if (x + 20 > 480)
    {
        x = 50;
        y += 20;
    }
}
x = 50;
y += 30;

6. 日文、韩文调用 API:

int GT_GetJapanese(unsigned long fontcode, unsigned int font_option, unsigned char* pbuffer);
int GT_GetKorean(unsigned long fontcode, unsigned int font_option, unsigned char* pbuffer);

用法与中文一致,根据编码调用即可。

7. 拉丁文、西里尔文、希腊文和希伯来文调用 API:

int GT_GetLatin(unsigned long fontcode, unsigned int font_option, unsigned char* pbuffer);
int GT_GetCyrillic(unsigned long fontcode, unsigned int font_option, unsigned char* pbuffer);
int GT_GetGreek(unsigned long fontcode, unsigned int font_option, unsigned char* pbuffer);
int GT_GetHebrew(unsigned long fontcode, unsigned int font_option, unsigned char* pbuffer);

用法与英文一致。

8. 阿拉伯文调用示例(需连字变换,从右向左书写):

// 阿拉伯文测试文本
unsigned short arabic_buf[] = {
    0x0645, 0x0631, 0x062D, 0x0628, 0x0627, 0x0020,
    0x0627, 0x0644, 0x0639, 0x0627, 0x0644, 0x0645,
};

// 阿拉伯文调用回调
static int _arabic_read_dot_font_cb(_gt_read_cb_param_st* read_cb)
{
    if(!read_cb || !read_cb->convert || !read_cb->data_p) return -1;
    font_convertor_st* convert = (font_convertor_st*)read_cb->convert;
    return GT_GetArabic(read_cb->font_code, convert->font_option, read_cb->data_p);
}

memset(DZ_Data, 0, sizeof(DZ_Data));

font_convertor_st arabic_convertor = {
    .fontcode   = arabic_buf,
    .code_len   = sizeof(arabic_buf)/sizeof(arabic_buf[0]),
    .fontsize   = 16,
    .fontgray   = 1,
    .font_option = GT_FAMILY_Arabic_16x16,
    .thick      = 16,
    .data_p     = DZ_Data,
    .data_len   = sizeof(DZ_Data),
    .is_rev     = 1,    // 阿拉伯文从右向左书写,需要反向
    .is_vec     = 0,
    .read_dot_font = _arabic_read_dot_font_cb,
};

int arabic_text_len = GT_Font_Code_Transform(&arabic_convertor);
for(int i = 0; i < arabic_text_len;)
{
    memset(DZ_Data, 0, sizeof(DZ_Data));
    int arabic_tmp = GT_Get_Font_Convertor_Data(&arabic_convertor, i);
    int arabic_font_wigth = gt_font_get_word_width_figure_up(
        &arabic_convertor.data_p[0], 16, 16, arabic_convertor.fontgray);
    fontDisplay_DZ(&arabic_convertor.data_p[0], x, y, 16, 16, 0x0000, 0xFFFF, 0);
    x += arabic_font_wigth;
    i += arabic_tmp;
}
x = 50;
y += 30;

9. 泰文调用示例:

unsigned short thai_buf[] = {
    0x0E2A, 0x0E27, 0x0E31, 0x0E2A, 0x0E14, 0x0E35,
    0x0E0A, 0x0E32, 0x0E27, 0x0E42, 0x0E25, 0x0E01,
};

static int _thai_read_dot_font_cb(_gt_read_cb_param_st* read_cb)
{
    if(!read_cb || !read_cb->convert || !read_cb->data_p) return -1;
    font_convertor_st* convert = (font_convertor_st*)read_cb->convert;
    return GT_GetThai(read_cb->font_code, convert->font_option, read_cb->data_p);
}

font_convertor_st thai_convertor = {
    .fontcode    = thai_buf,
    .code_len    = sizeof(thai_buf)/sizeof(thai_buf[0]),
    .fontsize    = 32,
    .fontgray    = 1,
    .font_option = GT_FAMILY_Thai_32x32,
    .thick       = 32,
    .data_p      = DZ_Data,
    .data_len    = sizeof(DZ_Data),
    .is_rev      = 0,
    .is_vec      = 0,
    .read_dot_font = _thai_read_dot_font_cb,
};

int thai_text_len = GT_Font_Code_Transform(&thai_convertor);
for(int i = 0; i < thai_text_len;)
{
    memset(DZ_Data, 0, sizeof(DZ_Data));
    int thai_tmp = GT_Get_Font_Convertor_Data(&thai_convertor, i);
    int thai_font_wigth = gt_font_get_word_width_figure_up(
        &thai_convertor.data_p[0], 32, 32, thai_convertor.fontgray);
    fontDisplay_DZ(thai_convertor.data_p, x, y, 32, 32, 0x0000, 0xFFFF, 0);
    x += thai_font_wigth;
    i += thai_tmp;
}
x = 50;
y += 30;

10. 印地文调用示例(需连字变换,从右向左书写):

unsigned short hindi_buf[] = {
    0x0928, 0x092E, 0x0938, 0x094D, 0x0924, 0x0947, 0x0020,
    0x0926, 0x0941, 0x0928, 0x093F, 0x092F, 0x093E,
};

static int _hindi_read_dot_font_cb(_gt_read_cb_param_st* read_cb)
{
    if(!read_cb || !read_cb->convert || !read_cb->data_p) return -1;
    font_convertor_st* convert = (font_convertor_st*)read_cb->convert;
    return GT_GetHindi(read_cb->font_code, convert->font_option, read_cb->data_p);
}

font_convertor_st hindi_convertor = {
    .fontcode    = hindi_buf,
    .code_len    = sizeof(hindi_buf)/sizeof(hindi_buf[0]),
    .fontsize    = 24,
    .fontgray    = 1,
    .font_option = GT_FAMILY_Hindi_16x24,
    .thick       = 24,
    .data_p      = DZ_Data,
    .data_len    = sizeof(DZ_Data),
    .is_rev      = 1,    // 印地文从右向左书写
    .is_vec      = 0,
    .read_dot_font = _hindi_read_dot_font_cb,
};

int hindi_text_len = GT_Font_Code_Transform(&hindi_convertor);
int font_data_len = (16 / 8) * 24;
for(int i = 0; i < hindi_text_len; i++)
{
    int hindi_font_wigth = gt_font_get_word_width_figure_up(
        &hindi_convertor.data_p[i * font_data_len], 16, 24, hindi_convertor.fontgray);
    fontDisplay_DZ(&hindi_convertor.data_p[i * font_data_len], x, y, 16, 24, 0x0000, 0xFFFF, 0);
    x += hindi_font_wigth;
}
x = 50;
y += 30;