UP 字库生成脚本
parent
790d26fbaa
commit
dd27c265da
|
@ -23,4 +23,6 @@ add_executable(HW_Lib main.c ${SOURCES})
|
||||||
|
|
||||||
#导入库
|
#导入库
|
||||||
add_subdirectory(lib)
|
add_subdirectory(lib)
|
||||||
target_link_libraries(HW_Lib HW_LIB_List HW_LIB_Task HW_LIB_Printf HW_LIB_Utils HW_LIB_Iic HW_LIB_Spi HW_LIB_Key HW_LIB_Oled)
|
target_link_libraries(HW_Lib HW_LIB_List HW_LIB_Task HW_LIB_Printf HW_LIB_Utils HW_LIB_Iic
|
||||||
|
HW_LIB_Spi HW_LIB_Key HW_LIB_Oled HW_LIB_Font
|
||||||
|
)
|
|
@ -114,7 +114,7 @@ void Test_OLED() {
|
||||||
|
|
||||||
int s = 0;
|
int s = 0;
|
||||||
char buf[30] = {0x5B, 0x57, 0x5E, 0x93, 0x75, 0x1F, 0x62, 0x10, 0x6D, 0x4B, 0x8B, 0xD5};
|
char buf[30] = {0x5B, 0x57, 0x5E, 0x93, 0x75, 0x1F, 0x62, 0x10, 0x6D, 0x4B, 0x8B, 0xD5};
|
||||||
OLED_ShowCHString(&oled, 15, 16, buf, 16);
|
OLED_ShowCHString(&oled, 15, 16, buf);
|
||||||
OLED_Refresh(&oled);
|
OLED_Refresh(&oled);
|
||||||
|
|
||||||
_beginthread(Get_Key, 0, NULL);
|
_beginthread(Get_Key, 0, NULL);
|
||||||
|
|
|
@ -8,6 +8,7 @@ set(LIBRARIES
|
||||||
HW_LIB_Spi src/spi inc/spi
|
HW_LIB_Spi src/spi inc/spi
|
||||||
HW_LIB_Key src/key inc/key
|
HW_LIB_Key src/key inc/key
|
||||||
HW_LIB_Oled src/oled inc/oled
|
HW_LIB_Oled src/oled inc/oled
|
||||||
|
HW_LIB_Font src/font inc/font
|
||||||
)
|
)
|
||||||
|
|
||||||
# 循环浏览库列表以创建它们
|
# 循环浏览库列表以创建它们
|
||||||
|
|
|
@ -0,0 +1,224 @@
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifndef __lvgl_H
|
||||||
|
#define __lvgl_H
|
||||||
|
|
||||||
|
#include "stdlib.h"
|
||||||
|
#include "string.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
/* Attribute to mark large constant arrays for example
|
||||||
|
* font's bitmaps */
|
||||||
|
#define LV_ATTRIBUTE_LARGE_CONST
|
||||||
|
|
||||||
|
/** Format of font character map. */
|
||||||
|
enum {
|
||||||
|
LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY,
|
||||||
|
LV_FONT_FMT_TXT_CMAP_FORMAT0_FULL,
|
||||||
|
LV_FONT_FMT_TXT_CMAP_SPARSE_TINY,
|
||||||
|
LV_FONT_FMT_TXT_CMAP_SPARSE_FULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef uint8_t lv_font_fmt_txt_cmap_type_t;
|
||||||
|
|
||||||
|
typedef uint8_t lv_opa_t;
|
||||||
|
|
||||||
|
/** This describes a glyph. */
|
||||||
|
typedef struct {
|
||||||
|
#if LV_FONT_FMT_TXT_LARGE == 0
|
||||||
|
uint32_t bitmap_index: 20; /**< Start index of the bitmap. A font can be max 1 MB. */
|
||||||
|
uint32_t adv_w: 12; /**< Draw the next glyph after this width. 8.4 format (real_value * 16 is stored). */
|
||||||
|
uint8_t box_w; /**< Width of the glyph's bounding box*/
|
||||||
|
uint8_t box_h; /**< Height of the glyph's bounding box*/
|
||||||
|
int8_t ofs_x; /**< x offset of the bounding box*/
|
||||||
|
int8_t ofs_y; /**< y offset of the bounding box. Measured from the top of the line*/
|
||||||
|
#else
|
||||||
|
uint32_t bitmap_index; /**< Start index of the bitmap. A font can be max 4 GB. */
|
||||||
|
uint32_t adv_w; /**< Draw the next glyph after this width. 28.4 format (real_value * 16 is stored). */
|
||||||
|
uint16_t box_w; /**< Width of the glyph's bounding box*/
|
||||||
|
uint16_t box_h; /**< Height of the glyph's bounding box*/
|
||||||
|
int16_t ofs_x; /**< x offset of the bounding box*/
|
||||||
|
int16_t ofs_y; /**< y offset of the bounding box. Measured from the top of the line*/
|
||||||
|
#endif
|
||||||
|
} lv_font_fmt_txt_glyph_dsc_t;
|
||||||
|
|
||||||
|
/* 将码点映射到 `glyph_dsc` 的结构体
|
||||||
|
* 支持多种格式以优化内存使用
|
||||||
|
* 详见 https://github.com/lvgl/lv_font_conv/blob/master/doc/font_spec.md
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
/** 此范围的第一个Unicode字符 */
|
||||||
|
uint32_t range_start;
|
||||||
|
|
||||||
|
/** 与此范围相关的Unicode字符数。
|
||||||
|
* 最后一个Unicode字符 = range_start + range_length - 1*/
|
||||||
|
uint16_t range_length;
|
||||||
|
|
||||||
|
/** 此范围的第一个字形ID(`glyph_dsc` 的数组索引) */
|
||||||
|
uint16_t glyph_id_start;
|
||||||
|
|
||||||
|
/*
|
||||||
|
根据规范,有4种格式:
|
||||||
|
https://github.com/lvgl/lv_font_conv/blob/master/doc/font_spec.md
|
||||||
|
|
||||||
|
为简单起见引入“相对码点”:
|
||||||
|
rcp = codepoint - range_start
|
||||||
|
|
||||||
|
和一个搜索函数:
|
||||||
|
在“数组”中搜索“值”并返回“值”的索引。
|
||||||
|
|
||||||
|
格式0 紧凑
|
||||||
|
unicode_list == NULL && glyph_id_ofs_list == NULL
|
||||||
|
glyph_id = glyph_id_start + rcp
|
||||||
|
|
||||||
|
格式0 完整
|
||||||
|
unicode_list == NULL && glyph_id_ofs_list != NULL
|
||||||
|
glyph_id = glyph_id_start + glyph_id_ofs_list[rcp]
|
||||||
|
|
||||||
|
Fomat 紧凑
|
||||||
|
unicode_list != NULL && glyph_id_ofs_list == NULL
|
||||||
|
glyph_id = glyph_id_start + search(unicode_list, rcp)
|
||||||
|
|
||||||
|
Fomat 完整
|
||||||
|
unicode_list != NULL && glyph_id_ofs_list != NULL
|
||||||
|
glyph_id = glyph_id_start + glyph_id_ofs_list[search(unicode_list, rcp)]
|
||||||
|
*/
|
||||||
|
|
||||||
|
const uint16_t *unicode_list;
|
||||||
|
|
||||||
|
/** 如果(type == LV_FONT_FMT_TXT_CMAP_FORMAT0_...),则为 `uint8_t *`
|
||||||
|
* 如果(type == LV_FONT_FMT_TXT_CMAP_SPARSE_...),则为 `uint16_t *`
|
||||||
|
*/
|
||||||
|
const void *glyph_id_ofs_list;
|
||||||
|
|
||||||
|
/** `unicode_list` 和/或 `glyph_id_ofs_list` 的长度 */
|
||||||
|
uint16_t list_length;
|
||||||
|
|
||||||
|
/** 此字符映射的类型 */
|
||||||
|
lv_font_fmt_txt_cmap_type_t type;
|
||||||
|
} lv_font_fmt_txt_cmap_t;
|
||||||
|
|
||||||
|
/* 描述字体的附加数据的结构体 */
|
||||||
|
typedef struct {
|
||||||
|
/* 所有字形的位图 */
|
||||||
|
const uint8_t *glyph_bitmap;
|
||||||
|
|
||||||
|
/* 描述字形 */
|
||||||
|
const lv_font_fmt_txt_glyph_dsc_t *glyph_dsc;
|
||||||
|
|
||||||
|
/* 将字形映射到Unicode字符。
|
||||||
|
* `lv_font_cmap_fmt_txt_t` 变量的数组 */
|
||||||
|
const lv_font_fmt_txt_cmap_t *cmaps;
|
||||||
|
|
||||||
|
/* 存储字距值。
|
||||||
|
* 可以是 `lv_font_fmt_txt_kern_pair_t *` 或 `lv_font_kern_classes_fmt_txt_t *`
|
||||||
|
* 取决于 `kern_classes` */
|
||||||
|
const void *kern_dsc;
|
||||||
|
|
||||||
|
/* 缩放字距值,12.4格式 */
|
||||||
|
uint16_t kern_scale;
|
||||||
|
|
||||||
|
/* cmap表的数量 */
|
||||||
|
uint16_t cmap_num: 10;
|
||||||
|
|
||||||
|
/* 每像素位数:1, 2, 3, 4, 8 */
|
||||||
|
uint16_t bpp: 4;
|
||||||
|
|
||||||
|
/* `kern_dsc` 的类型 */
|
||||||
|
uint16_t kern_classes: 1;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 位图的存储格式
|
||||||
|
* 取自 `lv_font_fmt_txt_bitmap_format_t`
|
||||||
|
*/
|
||||||
|
uint16_t bitmap_format: 2;
|
||||||
|
|
||||||
|
/* 缓存最后一个字母和其字形ID */
|
||||||
|
uint32_t last_letter;
|
||||||
|
uint32_t last_glyph_id;
|
||||||
|
|
||||||
|
} lv_font_fmt_txt_dsc_t;
|
||||||
|
|
||||||
|
/* 坐标类型。应为 `int16_t`(或在极端情况下为 `int32_t`) */
|
||||||
|
typedef int16_t lv_coord_t;
|
||||||
|
|
||||||
|
/** 描述字形属性的结构体 */
|
||||||
|
typedef struct {
|
||||||
|
uint16_t adv_w; /**< 字形所需的空间。在此宽度后绘制下一个字形。8位整数,4位小数 */
|
||||||
|
uint16_t box_w; /**< 字形的包围框宽度 */
|
||||||
|
uint16_t box_h; /**< 字形的包围框高度 */
|
||||||
|
int16_t ofs_x; /**< 包围框的x偏移量 */
|
||||||
|
int16_t ofs_y; /**< 包围框的y偏移量 */
|
||||||
|
uint8_t bpp; /**< 每像素位数:1, 2, 4, 8 */
|
||||||
|
} lv_font_glyph_dsc_t;
|
||||||
|
|
||||||
|
/** 描述字体的属性的结构体 */
|
||||||
|
typedef struct _lv_font_struct {
|
||||||
|
/** 从字体中获取字形描述符 */
|
||||||
|
bool (*get_glyph_dsc)(const struct _lv_font_struct *, lv_font_glyph_dsc_t *, uint32_t letter, uint32_t letter_next);
|
||||||
|
|
||||||
|
/** 从字体中获取字形的位图 */
|
||||||
|
const uint8_t *(*get_glyph_bitmap)(const struct _lv_font_struct *, uint32_t);
|
||||||
|
|
||||||
|
/* 指向字体包中的字体的指针(必须具有相同的行高) */
|
||||||
|
lv_coord_t line_height; /**< 任何文本都适合的实际行高 */
|
||||||
|
lv_coord_t base_line; /**< 从行高顶部测量的基准线 */
|
||||||
|
uint8_t subpx: 2; /**< `lv_font_subpx_t` 的一个元素 */
|
||||||
|
|
||||||
|
int8_t underline_position; /**< 下划线顶部与基准线之间的距离(< 0 表示在基准线下方)*/
|
||||||
|
int8_t underline_thickness; /**< 下划线的厚度 */
|
||||||
|
|
||||||
|
void *dsc; /**< 在这里存储特定于实现或运行时数据或缓存 */
|
||||||
|
} lv_font_t;
|
||||||
|
|
||||||
|
|
||||||
|
#define NULL 0 /* see <stddef.h> */
|
||||||
|
|
||||||
|
/** Bitmap formats*/
|
||||||
|
typedef enum {
|
||||||
|
LV_FONT_FMT_TXT_PLAIN = 0,
|
||||||
|
LV_FONT_FMT_TXT_COMPRESSED = 1,
|
||||||
|
LV_FONT_FMT_TXT_COMPRESSED_NO_PREFILTER = 1,
|
||||||
|
} lv_font_fmt_txt_bitmap_format_t;
|
||||||
|
|
||||||
|
|
||||||
|
typedef uintptr_t lv_uintptr_t;
|
||||||
|
|
||||||
|
|
||||||
|
/** 用于简单映射字距值对的结构体 */
|
||||||
|
typedef struct {
|
||||||
|
/* 获取两个字符代码点之间的字距值:
|
||||||
|
1. 从 `lv_font_fmt_txt_cmap_t` 中获取 `glyph_id_left` 和 `glyph_id_right`
|
||||||
|
2. for(i = 0; i < pair_cnt * 2; i+2)
|
||||||
|
if(gylph_ids[i] == glyph_id_left &&
|
||||||
|
gylph_ids[i+1] == glyph_id_right)
|
||||||
|
return values[i / 2];
|
||||||
|
*/
|
||||||
|
const void *glyph_ids; /* 存储字形ID对 */
|
||||||
|
const int8_t *values; /* 存储字距值 */
|
||||||
|
uint32_t pair_cnt: 24; /* 字距值对的数量 */
|
||||||
|
uint32_t glyph_ids_size: 2; /* 0: `glyph_ids` 存储为 `uint8_t`; 1: 存储为 `uint16_t` */
|
||||||
|
} lv_font_fmt_txt_kern_pair_t;
|
||||||
|
|
||||||
|
/** 更复杂但更优化的基于类别的字距值存储结构体 */
|
||||||
|
typedef struct {
|
||||||
|
/* 结构体用于获取两个字符代码点之间的字距值:
|
||||||
|
1. 从 `lv_font_fmt_txt_cmap_t` 中获取 `glyph_id_left` 和 `glyph_id_right`
|
||||||
|
2. 获取左侧和右侧字形的类别,分别为 `left_class` 和 `right_class`
|
||||||
|
left_class = left_class_mapping[glyph_id_left];
|
||||||
|
right_class = right_class_mapping[glyph_id_right];
|
||||||
|
3. value = class_pair_values[(left_class-1)*right_class_cnt + (right_class-1)]
|
||||||
|
*/
|
||||||
|
|
||||||
|
const int8_t *class_pair_values; /* 存储左侧类别数 * 右侧类别数的值 */
|
||||||
|
const uint8_t *left_class_mapping; /* 将字形ID映射到类别:索引 -> 字形ID -> 类别ID */
|
||||||
|
const uint8_t *right_class_mapping; /* 将字形ID映射到类别:索引 -> 字形ID -> 类别ID */
|
||||||
|
uint8_t left_class_cnt; /* 左侧类别数 */
|
||||||
|
uint8_t right_class_cnt; /* 右侧类别数 */
|
||||||
|
} lv_font_fmt_txt_kern_classes_t;
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,20 @@
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifndef __lvgl_font_H
|
||||||
|
#define __lvgl_font_H
|
||||||
|
|
||||||
|
#include "stdlib.h"
|
||||||
|
#include "string.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include "lvgl.h"
|
||||||
|
|
||||||
|
#define LV_ANTIALIAS 0 //抗锯齿
|
||||||
|
|
||||||
|
char utf8_to_unicode(uint8_t *pInput, uint32_t *unicode_letter);
|
||||||
|
|
||||||
|
char lv_draw_letter(const lv_font_t *font, uint32_t letter, int16_t pos_x, int16_t pos_y);
|
||||||
|
|
||||||
|
#endif
|
|
@ -1,3 +1,4 @@
|
||||||
|
#pragma once
|
||||||
#ifndef HW_LIB_OLED_H
|
#ifndef HW_LIB_OLED_H
|
||||||
#define HW_LIB_OLED_H
|
#define HW_LIB_OLED_H
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -219,11 +220,10 @@ void OLED_ShowString(OLED_T *dev, uint8_t x, uint8_t y, uint8_t *chr, uint8_t si
|
||||||
* @param x: [输入] X坐标
|
* @param x: [输入] X坐标
|
||||||
* @param y: [输入] Y坐标
|
* @param y: [输入] Y坐标
|
||||||
* @param str: [输入] 中文字符串指针
|
* @param str: [输入] 中文字符串指针
|
||||||
* @param size: [输入] 字体大小
|
|
||||||
* @return void
|
* @return void
|
||||||
* @example OLED_ShowCHString(&oled_device, 0, 0, chinese_str, 16);
|
* @example OLED_ShowCHString(&oled_device, 0, 0, chinese_str, 16);
|
||||||
**/
|
**/
|
||||||
void OLED_ShowCHString(OLED_T *dev, uint8_t x, uint8_t y, uint8_t *str, uint8_t size);
|
void OLED_ShowCHString(OLED_T *dev, uint8_t x, uint8_t y, uint8_t *str);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 在OLED屏幕上显示数字
|
* @brief 在OLED屏幕上显示数字
|
||||||
|
|
|
@ -1,46 +1,74 @@
|
||||||
|
#pragma once
|
||||||
#ifndef HW_LIB_OLED_FONT_CHUC_H
|
#ifndef HW_LIB_OLED_FONT_CHUC_H
|
||||||
#define HW_LIB_OLED_FONT_CHUC_H
|
#define HW_LIB_OLED_FONT_CHUC_H
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t name[3];
|
uint8_t unicode[2];
|
||||||
uint8_t data[32];
|
uint8_t data[32];
|
||||||
} Chinese_t;
|
} Chinese_t;
|
||||||
|
|
||||||
|
uint8_t Hzk_size = 16;
|
||||||
|
|
||||||
Chinese_t Hzk[] = {
|
Chinese_t Hzk[] = {
|
||||||
{
|
{
|
||||||
// Original: 字
|
// Original: 字
|
||||||
{0x5B, 0x57},
|
{0x5B, 0x57},
|
||||||
{0x10, 0x0C, 0x04, 0x24, 0x24, 0x24, 0x25, 0x26, 0xA4, 0x64, 0x24, 0x04, 0x04, 0x14, 0x0C, 0x00,
|
{
|
||||||
0x02, 0x02, 0x02, 0x02, 0x02, 0x42, 0x82, 0x7F, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00
|
0x10, 0x0C, 0x04, 0x24, 0x24, 0x24, 0x25, 0x26, 0xA4, 0x64, 0x24, 0x04, 0x04, 0x14, 0x0C, 0x00,
|
||||||
}},
|
0x02, 0x02, 0x02, 0x02, 0x02, 0x42, 0x82, 0x7F, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00,
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
// Original: 库
|
// Original: 库
|
||||||
{0x5E, 0x93},
|
{0x5E, 0x93},
|
||||||
{0x00, 0x00, 0xFC, 0x24, 0x24, 0xA4, 0x64, 0x3D, 0xA6, 0x24, 0x24, 0x24, 0x24, 0x24, 0x04, 0x00,
|
{
|
||||||
0x40, 0x30, 0x0F, 0x10, 0x13, 0x12, 0x12, 0x12, 0xFF, 0x12, 0x12, 0x12, 0x12, 0x10, 0x10, 0x00
|
0x00, 0x00, 0xFC, 0x24, 0x24, 0xA4, 0x64, 0x3D, 0xA6, 0x24, 0x24, 0x24, 0x24, 0x24, 0x04, 0x00,
|
||||||
}},
|
0x40, 0x30, 0x0F, 0x10, 0x13, 0x12, 0x12, 0x12, 0xFF, 0x12, 0x12, 0x12, 0x12, 0x10, 0x10, 0x00,
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
// Original: 生
|
// Original: 生
|
||||||
{0x75, 0x1F},
|
{0x75, 0x1F},
|
||||||
{0x80, 0x40, 0x30, 0x1E, 0x10, 0x10, 0x10, 0xFF, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00,
|
{
|
||||||
0x40, 0x40, 0x42, 0x42, 0x42, 0x42, 0x42, 0x7F, 0x42, 0x42, 0x42, 0x42, 0x42, 0x40, 0x40, 0x00
|
0x80, 0x40, 0x30, 0x1E, 0x10, 0x10, 0x10, 0xFF, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00,
|
||||||
}},
|
0x40, 0x40, 0x42, 0x42, 0x42, 0x42, 0x42, 0x7F, 0x42, 0x42, 0x42, 0x42, 0x42, 0x40, 0x40, 0x00,
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
// Original: 成
|
// Original: 成
|
||||||
{0x62, 0x10},
|
{0x62, 0x10},
|
||||||
{0x00, 0x00, 0xF8, 0x88, 0x88, 0x88, 0x88, 0x08, 0x08, 0xFF, 0x08, 0x09, 0x0A, 0xC8, 0x08, 0x00,
|
{
|
||||||
0x80, 0x60, 0x1F, 0x00, 0x10, 0x20, 0x1F, 0x80, 0x40, 0x21, 0x16, 0x18, 0x26, 0x41, 0xF8, 0x00
|
0x00, 0x00, 0xF8, 0x88, 0x88, 0x88, 0x88, 0x08, 0x08, 0xFF, 0x08, 0x09, 0x0A, 0xC8, 0x08, 0x00,
|
||||||
}},
|
0x80, 0x60, 0x1F, 0x00, 0x10, 0x20, 0x1F, 0x80, 0x40, 0x21, 0x16, 0x18, 0x26, 0x41, 0xF8, 0x00,
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
// Original: 测
|
// Original: 测
|
||||||
{0x6D, 0x4B},
|
{0x6D, 0x4B},
|
||||||
{0x10, 0x60, 0x02, 0x8C, 0x00, 0xFE, 0x02, 0xF2, 0x02, 0xFE, 0x00, 0xF8, 0x00, 0xFF, 0x00, 0x00,
|
{
|
||||||
0x04, 0x04, 0x7E, 0x01, 0x80, 0x47, 0x30, 0x0F, 0x10, 0x27, 0x00, 0x47, 0x80, 0x7F, 0x00, 0x00
|
0x10, 0x60, 0x02, 0x8C, 0x00, 0xFE, 0x02, 0xF2, 0x02, 0xFE, 0x00, 0xF8, 0x00, 0xFF, 0x00, 0x00,
|
||||||
}},
|
0x04, 0x04, 0x7E, 0x01, 0x80, 0x47, 0x30, 0x0F, 0x10, 0x27, 0x00, 0x47, 0x80, 0x7F, 0x00, 0x00,
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
// Original: 试
|
// Original: 试
|
||||||
{0x8B, 0xD5},
|
{0x8B, 0xD5},
|
||||||
{0x40, 0x40, 0x42, 0xCC, 0x00, 0x90, 0x90, 0x90, 0x90, 0x90, 0xFF, 0x10, 0x11, 0x16, 0x10, 0x00,
|
{
|
||||||
0x00, 0x00, 0x00, 0x3F, 0x10, 0x28, 0x60, 0x3F, 0x10, 0x10, 0x01, 0x0E, 0x30, 0x40, 0xF0, 0x00
|
0x40, 0x40, 0x42, 0xCC, 0x00, 0x90, 0x90, 0x90, 0x90, 0x90, 0xFF, 0x10, 0x11, 0x16, 0x10, 0x00,
|
||||||
}},
|
0x00, 0x00, 0x00, 0x3F, 0x10, 0x28, 0x60, 0x3F, 0x10, 0x10, 0x01, 0x0E, 0x30, 0x40, 0xF0, 0x00,
|
||||||
|
}
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Chinese_t *find_chinese_data(uint8_t unicode_high, uint8_t unicode_low) {
|
||||||
|
for (int i = 0; i < sizeof(Hzk) / sizeof(Chinese_t); ++i) {
|
||||||
|
if (Hzk[i].unicode[0] == unicode_high && Hzk[i].unicode[1] == unicode_low) {
|
||||||
|
return &Hzk[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif //HW_LIB_OLED_FONT_CHUC_H
|
#endif //HW_LIB_OLED_FONT_CHUC_H
|
||||||
|
|
|
@ -0,0 +1,558 @@
|
||||||
|
|
||||||
|
#include "lvgl.h"
|
||||||
|
#include "lvgl_font.h"
|
||||||
|
|
||||||
|
#define LV_HOR_RES_MAX 128
|
||||||
|
|
||||||
|
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
||||||
|
// Show utf8_to_unicode
|
||||||
|
//
|
||||||
|
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
||||||
|
char utf8_to_unicode(uint8_t *pInput, uint32_t *unicode_letter) {
|
||||||
|
char outputSize = 0;
|
||||||
|
char ppOutput[8] = {0};
|
||||||
|
|
||||||
|
char *tmp = ppOutput; //临时变量,用于遍历输出字符串
|
||||||
|
|
||||||
|
if (*pInput > 0x00 && *pInput <= 0x7F) //处理单字节UTF8字符(英文字母、数字)
|
||||||
|
{
|
||||||
|
|
||||||
|
*tmp = *pInput;
|
||||||
|
tmp++;
|
||||||
|
*tmp = 0; //小端法表示,在高地址填补0
|
||||||
|
outputSize = 1;
|
||||||
|
} else if (((*pInput) & 0xE0) == 0xC0) //处理双字节UTF8字符
|
||||||
|
{
|
||||||
|
|
||||||
|
char high = *pInput;
|
||||||
|
|
||||||
|
pInput++;
|
||||||
|
|
||||||
|
char low = *pInput;
|
||||||
|
|
||||||
|
if ((low & 0xC0) != 0x80) //检查是否为合法的UTF8字符表示
|
||||||
|
return 0; //如果不是则报错
|
||||||
|
|
||||||
|
*tmp = (high << 6) + (low & 0x3F);
|
||||||
|
tmp++;
|
||||||
|
*tmp = (high >> 2) & 0x07;
|
||||||
|
outputSize = 2;
|
||||||
|
} else if (((*pInput) & 0xF0) == 0xE0) //处理三字节UTF8字符
|
||||||
|
{
|
||||||
|
|
||||||
|
char high = *pInput;
|
||||||
|
pInput++;
|
||||||
|
char middle = *pInput;
|
||||||
|
pInput++;
|
||||||
|
char low = *pInput;
|
||||||
|
|
||||||
|
if (((middle & 0xC0) != 0x80) || ((low & 0xC0) != 0x80))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
*tmp = (middle << 6) + (low & 0x7F);
|
||||||
|
tmp++;
|
||||||
|
*tmp = (high << 4) + ((middle >> 2) & 0x0F);
|
||||||
|
outputSize = 3;
|
||||||
|
} else //对于其他字节数的UTF8字符不进行处理
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
unicode_letter[0] = ppOutput[1];
|
||||||
|
unicode_letter[0] <<= 8;
|
||||||
|
unicode_letter[0] |= ppOutput[0];
|
||||||
|
|
||||||
|
return outputSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
||||||
|
// Show draw_letter_normal
|
||||||
|
// lv_opa_t opa ; //透明度 0-255
|
||||||
|
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
||||||
|
void draw_letter_normal(uint16_t pos_x, uint16_t pos_y, lv_font_glyph_dsc_t *g, const uint8_t *map_p) {
|
||||||
|
uint32_t bitmask_init;
|
||||||
|
uint32_t bitmask;
|
||||||
|
uint32_t bpp = g->bpp;
|
||||||
|
|
||||||
|
if (bpp == 3)
|
||||||
|
bpp = 4;
|
||||||
|
|
||||||
|
switch (bpp) {
|
||||||
|
case 1:
|
||||||
|
bitmask_init = 0x80;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
bitmask_init = 0xC0;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
bitmask_init = 0xF0;
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
bitmask_init = 0xFF;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return; /*Invalid bpp. Can't render the letter*/
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t col, row;
|
||||||
|
int32_t box_w = g->box_w;
|
||||||
|
int32_t box_h = g->box_h;
|
||||||
|
int32_t width_bit = box_w * bpp; /*Letter width in bits*/
|
||||||
|
|
||||||
|
/* Calculate the col/row start/end on the map*/
|
||||||
|
int32_t col_start = 0;
|
||||||
|
int32_t col_end = box_w;
|
||||||
|
int32_t row_start = 0;
|
||||||
|
int32_t row_end = box_h;
|
||||||
|
|
||||||
|
/*Move on the map too*/
|
||||||
|
uint32_t bit_ofs = (row_start * width_bit) + (col_start * bpp);
|
||||||
|
map_p += bit_ofs >> 3;
|
||||||
|
|
||||||
|
uint8_t letter_px;
|
||||||
|
uint32_t col_bit;
|
||||||
|
col_bit = bit_ofs & 0x7; /* "& 0x7" equals to "% 8" just faster */
|
||||||
|
|
||||||
|
// uint32_t mask_buf_size = box_w * box_h > LV_HOR_RES_MAX ? LV_HOR_RES_MAX : box_w * box_h;
|
||||||
|
// unsigned short mask_buf[LV_HOR_RES_MAX / 2];
|
||||||
|
uint8_t fbuf[128 / 8];
|
||||||
|
int32_t mask_p = 0;
|
||||||
|
|
||||||
|
uint32_t col_bit_max = 8 - bpp;
|
||||||
|
uint32_t col_bit_row_ofs = (box_w + col_start - col_end) * bpp;
|
||||||
|
uint8_t index = 0;
|
||||||
|
for (row = row_start; row < row_end; row++) {
|
||||||
|
int32_t mask_p_start = mask_p;
|
||||||
|
|
||||||
|
bitmask = bitmask_init >> col_bit;
|
||||||
|
for (col = col_start; col < col_end; col++) {
|
||||||
|
/*Load the pixel's opacity into the mask*/
|
||||||
|
letter_px = (*map_p & bitmask) >> (col_bit_max - col_bit);
|
||||||
|
|
||||||
|
// if (letter_px) 1;
|
||||||
|
// else 0;
|
||||||
|
|
||||||
|
if (letter_px) {
|
||||||
|
fbuf[index / 8] |= (1 << (index % 8));
|
||||||
|
} else {
|
||||||
|
fbuf[index / 8] &= ~(1 << (index % 8));
|
||||||
|
}
|
||||||
|
index++;
|
||||||
|
|
||||||
|
/*Go to the next column*/
|
||||||
|
if (col_bit < col_bit_max) {
|
||||||
|
col_bit += bpp;
|
||||||
|
bitmask >>= bpp;
|
||||||
|
} else {
|
||||||
|
col_bit = 0;
|
||||||
|
bitmask = bitmask_init;
|
||||||
|
map_p++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*Next mask byte*/
|
||||||
|
mask_p++;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
// LCD_fill_fast(pos_x, pos_y, box_w, 1, (uint8_t *)mask_buf, box_w);
|
||||||
|
|
||||||
|
//// 读取fbuf的当前位置的二进制位
|
||||||
|
//bool read_bit = (fbuf[pos / 8] >> (pos % 8)) & 1;
|
||||||
|
|
||||||
|
pos_y++;
|
||||||
|
mask_p = 0;
|
||||||
|
} //避免大字体,大缓存 ,单行即刻刷入
|
||||||
|
|
||||||
|
col_bit += col_bit_row_ofs;
|
||||||
|
map_p += (col_bit >> 3);
|
||||||
|
col_bit = col_bit & 0x7;
|
||||||
|
}
|
||||||
|
// LCD_fill_fast(pos_x, pos_y, box_w, box_h, (uint8_t *)mask_buf, box_w * box_h); // 如果 大缓存 一次刷入
|
||||||
|
}
|
||||||
|
|
||||||
|
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
||||||
|
// Show lv_draw_letter
|
||||||
|
//
|
||||||
|
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
||||||
|
char lv_draw_letter(const lv_font_t *font, uint32_t letter, int16_t pos_x, int16_t pos_y) {
|
||||||
|
const uint8_t *map_p;
|
||||||
|
|
||||||
|
lv_font_glyph_dsc_t g;
|
||||||
|
if (!font->get_glyph_dsc(font, &g, letter, '\0')) //获取字体 信息
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (letter == ' ') // lvgl 空格没有实际数据 直接跳过
|
||||||
|
return g.box_w;
|
||||||
|
|
||||||
|
/* Don't draw anything if the character is empty. E.g. space */
|
||||||
|
if ((g.box_h == 0) || (g.box_w == 0))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
map_p = font->get_glyph_bitmap(font, letter); //获取字体 实际数据
|
||||||
|
if (map_p == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
pos_x += g.ofs_x; //偏移修正
|
||||||
|
pos_y += font->line_height - g.box_h - g.ofs_y;
|
||||||
|
|
||||||
|
if (pos_x < 1) //有的时候会为负
|
||||||
|
pos_x = 1;
|
||||||
|
if (pos_y < 1) //有的时候会为负
|
||||||
|
pos_y = 1;
|
||||||
|
|
||||||
|
draw_letter_normal(pos_x, pos_y, &g, map_p);
|
||||||
|
|
||||||
|
return g.box_w;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if LV_FONT_UNSCII_8
|
||||||
|
|
||||||
|
/** Searches base[0] to base[n - 1] for an item that matches *key.
|
||||||
|
*
|
||||||
|
* @note The function cmp must return negative if its first
|
||||||
|
* argument (the search key) is less that its second (a table entry),
|
||||||
|
* zero if equal, and positive if greater.
|
||||||
|
*
|
||||||
|
* @note Items in the array must be in ascending order.
|
||||||
|
*
|
||||||
|
* @param key Pointer to item being searched for
|
||||||
|
* @param base Pointer to first element to search
|
||||||
|
* @param n Number of elements
|
||||||
|
* @param size Size of each element
|
||||||
|
* @param cmp Pointer to comparison function (see #lv_font_codeCompare as a comparison function
|
||||||
|
* example)
|
||||||
|
*
|
||||||
|
* @return a pointer to a matching item, or NULL if none exists.
|
||||||
|
*/
|
||||||
|
void *_lv_utils_bsearch(const void *key, const void *base, uint32_t n, uint32_t size,
|
||||||
|
int32_t (*cmp)(const void *pRef, const void *pElement))
|
||||||
|
{
|
||||||
|
const char *middle;
|
||||||
|
int32_t c;
|
||||||
|
|
||||||
|
for (middle = base; n != 0;)
|
||||||
|
{
|
||||||
|
middle += (n / 2) * size;
|
||||||
|
if ((c = (*cmp)(key, middle)) > 0)
|
||||||
|
{
|
||||||
|
n = (n / 2) - ((n & 1) == 0);
|
||||||
|
base = (middle += size);
|
||||||
|
}
|
||||||
|
else if (c < 0)
|
||||||
|
{
|
||||||
|
n /= 2;
|
||||||
|
middle = base;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return (char *)middle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
/** Code Comparator.
|
||||||
|
*
|
||||||
|
* Compares the value of both input arguments.
|
||||||
|
*
|
||||||
|
* @param[in] pRef Pointer to the reference.
|
||||||
|
* @param[in] pElement Pointer to the element to compare.
|
||||||
|
*
|
||||||
|
* @return Result of comparison.
|
||||||
|
* @retval < 0 Reference is greater than element.
|
||||||
|
* @retval = 0 Reference is equal to element.
|
||||||
|
* @retval > 0 Reference is less than element.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static int32_t unicode_list_compare(const void *ref, const void *element)
|
||||||
|
{
|
||||||
|
return ((int32_t)(*(uint16_t *)ref)) - ((int32_t)(*(uint16_t *)element));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**********************
|
||||||
|
* STATIC FUNCTIONS
|
||||||
|
**********************/
|
||||||
|
|
||||||
|
static uint32_t get_glyph_dsc_id(const lv_font_t *font, uint32_t letter)
|
||||||
|
{
|
||||||
|
if (letter == '\0')
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
lv_font_fmt_txt_dsc_t *fdsc = (lv_font_fmt_txt_dsc_t *)font->dsc;
|
||||||
|
|
||||||
|
/*Check the cache first*/
|
||||||
|
if (letter == fdsc->last_letter)
|
||||||
|
return fdsc->last_glyph_id;
|
||||||
|
|
||||||
|
uint16_t i;
|
||||||
|
for (i = 0; i < fdsc->cmap_num; i++)
|
||||||
|
{
|
||||||
|
|
||||||
|
/*Relative code point*/
|
||||||
|
uint32_t rcp = letter - fdsc->cmaps[i].range_start;
|
||||||
|
if (rcp > fdsc->cmaps[i].range_length)
|
||||||
|
continue;
|
||||||
|
uint32_t glyph_id = 0;
|
||||||
|
if (fdsc->cmaps[i].type == LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY)
|
||||||
|
{
|
||||||
|
glyph_id = fdsc->cmaps[i].glyph_id_start + rcp;
|
||||||
|
}
|
||||||
|
else if (fdsc->cmaps[i].type == LV_FONT_FMT_TXT_CMAP_FORMAT0_FULL)
|
||||||
|
{
|
||||||
|
const uint8_t *gid_ofs_8 = fdsc->cmaps[i].glyph_id_ofs_list;
|
||||||
|
glyph_id = fdsc->cmaps[i].glyph_id_start + gid_ofs_8[rcp];
|
||||||
|
}
|
||||||
|
else if (fdsc->cmaps[i].type == LV_FONT_FMT_TXT_CMAP_SPARSE_TINY)
|
||||||
|
{
|
||||||
|
uint16_t key = rcp;
|
||||||
|
uint8_t *p = _lv_utils_bsearch(&key, fdsc->cmaps[i].unicode_list, fdsc->cmaps[i].list_length,
|
||||||
|
sizeof(fdsc->cmaps[i].unicode_list[0]), unicode_list_compare);
|
||||||
|
|
||||||
|
if (p)
|
||||||
|
{
|
||||||
|
lv_uintptr_t ofs = (lv_uintptr_t)(p - (uint8_t *)fdsc->cmaps[i].unicode_list);
|
||||||
|
ofs = ofs >> 1; /*The list stores `uint16_t` so the get the index divide by 2*/
|
||||||
|
glyph_id = fdsc->cmaps[i].glyph_id_start + ofs;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (fdsc->cmaps[i].type == LV_FONT_FMT_TXT_CMAP_SPARSE_FULL)
|
||||||
|
{
|
||||||
|
uint16_t key = rcp;
|
||||||
|
uint8_t *p = _lv_utils_bsearch(&key, fdsc->cmaps[i].unicode_list, fdsc->cmaps[i].list_length,
|
||||||
|
sizeof(fdsc->cmaps[i].unicode_list[0]), unicode_list_compare);
|
||||||
|
|
||||||
|
if (p)
|
||||||
|
{
|
||||||
|
lv_uintptr_t ofs = (lv_uintptr_t)(p - (uint8_t *)fdsc->cmaps[i].unicode_list);
|
||||||
|
ofs = ofs >> 1; /*The list stores `uint16_t` so the get the index divide by 2*/
|
||||||
|
const uint8_t *gid_ofs_16 = fdsc->cmaps[i].glyph_id_ofs_list;
|
||||||
|
glyph_id = fdsc->cmaps[i].glyph_id_start + gid_ofs_16[ofs];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*Update the cache*/
|
||||||
|
fdsc->last_letter = letter;
|
||||||
|
fdsc->last_glyph_id = glyph_id;
|
||||||
|
return glyph_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
fdsc->last_letter = letter;
|
||||||
|
fdsc->last_glyph_id = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Used as `get_glyph_bitmap` callback in LittelvGL's native font format if the font is uncompressed.
|
||||||
|
* @param font pointer to font
|
||||||
|
* @param unicode_letter an unicode letter which bitmap should be get
|
||||||
|
* @return pointer to the bitmap or NULL if not found
|
||||||
|
*/
|
||||||
|
const uint8_t *lv_font_get_bitmap_fmt_txt(const lv_font_t *font, uint32_t unicode_letter)
|
||||||
|
{
|
||||||
|
if (unicode_letter == '\t')
|
||||||
|
unicode_letter = ' ';
|
||||||
|
|
||||||
|
lv_font_fmt_txt_dsc_t *fdsc = (lv_font_fmt_txt_dsc_t *)font->dsc;
|
||||||
|
uint32_t gid = get_glyph_dsc_id(font, unicode_letter);
|
||||||
|
if (!gid)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
const lv_font_fmt_txt_glyph_dsc_t *gdsc = &fdsc->glyph_dsc[gid];
|
||||||
|
|
||||||
|
if (fdsc->bitmap_format == LV_FONT_FMT_TXT_PLAIN)
|
||||||
|
{
|
||||||
|
if (gdsc)
|
||||||
|
return &fdsc->glyph_bitmap[gdsc->bitmap_index];
|
||||||
|
}
|
||||||
|
/*Handle compressed bitmap*/
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#if LV_USE_FONT_COMPRESSED
|
||||||
|
uint32_t gsize = gdsc->box_w * gdsc->box_h;
|
||||||
|
if (gsize == 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
uint32_t buf_size = gsize;
|
||||||
|
/*Compute memory size needed to hold decompressed glyph, rounding up*/
|
||||||
|
switch (fdsc->bpp)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
buf_size = (gsize + 7) >> 3;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
buf_size = (gsize + 3) >> 2;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
buf_size = (gsize + 1) >> 1;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
buf_size = (gsize + 1) >> 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_lv_mem_get_size(LV_GC_ROOT(_lv_font_decompr_buf)) < buf_size)
|
||||||
|
{
|
||||||
|
LV_GC_ROOT(_lv_font_decompr_buf) = lv_mem_realloc(LV_GC_ROOT(_lv_font_decompr_buf), buf_size);
|
||||||
|
LV_ASSERT_MEM(LV_GC_ROOT(_lv_font_decompr_buf));
|
||||||
|
if (LV_GC_ROOT(_lv_font_decompr_buf) == NULL)
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool prefilter = fdsc->bitmap_format == LV_FONT_FMT_TXT_COMPRESSED ? true : false;
|
||||||
|
decompress(&fdsc->glyph_bitmap[gdsc->bitmap_index], LV_GC_ROOT(_lv_font_decompr_buf), gdsc->box_w, gdsc->box_h,
|
||||||
|
(uint8_t)fdsc->bpp,
|
||||||
|
prefilter);
|
||||||
|
return LV_GC_ROOT(_lv_font_decompr_buf);
|
||||||
|
#else /* !LV_USE_FONT_COMPRESSED */
|
||||||
|
return NULL;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/*If not returned earlier then the letter is not found in this font*/
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t kern_pair_8_compare(const void *ref, const void *element)
|
||||||
|
{
|
||||||
|
const uint8_t *ref8_p = ref;
|
||||||
|
const uint8_t *element8_p = element;
|
||||||
|
|
||||||
|
/*If the MSB is different it will matter. If not return the diff. of the LSB*/
|
||||||
|
if (ref8_p[0] != element8_p[0])
|
||||||
|
return (int32_t)ref8_p[0] - element8_p[0];
|
||||||
|
else
|
||||||
|
return (int32_t)ref8_p[1] - element8_p[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t kern_pair_16_compare(const void *ref, const void *element)
|
||||||
|
{
|
||||||
|
const uint16_t *ref16_p = ref;
|
||||||
|
const uint16_t *element16_p = element;
|
||||||
|
|
||||||
|
/*If the MSB is different it will matter. If not return the diff. of the LSB*/
|
||||||
|
if (ref16_p[0] != element16_p[0])
|
||||||
|
return (int32_t)ref16_p[0] - element16_p[0];
|
||||||
|
else
|
||||||
|
return (int32_t)ref16_p[1] - element16_p[1];
|
||||||
|
}
|
||||||
|
static int8_t get_kern_value(const lv_font_t *font, uint32_t gid_left, uint32_t gid_right)
|
||||||
|
{
|
||||||
|
lv_font_fmt_txt_dsc_t *fdsc = (lv_font_fmt_txt_dsc_t *)font->dsc;
|
||||||
|
|
||||||
|
int8_t value = 0;
|
||||||
|
|
||||||
|
if (fdsc->kern_classes == 0)
|
||||||
|
{
|
||||||
|
/*Kern pairs*/
|
||||||
|
const lv_font_fmt_txt_kern_pair_t *kdsc = fdsc->kern_dsc;
|
||||||
|
if (kdsc->glyph_ids_size == 0)
|
||||||
|
{
|
||||||
|
/* Use binary search to find the kern value.
|
||||||
|
* The pairs are ordered left_id first, then right_id secondly. */
|
||||||
|
const uint8_t *g_ids = kdsc->glyph_ids;
|
||||||
|
uint16_t g_id_both = (gid_right << 8) + gid_left; /*Create one number from the ids*/
|
||||||
|
uint8_t *kid_p = _lv_utils_bsearch(&g_id_both, g_ids, kdsc->pair_cnt, 2, kern_pair_8_compare);
|
||||||
|
|
||||||
|
/*If the `g_id_both` were found get its index from the pointer*/
|
||||||
|
if (kid_p)
|
||||||
|
{
|
||||||
|
lv_uintptr_t ofs = (lv_uintptr_t)(kid_p - g_ids);
|
||||||
|
ofs = ofs >> 1; /*ofs is for pair, divide by 2 to refer as a single value*/
|
||||||
|
value = kdsc->values[ofs];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (kdsc->glyph_ids_size == 1)
|
||||||
|
{
|
||||||
|
/* Use binary search to find the kern value.
|
||||||
|
* The pairs are ordered left_id first, then right_id secondly. */
|
||||||
|
const uint16_t *g_ids = kdsc->glyph_ids;
|
||||||
|
lv_uintptr_t g_id_both = (uint32_t)((uint32_t)gid_right << 8) + gid_left; /*Create one number from the ids*/
|
||||||
|
uint8_t *kid_p = _lv_utils_bsearch(&g_id_both, g_ids, kdsc->pair_cnt, 4, kern_pair_16_compare);
|
||||||
|
|
||||||
|
/*If the `g_id_both` were found get its index from the pointer*/
|
||||||
|
if (kid_p)
|
||||||
|
{
|
||||||
|
lv_uintptr_t ofs = (lv_uintptr_t)(kid_p - (const uint8_t *)g_ids);
|
||||||
|
ofs = ofs >> 4; /*ofs is 4 byte pairs, divide by 4 to refer as a single value*/
|
||||||
|
value = kdsc->values[ofs];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/*Invalid value*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/*Kern classes*/
|
||||||
|
const lv_font_fmt_txt_kern_classes_t *kdsc = fdsc->kern_dsc;
|
||||||
|
uint8_t left_class = kdsc->left_class_mapping[gid_left];
|
||||||
|
uint8_t right_class = kdsc->right_class_mapping[gid_right];
|
||||||
|
|
||||||
|
/* If class = 0, kerning not exist for that glyph
|
||||||
|
* else got the value form `class_pair_values` 2D array*/
|
||||||
|
if (left_class > 0 && right_class > 0)
|
||||||
|
{
|
||||||
|
value = kdsc->class_pair_values[(left_class - 1) * kdsc->right_class_cnt + (right_class - 1)];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used as `get_glyph_dsc` callback in LittelvGL's native font format if the font is uncompressed.
|
||||||
|
* @param font_p pointer to font
|
||||||
|
* @param dsc_out store the result descriptor here
|
||||||
|
* @param letter an UNICODE letter code
|
||||||
|
* @return true: descriptor is successfully loaded into `dsc_out`.
|
||||||
|
* false: the letter was not found, no data is loaded to `dsc_out`
|
||||||
|
*/
|
||||||
|
bool lv_font_get_glyph_dsc_fmt_txt(const lv_font_t *font, lv_font_glyph_dsc_t *dsc_out, uint32_t unicode_letter,
|
||||||
|
uint32_t unicode_letter_next)
|
||||||
|
{
|
||||||
|
bool is_tab = false;
|
||||||
|
if (unicode_letter == '\t')
|
||||||
|
{
|
||||||
|
unicode_letter = ' ';
|
||||||
|
is_tab = true;
|
||||||
|
}
|
||||||
|
lv_font_fmt_txt_dsc_t *fdsc = (lv_font_fmt_txt_dsc_t *)font->dsc;
|
||||||
|
uint32_t gid = get_glyph_dsc_id(font, unicode_letter);
|
||||||
|
if (!gid)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
int8_t kvalue = 0;
|
||||||
|
if (fdsc->kern_dsc)
|
||||||
|
{
|
||||||
|
uint32_t gid_next = get_glyph_dsc_id(font, unicode_letter_next);
|
||||||
|
if (gid_next)
|
||||||
|
{
|
||||||
|
kvalue = get_kern_value(font, gid, gid_next);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*Put together a glyph dsc*/
|
||||||
|
const lv_font_fmt_txt_glyph_dsc_t *gdsc = &fdsc->glyph_dsc[gid];
|
||||||
|
|
||||||
|
int32_t kv = ((int32_t)((int32_t)kvalue * fdsc->kern_scale) >> 4);
|
||||||
|
|
||||||
|
uint32_t adv_w = gdsc->adv_w;
|
||||||
|
if (is_tab)
|
||||||
|
adv_w *= 2;
|
||||||
|
|
||||||
|
adv_w += kv;
|
||||||
|
adv_w = (adv_w + (1 << 3)) >> 4;
|
||||||
|
|
||||||
|
dsc_out->adv_w = adv_w;
|
||||||
|
dsc_out->box_h = gdsc->box_h;
|
||||||
|
dsc_out->box_w = gdsc->box_w;
|
||||||
|
dsc_out->ofs_x = gdsc->ofs_x;
|
||||||
|
dsc_out->ofs_y = gdsc->ofs_y;
|
||||||
|
dsc_out->bpp = (uint8_t)fdsc->bpp;
|
||||||
|
|
||||||
|
if (is_tab)
|
||||||
|
dsc_out->box_w = dsc_out->box_w * 2;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -1,6 +1,7 @@
|
||||||
#include "oled.h"
|
#include "oled.h"
|
||||||
#include "oled_font.h"
|
#include "oled_font.h"
|
||||||
#include "oled_font_chuc.h"
|
#include "oled_font_chuc.h"
|
||||||
|
#include "../../inc/font/lvgl_font.h"
|
||||||
|
|
||||||
#define BUFPOINT(x, y) (*(dev->buf + x + (y * dev->width)))
|
#define BUFPOINT(x, y) (*(dev->buf + x + (y * dev->width)))
|
||||||
#define GET_BIT(x, bit) ((x & (1 << bit)) >> bit)
|
#define GET_BIT(x, bit) ((x & (1 << bit)) >> bit)
|
||||||
|
@ -220,20 +221,24 @@ void OLED_ShowString(OLED_T *dev, uint8_t x, uint8_t y, uint8_t *chr, uint8_t si
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OLED_ShowCHString(OLED_T *dev, uint8_t x, uint8_t y, uint8_t *str, uint8_t size) {
|
void OLED_ShowCHString(OLED_T *dev, uint8_t x, uint8_t y, uint8_t *str) {
|
||||||
uint8_t i, temp, size2, ys = y, xs = x;
|
uint8_t i, temp, size2, ys = y, xs = x, c = x;
|
||||||
uint16_t index;
|
uint16_t index;
|
||||||
size2 = (size / 8 + ((size % 8) ? 1 : 0)) * (size); //得到字体一个字符对应点阵集所占的字节数
|
size2 = Hzk_size * Hzk_size / 8; //得到字体一个字符对应点阵集所占的字节数
|
||||||
while (*str) {
|
while (*str) {
|
||||||
for (index = 0; index < sizeof(Hzk) / 35; index++) {
|
for (index = 0; index < sizeof(Hzk) / sizeof(Chinese_t); index++) {
|
||||||
if (Hzk[index].name[0] == str[0] && Hzk[index].name[1] == str[1])//对比汉字区码位码
|
if (Hzk[index].unicode[0] == str[0] && Hzk[index].unicode[1] == str[1])//对比汉字区码位码
|
||||||
{
|
{
|
||||||
for (i = 0; i < size2; i++) {
|
for (i = 0; i < size2; i++) {
|
||||||
temp = Hzk[index].data[i];
|
temp = Hzk[index].data[i];
|
||||||
OLED_BSet(dev, xs + (i % size), ys, temp);
|
OLED_BSet(dev, xs, ys, temp);
|
||||||
if (i == size2 / 2)ys += size / 2;
|
xs++;
|
||||||
|
if (xs - c == Hzk_size) {
|
||||||
|
ys += 8;
|
||||||
|
xs = c;
|
||||||
|
c += Hzk_size;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
xs += size;
|
|
||||||
ys = y;
|
ys = y;
|
||||||
str++;
|
str++;
|
||||||
str++;
|
str++;
|
||||||
|
@ -243,6 +248,21 @@ void OLED_ShowCHString(OLED_T *dev, uint8_t x, uint8_t y, uint8_t *str, uint8_t
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//
|
||||||
|
//void OLED_DisplayString(OLED_T *dev, const lv_font_t *font, uint8_t *s, uint16_t x, uint16_t y) {
|
||||||
|
// uint32_t unicode_letter;
|
||||||
|
// while (*s) {
|
||||||
|
// if (font) {
|
||||||
|
// s += utf8_to_unicode(s, &unicode_letter);
|
||||||
|
// x += lv_draw_letter(font, unicode_letter, x, y);
|
||||||
|
// x += 2; //字间距
|
||||||
|
// } else {
|
||||||
|
// OLED_ShowChar(dev, x, y, *s, 6);
|
||||||
|
// x += 6;
|
||||||
|
// s++;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
uint32_t OLED_Pow(uint8_t m, uint8_t n) {
|
uint32_t OLED_Pow(uint8_t m, uint8_t n) {
|
||||||
uint32_t result = 1;
|
uint32_t result = 1;
|
||||||
|
|
|
@ -18,6 +18,50 @@ def generate_chinese_struct(char_code, font, size):
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
# from bitarray import bitarray
|
||||||
|
# # from PIL import Image, ImageDraw
|
||||||
|
# # from bitarray import bitarray
|
||||||
|
|
||||||
|
|
||||||
|
# def generate_chinese_struct(char_code, font, size):
|
||||||
|
# height=(size[1] + 7) // 8 * 8
|
||||||
|
# wight=(size[0] + 7) // 8 * 8
|
||||||
|
# image = Image.new('1', size, 1)
|
||||||
|
# draw = ImageDraw.Draw(image)
|
||||||
|
# draw.text((0, -1), char_code, font=font, fill=0)
|
||||||
|
# image.show()
|
||||||
|
# bitmap = bitarray()
|
||||||
|
# for w in range(size[1]):
|
||||||
|
# for h in range(size[0]):
|
||||||
|
# # if h > size[1] or w > size[0]:
|
||||||
|
# # bitmap.append(False)
|
||||||
|
# # else:
|
||||||
|
# if image.getpixel((w, h)) == 0:
|
||||||
|
# bitmap.append(True)
|
||||||
|
# print('■', end=' ')
|
||||||
|
# else:
|
||||||
|
# bitmap.append(False)
|
||||||
|
# print('0', end=' ')
|
||||||
|
# print()
|
||||||
|
# result = np.zeros(size[0] * size[1] // 8, dtype=np.uint8)
|
||||||
|
# # for i in range(height):
|
||||||
|
# # for j in range(wight // 8):
|
||||||
|
# # for k in range(8):
|
||||||
|
# # if bitmap[j * 8 + k, i]==1:
|
||||||
|
# # result[j * height + i] |= (1 << k)
|
||||||
|
# for h in range(height):
|
||||||
|
# for w in range(wight):
|
||||||
|
# if bitmap[w+h]:
|
||||||
|
# #前景字符(即用来表示汉字笔画的输出字符)
|
||||||
|
# print('■', end=' ')
|
||||||
|
# else:
|
||||||
|
#
|
||||||
|
# # 背景字符(即用来表示背景的输出字符)
|
||||||
|
# print('0', end=' ')
|
||||||
|
# print()
|
||||||
|
# return result
|
||||||
|
|
||||||
|
|
||||||
def generate_chinese_array(input_str, font_str, size):
|
def generate_chinese_array(input_str, font_str, size):
|
||||||
font = pilfont.truetype(font_str, size=size[1])
|
font = pilfont.truetype(font_str, size=size[1])
|
||||||
chinese_array = []
|
chinese_array = []
|
||||||
|
@ -64,7 +108,7 @@ def generate_and_write_chinese_array_output():
|
||||||
# simsun: 宋体
|
# simsun: 宋体
|
||||||
# kaiti: 楷体
|
# kaiti: 楷体
|
||||||
# size = (20, 20)
|
# size = (20, 20)
|
||||||
# size = (20, 20)
|
# size = (12, 12)
|
||||||
size = (16, 16)
|
size = (16, 16)
|
||||||
chinese_array = generate_chinese_array("字库生成测试", 'simsun', size)
|
chinese_array = generate_chinese_array("字库生成测试", 'simsun', size)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue