UP 字库生成脚本

main
JiXieShi 2024-06-23 18:03:57 +08:00
parent 3a889f16dd
commit 3dcc2f8f20
9 changed files with 218 additions and 22 deletions

3
.gitignore vendored
View File

@ -1,2 +1,3 @@
/cmake-build-debug/ /cmake-build-debug/
/.idea/ /.idea/
/.venv/

View File

@ -106,19 +106,23 @@ OLED_T oled = {
void Test_OLED() { void Test_OLED() {
SIM_OLED_INIT(128, 64, CYAN, 0x0, 5, 0); SIM_OLED_INIT(128, 64, CYAN, 0x0, 5, 0);
SIM_OLED_START();
OLED_Init(&oled); OLED_Init(&oled);
OLED_CLS(&oled); OLED_CLS(&oled);
// OLED_DrawRect(&oled, 0, 0, 127, 63); OLED_DrawRect(&oled, 0, 0, 127, 63);
mainpage(&oled);
SIM_OLED_START();
int s = 0; int s = 0;
char buf[30]; char buf[30] = {0x5B, 0x57, 0x5E, 0x93, 0x75, 0x1F, 0x62, 0x10, 0x6D, 0x4B, 0x8B, 0xD5};
OLED_ShowCHString(&oled, 15, 16, buf, 16);
OLED_Refresh(&oled);
_beginthread(Get_Key, 0, NULL); _beginthread(Get_Key, 0, NULL);
pageinit(); pageinit();
Sleep(5000);
while (1) { while (1) {
if (pageid > 3)pageid = 0; if (pageid > 3)pageid = 0;
pagesearch(pageid).page(&oled); // pagesearch(pageid).page(&oled);
// sprintf(buf, "DATA:%d", s); // sprintf(buf, "DATA:%d", s);
// OLED_ShowString(&oled, 2, 51, buf, 12); // OLED_ShowString(&oled, 2, 51, buf, 12);
OLED_Refresh(&oled); OLED_Refresh(&oled);

View File

@ -213,6 +213,18 @@ void OLED_ShowChar(OLED_T *dev, uint8_t x, uint8_t y, uint8_t chr, uint8_t size1
*/ */
void OLED_ShowString(OLED_T *dev, uint8_t x, uint8_t y, uint8_t *chr, uint8_t size1); void OLED_ShowString(OLED_T *dev, uint8_t x, uint8_t y, uint8_t *chr, uint8_t size1);
/**
* @brief OLED
* @param dev: [] OLED
* @param x: [] X
* @param y: [] Y
* @param str: []
* @param size: []
* @return void
* @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);
/** /**
* @brief OLED * @brief OLED
* @param dev: [] OLED * @param dev: [] OLED

View File

@ -1,12 +1,7 @@
#ifndef HW_LIB_OLED_FONT_H #ifndef HW_LIB_OLED_FONT_H
#define HW_LIB_OLED_FONT_H #define HW_LIB_OLED_FONT_H
//常用ASCII表
//偏移量32 //12*6 ASCII字符集点阵
//ASCII字符集
//偏移量32
//大小:12*6
/************************************6*8的点阵************************************/
//12*12 ASCII字符集点阵
const unsigned char asc2_1206[95][12] = { const unsigned char asc2_1206[95][12] = {
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},/*" ",0*/ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},/*" ",0*/
{0x00, 0x00, 0x00, 0x00, 0x3F, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},/*"!",1*/ {0x00, 0x00, 0x00, 0x00, 0x3F, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},/*"!",1*/
@ -104,7 +99,7 @@ const unsigned char asc2_1206[95][12] = {
{0x00, 0x00, 0x40, 0x20, 0x7B, 0xE0, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00},/*"}",93*/ {0x00, 0x00, 0x40, 0x20, 0x7B, 0xE0, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00},/*"}",93*/
{0x40, 0x00, 0x80, 0x00, 0x40, 0x00, 0x20, 0x00, 0x20, 0x00, 0x40, 0x00},/*"~",94*/ {0x40, 0x00, 0x80, 0x00, 0x40, 0x00, 0x20, 0x00, 0x20, 0x00, 0x40, 0x00},/*"~",94*/
}; };
//16*16 ASCII字符集点阵 //16*8 ASCII字符集点阵
const unsigned char asc2_1608[95][16] = { const unsigned char asc2_1608[95][16] = {
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},/*" ",0*/ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},/*" ",0*/
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xCC, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},/*"!",1*/ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xCC, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},/*"!",1*/
@ -202,7 +197,7 @@ const unsigned char asc2_1608[95][16] = {
{0x00, 0x00, 0x40, 0x02, 0x40, 0x02, 0x3E, 0xFC, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},/*"}",93*/ {0x00, 0x00, 0x40, 0x02, 0x40, 0x02, 0x3E, 0xFC, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},/*"}",93*/
{0x00, 0x00, 0x60, 0x00, 0x80, 0x00, 0x80, 0x00, 0x40, 0x00, 0x40, 0x00, 0x20, 0x00, 0x20, 0x00},/*"~",94*/ {0x00, 0x00, 0x60, 0x00, 0x80, 0x00, 0x80, 0x00, 0x40, 0x00, 0x40, 0x00, 0x20, 0x00, 0x20, 0x00},/*"~",94*/
}; };
//24*24 ASICII字符集点阵 //24*12 ASICII字符集点阵
const unsigned char asc2_2412[95][36] = { const unsigned char asc2_2412[95][36] = {
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},/*" ",0*/ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},/*" ",0*/
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x80, 0x38, 0x0F, 0xFE, 0x38, 0x0F, 0x80, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},/*"!",1*/ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x80, 0x38, 0x0F, 0xFE, 0x38, 0x0F, 0x80, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},/*"!",1*/

