Skip to content

Commit 6adf99d

Browse files
committed
添加一键更新字库脚本
1 parent e82c42d commit 6adf99d

File tree

7 files changed

+403
-0
lines changed

7 files changed

+403
-0
lines changed

tools/.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
bin2hex
2+
*.csv
3+
*.txt
4+
*.h

tools/README.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# 开发工具包
2+
3+
## 构建字库
4+
5+
参考这里 https://chowdera.com/2021/09/20210918113606411C.html 写了个一键更新脚本
6+
7+
### 准备工作
8+
9+
- 安装 gcc
10+
- 安装 processing 程序,打开程序,工具 -> 安装 'processing-java'
11+
-[LocationList](https://github.com/qwd/LocationList)下载[China-City-List-latest.csv](https://raw.githubusercontent.com/qwd/LocationList/master/China-City-List-latest.csv)文件到当前目录
12+
-[思源黑体仓库](https://github.com/adobe-fonts/source-han-sans)自行下载最新 [release 字体文件: Language Specific HW OTFs Simplified Chinese (简体中文)](https://github.com/adobe-fonts/source-han-sans/releases/download/2.004R/SourceHanSansHWSC.zip),解压后把 `SourceHanSansHWSC-Regular.otf` 放到 `.pio/libdeps/esp12e/TFT_eSPI/Tools/Create_Smooth_Font/Create_font/data/` 目录下
13+
14+
### 编译字体文件
15+
16+
执行 `bash update_font.sh` 中间会弹出字体渲染窗口, 手动关闭之后会继续执行, 脚本执行成功后会自动更新 `/src/font/SourceHanSans_20.h` 文件,重新编译固件即可
17+
18+
如果有缺失字体,修改 `get_dict.py` 里面的 `additional_list` 变量即可

tools/bin2hex.c

Lines changed: 271 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,271 @@
1+
/** \file
2+
\brief Binary to hex converter
3+
\author Tomasz Ostrowski, ot at epf dot pl
4+
\date October 2006
5+
from http://tomeko.net/bin/bin2hex/bin2hex.c
6+
online version: https://tomeko.net/online_tools/file_to_hex.php?lang=zh
7+
*/
8+
#include <stdio.h>
9+
#include <stdlib.h>
10+
#include <string.h>
11+
#include <getopt.h>
12+
13+
/** Flag set by `--verbose'. */
14+
static int verbose_flag;
15+
16+
char fin[255]; ///< input filename
17+
char fout[255]; ///< output filename
18+
char strtmp[255]; ///< temporary string
19+
char separator[255]; ///< separator for output strings
20+
int bytes_per_string; ///< how many bytes convert to string? (byte/word/quad/... data)
21+
unsigned int wrap_line; ///< wrap line after about N chars
22+
/** \brief Print some help */
23+
void help(char *exename)
24+
{
25+
puts("\nBinary to hex string (C-like) converter");
26+
printf("\nUsage: %s --i <input_filename> --o <output_filename>\n", exename);
27+
puts(" i.e. bin2hex --i myfile.dat --o myfile.c");
28+
puts("Other options:");
29+
puts(" --s <separator> select separator for output string (i.e. comma or comma+space)");
30+
puts(" --b <bytes_per_string> read byte (default), word, int (0xAB/0xABCD/0x89ABCDEF)");
31+
puts(" --w <wrap_line> wrap line after specified number of chars (default: 70)");
32+
puts(" multi-bytes values treated as little endian");
33+
puts("\nauthor: Tomasz Ostrowski, ot at epf dot pl");
34+
puts("created: 2006.10.23\n");
35+
}
36+
37+
38+
/** \brief Init default options (if not exist in command line) */
39+
void init_options(void)
40+
{
41+
strcpy(fin,"");
42+
strcpy(fout,"hex_out.c");
43+
strcpy(separator, ", "); //default separator
44+
bytes_per_string = 1; //read bytes (not words or ints) from file
45+
wrap_line = 70;
46+
}
47+
48+
49+
int
50+
main (argc, argv)
51+
int argc;
52+
char **argv;
53+
{
54+
int c;
55+
int i;
56+
unsigned int chars_in_line=0; ///< number of chars in current line
57+
int stringlength; ///< length of single converted string
58+
long lSize; ///< filesize
59+
unsigned char *buffer; ///< pointer to buffer for input file
60+
int option_count=0; ///< command-line options counter
61+
FILE *fileIn, *fileOut; ///< input and output file
62+
63+
64+
init_options();
65+
66+
while (1)
67+
{
68+
static struct option long_options[] =
69+
{
70+
/* Flag-type options */
71+
{"verbose", no_argument, &verbose_flag, 1
72+
},
73+
/* Non-flag options distinguished by their indices. */
74+
{"add", no_argument, 0, 'a'
75+
},
76+
{"bytes_per_string", required_argument, 0, 'b'
77+
},
78+
{"in", required_argument, 0, 'i'
79+
},
80+
{"out", required_argument, 0, 'o'
81+
},
82+
{"separator", required_argument, 0, 's'
83+
},
84+
{"wrap_line", required_argument, 0, 'w'
85+
},
86+
{0, 0, 0, 0
87+
}
88+
};
89+
/* getopt_long stores the option index here. */
90+
int option_index = 0;
91+
92+
c = getopt_long (argc, argv, "abc:d:f:",
93+
long_options, &option_index);
94+
95+
/* Detect the end of the options. */
96+
if (c == -1)
97+
{
98+
if(option_count<1)
99+
help(argv[0]); // print help if no arguments
100+
break;
101+
}
102+
option_count++;
103+
104+
switch (c)
105+
{
106+
case 0:
107+
/* If this option set a flag, do nothing else now. */
108+
if (long_options[option_index].flag != 0)
109+
break;
110+
printf ("option %s", long_options[option_index].name);
111+
if (optarg)
112+
printf (" with arg %s", optarg);
113+
printf ("\n");
114+
break;
115+
116+
case 'a':
117+
puts ("option -a\n");
118+
break;
119+
120+
case 'b':
121+
printf ("option -b with value `%s'\n", optarg);
122+
bytes_per_string = atoi(optarg);
123+
if(bytes_per_string<1 || bytes_per_string>10)
124+
{
125+
puts("Required 0<bytes_per_string<=10");
126+
exit(1);
127+
}
128+
break;
129+
130+
case 'c':
131+
printf ("option -c with value `%s'\n", optarg);
132+
break;
133+
134+
case 'i':
135+
printf ("option -i with value `%s'\n", optarg);
136+
strcpy(fin, optarg);
137+
break;
138+
139+
case 'o':
140+
printf ("option -o with value `%s'\n", optarg);
141+
strcpy(fout, optarg);
142+
break;
143+
144+
case 's':
145+
printf ("option -s with value `%s'\n", optarg);
146+
strcpy(separator, optarg);
147+
break;
148+
149+
case '?':
150+
/* getopt_long already printed an error message. */
151+
help(argv[0]);
152+
break;
153+
154+
default:
155+
abort ();
156+
}
157+
}
158+
159+
160+
if (verbose_flag)
161+
puts ("verbose flag is set");
162+
163+
/* Print any remaining command line arguments (not options). */
164+
if (optind < argc)
165+
{
166+
printf ("non-option ARGV-elements: ");
167+
while (optind < argc)
168+
printf ("%s ", argv[optind++]);
169+
putchar ('\n');
170+
}
171+
172+
// start processing
173+
fileIn = fopen(fin, "rb"); // open input file (binary)
174+
if (fileIn==NULL)
175+
{
176+
puts("Error opening input file");
177+
exit (1);
178+
}
179+
180+
// open output file
181+
fileOut = fopen(fout, "wt");
182+
if (fileOut==NULL)
183+
{
184+
puts("Error opening output file for write");
185+
exit (1);
186+
}
187+
188+
189+
// obtain file size.
190+
fseek (fileIn , 0 , SEEK_END);
191+
lSize = ftell (fileIn);
192+
rewind (fileIn);
193+
printf("Filesize: %d bytes.\n", lSize);
194+
if(lSize%bytes_per_string)
195+
{
196+
puts("Error: length of file isn't multiplication of bytes_per_string value.");
197+
puts("Please modify input file or select other formatting");
198+
exit (3);
199+
}
200+
201+
// allocate memory to contain the whole file.
202+
buffer = (unsigned char*) malloc (lSize);
203+
if (buffer == NULL)
204+
{
205+
puts("malloc for input file buffer failed (not enough memory?)");
206+
exit (2);
207+
}
208+
209+
// copy the file into the buffer.
210+
fread (buffer,1,lSize,fileIn);
211+
212+
switch(bytes_per_string)
213+
{
214+
case 1:
215+
stringlength = 4 + strlen(separator); //length of single converted string
216+
for(i=0; i<lSize-1; i++)
217+
{
218+
fprintf(fileOut,"0x%02X%s",buffer[i],separator);
219+
chars_in_line += stringlength;
220+
if(chars_in_line >= wrap_line)
221+
{
222+
fprintf(fileOut, "\n");
223+
chars_in_line = 0;
224+
}
225+
}
226+
fprintf(fileOut,"0x%02X",buffer[i]); //no separator after last string
227+
break;
228+
case 2:
229+
stringlength = 6 + strlen(separator);
230+
for(i=0; i<lSize-2; i+=2)
231+
{
232+
fprintf(fileOut,"0x%04X%s",(unsigned int)(buffer[i]*256 +
233+
buffer[i+1]), separator);
234+
chars_in_line += stringlength;
235+
if(chars_in_line >= wrap_line)
236+
{
237+
fprintf(fileOut, "\n");
238+
chars_in_line = 0;
239+
}
240+
}
241+
fprintf(fileOut,"0x%04X",(unsigned int)(buffer[i]*256 +
242+
buffer[i+1]));
243+
break;
244+
case 4:
245+
stringlength = 10 + strlen(separator);
246+
for(i=0; i<lSize-4; i+=4)
247+
{
248+
fprintf(fileOut,"0x%08X%s",(unsigned int)(buffer[i]*16777216 +
249+
buffer[i+1]*65536 + buffer[i+2]*256 +
250+
buffer[i+3]), separator);
251+
chars_in_line += stringlength;
252+
if(chars_in_line >= wrap_line)
253+
{
254+
fprintf(fileOut, "\n");
255+
chars_in_line = 0;
256+
}
257+
}
258+
fprintf(fileOut,"0x%08X",(unsigned int)(buffer[i]*16777216 +
259+
buffer[i+1]*65536 + buffer[i+2]*256 +
260+
buffer[i+3]));
261+
break;
262+
default:
263+
puts("Sorry, processing for this bytes_per_string value not implemented yet");
264+
}
265+
printf("%d strings printed to file\n", i/bytes_per_string+1);
266+
267+
if(fileIn) fclose (fileIn);
268+
if(fileOut) fclose (fileOut);
269+
if(buffer) free (buffer);
270+
exit (0);
271+
}

tools/get_addr_unicode.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#!/usr/bin/env python
2+
# encoding: utf-8
3+
4+
char_list = set()
5+
6+
with open("dict.txt") as f:
7+
while True:
8+
lines = f.readlines(1024 * 1024)
9+
if not lines:
10+
break
11+
for line in lines:
12+
for c in line:
13+
char_list.add(c)
14+
15+
def hex_to_char(unicode):
16+
return unicode.replace("0x", "\\u").encode("utf-8").decode("unicode_escape")
17+
18+
def char_to_hex(char):
19+
return char.encode("unicode_escape").decode("utf-8").replace("\\u", "0x")
20+
21+
def is_hans_char(char):
22+
return len(char.encode("unicode_escape")) > 4
23+
24+
chinese_list = [char_to_hex(x) for x in char_list if is_hans_char(x)];
25+
# for char in chinese_list:
26+
# print(hex_to_char(char) + " " + char)
27+
print("字符数量=" + str(len(chinese_list)))
28+
print(", ".join(chinese_list))

tools/get_dict.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#!/usr/bin/env python
2+
# encoding: utf-8
3+
4+
# 生成的字库包含下面三部分,可以重复,下个脚本会去重
5+
# 495 个常用汉字
6+
#chinese_list = [ "雕", "虎", "的", "一", "了", "是", "我", "不", "在", "人", "们", "有", "来", "他", "这", "上", "着", "个", "地", "到", "大", "里", "说", "就", "去", "子", "得", "也", "和", "那", "要", "下", "看", "天", "时", "过", "出", "小", "么", "起", "你", "都", "把", "好", "还", "多", "没", "为", "又", "可", "家", "学", "只", "以", "主", "会", "样", "年", "想", "生", "同", "老", "中", "十", "从", "自", "面", "前", "头", "道", "它", "后", "然", "走", "很", "像", "见", "两", "用", "她", "国", "动", "进", "成", "回", "什", "边", "作", "对", "开", "而", "己", "些", "现", "山", "民", "候", "经", "发", "工", "向", "事", "命", "给", "长", "水", "几", "义", "三", "声", "于", "高", "手", "知", "理", "眼", "志", "点", "心", "战", "二", "问", "但", "身", "方", "实", "吃", "做", "叫", "当", "住", "听", "革", "打", "呢", "真", "全", "才", "四", "已", "所", "敌", "之", "最", "光", "产", "情", "路", "分", "总", "条", "白", "话", "东", "席", "次", "亲", "如", "被", "花", "口", "放", "儿", "常", "气", "黄", "五", "第", "使", "写", "军", "木", "珍", "吧", "文", "运", "再", "果", "怎", "定", "许", "快", "明", "行", "因", "别", "飞", "外", "树", "物", "活", "部", "门", "无", "往", "船", "望", "新", "带", "队", "先", "力", "完", "却", "站", "代", "员", "机", "更", "九", "您", "每", "风", "级", "跟", "笑", "啊", "孩", "万", "少", "直", "意", "夜", "比", "阶", "连", "车", "重", "便", "斗", "马", "哪", "化", "太", "指", "变", "社", "似", "士", "者", "干", "石", "满", "梅", "日", "决", "百", "原", "拿", "群", "究", "各", "六", "本", "思", "解", "立", "河", "村", "八", "难", "早", "论", "吗", "根", "共", "让", "相", "研", "今", "其", "书", "坐", "接", "应", "关", "信", "觉", "步", "反", "处", "记", "将", "千", "找", "争", "领", "或", "师", "结", "块", "跑", "谁", "草", "越", "字", "加", "脚", "紧", "爱", "等", "习", "阵", "怕", "月", "青", "半", "火", "法", "题", "建", "赶", "位", "唱", "海", "七", "女", "任", "件", "感", "准", "张", "团", "屋", "离", "色", "脸", "片", "科", "倒", "睛", "利", "世", "刚", "且", "由", "送", "切", "星", "导", "晚", "表", "够", "整", "认", "响", "雪", "流", "未", "场", "该", "并", "底", "深", "刻", "平", "伟", "忙", "提", "确", "近", "亮", "轻", "讲", "农", "古", "黑", "告", "界", "拉", "名", "呀", "土", "清", "阳", "照", "办", "史", "改", "历", "转", "画", "造", "嘴", "此", "治", "北", "必", "服", "雨", "穿", "内", "识", "验", "传", "业", "菜", "爬", "睡", "兴", "形", "量", "咱", "观", "苦", "体", "众", "通", "冲", "合", "破", "友", "度", "术", "饭", "公", "旁", "房", "极", "南", "枪", "读", "沙", "岁", "线", "野", "坚", "空", "收", "算", "至", "政", "城", "劳", "落", "钱", "特", "围", "弟", "胜", "教", "热", "展", "包", "歌", "类", "渐", "强", "数", "乡", "呼", "音", "答", "哥", "际", "旧", "神", "座", "章", "帮", "啦", "受", "系", "令", "跳", "非", "何", "牛", "取", "入", "岸", "敢", "掉", "忽", "种", "装", "顶", "急", "戴", "林", "停", "息", "句", "区", "衣", "般", "报", "叶", "压", "慢", "叔", "背", "细", "艳", "佐"]
7+
# 和风天气的地址获取地名汉字
8+
addr_file = "China-City-List-latest.csv"
9+
# 添加以下地区的区县,其他地方不添加区县字库(不然生成的文件太大了,固件放不下~)
10+
county_list = ["北京市", "天津市", "上海市", "广州市", "深圳市"]
11+
# 自定义汉字
12+
additional_list = ["℃", "廿", "小", "雨", "转", "多", "云", "晴", "空", "气", "质", "量", "温", "度", "东", "西", "南", "北", "风", "向", "级", "最", "高", "低", "优", "良", "重", "轻", "实", "时", "今", "日", "月", "周", "一", "二", "三", "四", "五", "六", "七", "八", "九", "十"]
13+
14+
chinese_addr_list = set()
15+
with open(addr_file) as f:
16+
while True:
17+
lines = f.readlines(1024 * 1024)
18+
if not lines:
19+
break
20+
for line in lines:
21+
row = line.split(",")
22+
start_idx = 2 if row[7] in county_list else 5
23+
for i in range(start_idx, 10):
24+
for char in row[i]:
25+
chinese_addr_list.add(char)
26+
27+
# print("".join(chinese_list))
28+
print("".join(chinese_addr_list))
29+
print("".join(additional_list))

tools/get_unicode.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#!/usr/bin/env python
2+
# encoding: utf-8
3+
4+
char_list = set()
5+
6+
with open("dict.txt") as f:
7+
while True:
8+
lines = f.readlines(1024 * 1024)
9+
if not lines:
10+
break
11+
for line in lines:
12+
for c in line:
13+
char_list.add(c)
14+
15+
def hex_to_char(unicode):
16+
return unicode.replace("0x", "\\u").encode("utf-8").decode("unicode_escape")
17+
18+
def char_to_hex(char):
19+
return char.encode("unicode_escape").decode("utf-8").replace("\\u", "0x")
20+
21+
def is_hans_char(char):
22+
return len(char.encode("unicode_escape")) > 4
23+
24+
chinese_list = [char_to_hex(x) for x in char_list if is_hans_char(x)];
25+
# for char in chinese_list:
26+
# print(hex_to_char(char) + " " + char)
27+
# print(len(chinese_list))
28+
print(", ".join(sorted(chinese_list)))

0 commit comments

Comments
 (0)