View File

@ -0,0 +1,46 @@
#ifndef HW_LIB_OLED_FONT_CHUC_H
#define HW_LIB_OLED_FONT_CHUC_H
typedef struct {
uint8_t name[3];
uint8_t data[32];
} Chinese_t;
Chinese_t Hzk[] = {
{
// Original: 字
{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
}},
{
// Original: 库
{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
}},
{
// Original: 生
{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
}},
{
// Original: 成
{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
}},
{
// Original: 测
{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
}},
{
// Original: 试
{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
}},
};
#endif //HW_LIB_OLED_FONT_CHUC_H

View File

@ -153,7 +153,7 @@ double :"[double]-> "#v"=%.2f" END, \
default: "[err]-> "#v"=%p" END) default: "[err]-> "#v"=%p" END)
#define POUT(s) printf(TYPE_F(s) ,s) #define POUT(s) printf(TYPE_F(s) ,s)
#define GET_BIT(x, bit) ((x & (1 << bit)) >> bit)
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -1,7 +1,9 @@
#include "oled.h" #include "oled.h"
#include "oled_font.h" #include "oled_font.h"
#include "oled_font_chuc.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)
const uint8_t initCmd[] = { const uint8_t initCmd[] = {
0xAE, // 关闭显示 0xAE, // 关闭显示
@ -104,6 +106,16 @@ void OLED_Set(OLED_T *dev, uint8_t x, uint8_t y) {
BUFPOINT(x, i) |= n; BUFPOINT(x, i) |= n;
} }
void OLED_BSet(OLED_T *dev, uint8_t x, uint8_t y, uint8_t data) {
uint8_t i, ys = y;
for (i = 0; i < 8; i++) //写入数据
{
if (GET_BIT(data, i))OLED_Set(dev, x, ys);
else OLED_RSet(dev, x, ys);
ys++;
}
}
void OLED_RSet(OLED_T *dev, uint8_t x, uint8_t y) { void OLED_RSet(OLED_T *dev, uint8_t x, uint8_t y) {
uint8_t i, m, n; uint8_t i, m, n;
i = y / 8; i = y / 8;
@ -171,7 +183,7 @@ void OLED_DrawCircle(OLED_T *dev, uint8_t x, uint8_t y, uint8_t r) {
void OLED_ShowChar(OLED_T *dev, uint8_t x, uint8_t y, uint8_t chr, uint8_t size1) { void OLED_ShowChar(OLED_T *dev, uint8_t x, uint8_t y, uint8_t chr, uint8_t size1) {
uint8_t i, m, temp, size2, chr1; uint8_t i, m, temp, size2, chr1;
uint8_t y0 = y; uint8_t ys = y;
size2 = (size1 / 8 + ((size1 % 8) ? 1 : 0)) * (size1 / 2); //得到字体一个字符对应点阵集所占的字节数 size2 = (size1 / 8 + ((size1 % 8) ? 1 : 0)) * (size1 / 2); //得到字体一个字符对应点阵集所占的字节数
chr1 = chr - ' '; //计算偏移后的值 chr1 = chr - ' '; //计算偏移后的值
for (i = 0; i < size2; i++) { for (i = 0; i < size2; i++) {
@ -181,12 +193,12 @@ void OLED_ShowChar(OLED_T *dev, uint8_t x, uint8_t y, uint8_t chr, uint8_t size1
else return; else return;
for (m = 0; m < 8; m++) //写入数据 for (m = 0; m < 8; m++) //写入数据
{ {
if (temp & 0x80)OLED_Set(dev, x, y); if (temp & 0x80)OLED_Set(dev, x, ys);
else OLED_RSet(dev, x, y); else OLED_RSet(dev, x, ys);
temp <<= 1; temp <<= 1;
y++; ys++;
if ((y - y0) == size1) { if ((ys - y) == size1) {
y = y0; ys = y;
x++; x++;
break; break;
} }
@ -208,6 +220,30 @@ 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) {
uint8_t i, temp, size2, ys = y, xs = x;
uint16_t index;
size2 = (size / 8 + ((size % 8) ? 1 : 0)) * (size); //得到字体一个字符对应点阵集所占的字节数
while (*str) {
for (index = 0; index < sizeof(Hzk) / 35; index++) {
if (Hzk[index].name[0] == str[0] && Hzk[index].name[1] == str[1])//对比汉字区码位码
{
for (i = 0; i < size2; i++) {
temp = Hzk[index].data[i];
OLED_BSet(dev, xs + (i % size), ys, temp);
if (i == size2 / 2)ys += size / 2;
}
xs += size;
ys = y;
str++;
str++;
} else {
return;
}
}
}
}
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;
while (n--) { while (n--) {
@ -237,6 +273,7 @@ void OLED_ShowPic(OLED_T *dev, uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1, u
dev->data(bmp + y * (x1 - x0), x1 - x0); dev->data(bmp + y * (x1 - x0), x1 - x0);
} }
} }
void OLED_Fill(OLED_T *dev, uint8_t data) { void OLED_Fill(OLED_T *dev, uint8_t data) {
uint8_t x, y; uint8_t x, y;
for (y = 0; y < (dev->height >> 3); y++) { for (y = 0; y < (dev->height >> 3); y++) {

View File

@ -3,6 +3,7 @@
// //
#include <stdio.h> #include <stdio.h>
#include <ctime> #include <ctime>
#include <stdint.h>
#include "tool.h" #include "tool.h"
float Mapping(float val, float I_Min, float I_Max, float O_Min, float O_Max) { float Mapping(float val, float I_Min, float I_Max, float O_Min, float O_Max) {
@ -45,6 +46,16 @@ void BufPrint(char *name, void *buf, Type_t type, unsigned int len, unsigned cha
printf("\n"); printf("\n");
} }
uint8_t UTF8ToUnicode(uint8_t *dataArea, uint8_t dataAreaLength, uint8_t *uniDA) {
uint8_t len = dataAreaLength * 2 / 3;
// uint8_t uniDA[len];
for (int i = 0; i < dataAreaLength / 3; i++) {
uniDA[i * 2] = ((dataArea[i * 3] & 0xF) << 4) + ((dataArea[i * 3 + 1] >> 2) & 0xF);
uniDA[i * 2 + 1] = ((dataArea[i * 3 + 1] & 0x3) << 6) + (dataArea[i * 3 + 2] & 0x3F);
}
return len;
}
float Str2Float(char *str) { float Str2Float(char *str) {
int integer = 0; int integer = 0;
double decimal = 0; double decimal = 0;

90
tools/unicode_ch_gen.py Normal file
View File

@ -0,0 +1,90 @@
import numpy as np
import PIL.ImageFont as pilfont
import PIL.Image as pilimage
import PIL.ImageDraw as pildraw
def generate_chinese_struct(char_code, font, size):
image = pilimage.new('L', size)
draw = pildraw.Draw(image)
draw.text((0, 0), char_code, font=font, fill=255)
pixel_array = np.array(image)
result = np.zeros(size[0] * size[1] // 8, dtype=np.uint8)
for i in range(size[1]):
for j in range(size[0] // 8):
for k in range(8):
if pixel_array[j * 8 + k, i]:
result[j * size[1] + i] |= (1 << k)
return result
def generate_chinese_array(input_str, font_str, size):
font = pilfont.truetype(font_str, size=size[1])
chinese_array = []
for char_code in input_str:
char_struct = generate_chinese_struct(char_code, font, size)
chinese_array.append({'name': char_code, 'data': char_struct})
return chinese_array
def format_chinese_array_as_text(chinese_array, size):
text_output = "#pragma pack(1)\n\n"
text_output += f"typedef struct {{\n"
text_output += " uint8_t unicode[2];\n"
text_output += f" uint8_t data[{size[0] * size[1] // 8}];\n"
text_output += "} Chinese_t;\n\n"
text_output += f"uint8_t Hzk_size={size[0]};\n\n"
text_output += "Chinese_t Hzk[] = {\n"
line_size = size[0] * size[1] // 8
line_size = line_size // 2
# line_size = 16 if line_size >= 16 else 8
for item in chinese_array:
unicode_hex = ', '.join(f"0x{ord(char) >> 8:02X}, 0x{ord(char) & 0xFF:02X}" for char in item['name'])
text_output += f" {{\n // Original: {item['name']}\n"
text_output += f" {{ {unicode_hex} }},\n {{\n "
bytes_str = ', '.join(f"0x{byte:02X}" for byte in item['data'])
bytes_lines = [bytes_str[i:i + 6 * line_size] for i in range(0, len(bytes_str), 6 * line_size)]
# 每行显示line_size个字节
text_output += '\n '.join(bytes_lines)
text_output += ",\n }\n },\n"
text_output += "};\n\n"
text_output += "Chinese_t* find_chinese_data(uint8_t unicode_high, uint8_t unicode_low) {\n"
text_output += " for (int i = 0; i < sizeof(Hzk) / sizeof(Chinese_t); ++i) {\n"
text_output += " if (Hzk[i].unicode[0] == unicode_high && Hzk[i].unicode[1] == unicode_low) {\n"
text_output += " return &Hzk[i];\n"
text_output += " }\n"
text_output += " }\n"
text_output += " return NULL;\n"
text_output += "}\n"
return text_output
def generate_and_write_chinese_array_output():
# 生成包含汉字结构体的数组
# simsun: 宋体
# kaiti: 楷体
# size = (20, 20)
# size = (20, 20)
size = (16, 16)
chinese_array = generate_chinese_array("字库生成测试", 'simsun', size)
# 将数组格式化为文本输出并写入文件
text_output = format_chinese_array_as_text(chinese_array, size)
with open('chinese_array_output.txt', 'w') as file:
file.write(text_output)
# 调用函数生成并写入汉字数组输出文件
generate_and_write_chinese_array_output()
def generate_unicode_bin_file():
font = pilfont.truetype('simsun', size=16)
with open('cao.bin', 'wb') as file:
for char_code in range(0x4e00, 0xa000):
result = generate_chinese_struct(chr(char_code), font)
file.write(result)
file.close()
# 调用函数生成Unicode二进制文件
# generate_unicode_bin_file()