backup codes

This commit is contained in:
2026-01-30 12:58:30 +08:00
parent 95f2bf2e4a
commit 1a95d6c005
5 changed files with 415 additions and 26 deletions

View File

@@ -1,15 +1,49 @@
#!/bin/bash
# -*- coding: utf-8 -*-
CN_TEXT='配置设备网络连接热点自动进入页面0123456789 abcdefghijklmnopqrstuvwxyz:ABCDEFGHIJKLMNOPQRSTUVWXYZ!%*+,-./()[]\"<>=?℃'
CN_TEXT='北京月日星期一二三四五六末优良中差污恶能见度配置设备网络连接热点自动进入页面0123456789 abcdefghijklmnopqrstuvwxyz:ABCDEFGHIJKLMNOPQRSTUVWXYZ!%*+,-./()[]\"<>=?℃'
TIME_TEXT='0123456789: .-'
SRC_DIR=./assets
DST_DIR=../src/rom/fonts
OTF_FONT=$SRC_DIR/NotoSansSC-Regular.otf
README=$DST_DIR/README.md
python3 pyfont_to_bin.py $SRC_DIR/romand.py $DST_DIR/en-32x32.hfont
python3 pyfont_to_bin.py $SRC_DIR/vga1_8x16.py $DST_DIR/en-8x16.rfont
python3 pyfont_to_bin.py $SRC_DIR/vga1_16x32.py $DST_DIR/en-16x32.rfont
# 中文黑体源字体
CN_OTF_FONT=$SRC_DIR/STHeiti.ttc
# 英文时间源字体
TIME_OTF_FONT=$SRC_DIR/BloodWaxItalic.otf
python3 font2bitmap.py -s "$CN_TEXT" $OTF_FONT 22 > $SRC_DIR/cn-22x24.py
python3 pyfont_to_bin.py $SRC_DIR/cn-22x24.py $DST_DIR/cn-22x24.bfont
echo "# 字体文件说明" > $README
echo "" >>$README
echo "1. en0.rfont/en1.rfont 英文字体" >> $README
echo "> 顺序排列,相等大小、可快速定位" >> $README
echo "" >>$README
python3 pyfont_to_bin.py $SRC_DIR/vga1_8x16.py $DST_DIR/en0.rfont
python3 pyfont_to_bin.py $SRC_DIR/vga1_16x32.py $DST_DIR/en1.rfont
echo "2. en.hfont 矢量英文字体" >> $README
echo "> 顺序排列,带索引表,只画线无背景色,可自由缩放,显示速度快" >> $README
echo "" >>$README
python3 pyfont_to_bin.py $SRC_DIR/romand.py $DST_DIR/en.hfont
echo "3. cn.bfont 中文字体" >> $README
echo "> 有字符MAP表当前顺序查找、需实现二叉树查找" >> $README
echo "" >>$README
python3 font2bitmap.py -s "$CN_TEXT" $CN_OTF_FONT 22 > $SRC_DIR/cn.py
python3 pyfont_to_bin.py $SRC_DIR/cn.py $DST_DIR/cn.bfont
echo "4. time.bfont 时间字体" >> $README
echo "> 有字符MAP表当前顺序查找、需实现二叉树查找" >> $README
echo "" >>$README
python3 font2bitmap.py -s "$TIME_TEXT" $TIME_OTF_FONT 48 > $SRC_DIR/time.py
python3 pyfont_to_bin.py $SRC_DIR/time.py $DST_DIR/time.bfont
# 开始转换图片文件
SRC_DIR=./assets
DST_DIR=../src/rom/images
# 透明色转换成黑色背景质量95%
python3 png_to_jpg.py -d $SRC_DIR/ --color black --quality 100
cp -v $SRC_DIR/*.jpg $DST_DIR/

253
utils/icons.html Normal file
View File

@@ -0,0 +1,253 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>常用天气符号</title>
<!-- 引入Font Awesome -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css">
<style>
body {
font-family: Arial, sans-serif;
padding: 20px;
background-color: #f0f0f0;
}
h1 {
text-align: center;
color: #333;
}
.container {
display: flex;
flex-wrap: wrap;
justify-content: center;
gap: 20px;
margin-top: 30px;
}
.weather-icon {
background-color: white;
border-radius: 10px;
padding: 20px;
text-align: center;
width: 150px;
box-shadow: 0 4px 8px rgba(0,0,0,0.1);
transition: transform 0.3s;
}
.weather-icon:hover {
transform: translateY(-5px);
}
.weather-icon i {
font-size: 48px;
margin-bottom: 10px;
}
.weather-icon .icon-name {
font-size: 18px;
color: #555;
}
.weather-icon .icon-class {
font-size: 12px;
color: #888;
margin-top: 5px;
word-break: break-all;
}
.fas.fa-sun { color: #FFD700; }
.fas.fa-cloud-sun { color: #87CEEB; }
.fas.fa-cloud { color: #A9A9A9; }
.fas.fa-cloud-rain { color: #4682B4; }
.fas.fa-bolt { color: #FF4500; }
.fas.fa-snowflake { color: #B0E0E6; }
.fas.fa-smog { color: #696969; }
.fas.fa-wind { color: #708090; }
.fas.fa-cloud-showers-heavy { color: #1E90FF; }
.fas.fa-question-circle { color: #32CD32; }
</style>
</head>
<body>
<h1>常用天气符号</h1>
<div class="container">
<!-- 晴天 -->
<div class="weather-icon">
<i class="fas fa-sun"></i>
<div class="icon-name">晴天</div>
<div class="icon-class">fas fa-sun</div>
</div>
<!-- 多云转晴 -->
<div class="weather-icon">
<i class="fas fa-cloud-sun"></i>
<div class="icon-name">多云转晴</div>
<div class="icon-class">fas fa-cloud-sun</div>
</div>
<!-- 多云 -->
<div class="weather-icon">
<i class="fas fa-cloud"></i>
<div class="icon-name">多云</div>
<div class="icon-class">fas fa-cloud</div>
</div>
<!-- 雨天 -->
<div class="weather-icon">
<i class="fas fa-cloud-rain"></i>
<div class="icon-name">雨天</div>
<div class="icon-class">fas fa-cloud-rain</div>
</div>
<!-- 雷雨 -->
<div class="weather-icon">
<i class="fas fa-bolt"></i>
<div class="icon-name">雷雨</div>
<div class="icon-class">fas fa-bolt</div>
</div>
<!-- 雪天 -->
<div class="weather-icon">
<i class="fas fa-snowflake"></i>
<div class="icon-name">雪天</div>
<div class="icon-class">fas fa-snowflake</div>
</div>
<!-- 雾天 -->
<div class="weather-icon">
<i class="fas fa-smog"></i>
<div class="icon-name">雾天</div>
<div class="icon-class">fas fa-smog</div>
</div>
<!-- 大风 -->
<div class="weather-icon">
<i class="fas fa-wind"></i>
<div class="icon-name">大风</div>
<div class="icon-class">fas fa-wind</div>
</div>
<!-- 暴雨 -->
<div class="weather-icon">
<i class="fas fa-cloud-showers-heavy"></i>
<div class="icon-name">暴雨</div>
<div class="icon-class">fas fa-cloud-showers-heavy</div>
</div>
<!-- 太阳雨 -->
<div class="weather-icon">
<i class="fas fa-question-circle"></i>
<div class="icon-name">未知</div>
<div class="icon-class">fas fa-question-circle</div>
</div>
</div>
<script>
// 可以添加一些交互效果,例如点击图标复制类名
document.querySelectorAll('.weather-icon').forEach(icon => {
icon.addEventListener('click', function() {
const iconClass = this.querySelector('.icon-class').textContent;
navigator.clipboard.writeText(iconClass).then(() => {
alert('已复制类名: ' + iconClass);
});
});
});
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.7.1/jszip.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/2.0.5/FileSaver.min.js"></script>
<script>
// 添加下载按钮
const downloadBtn = document.createElement('button');
downloadBtn.innerHTML = '📥 下载所有图标为PNG (48x48)';
downloadBtn.style.cssText = `
display: block;
margin: 30px auto;
padding: 15px 30px;
font-size: 18px;
background: linear-gradient(135deg, #4CAF50, #2E7D32);
color: white;
border: none;
border-radius: 8px;
cursor: pointer;
transition: transform 0.3s, box-shadow 0.3s;
`;
downloadBtn.onmouseover = () => {
downloadBtn.style.transform = 'translateY(-2px)';
downloadBtn.style.boxShadow = '0 6px 12px rgba(0,0,0,0.2)';
};
downloadBtn.onmouseout = () => {
downloadBtn.style.transform = 'translateY(0)';
downloadBtn.style.boxShadow = 'none';
};
// 插入按钮到页面
document.querySelector('.container').after(downloadBtn);
// 映射Font Awesome类名到Unicode字符
const faUnicodeMap = {
'fa-sun': '\uf185',
'fa-cloud-sun': '\uf6c4',
'fa-cloud': '\uf0c2',
'fa-cloud-rain': '\uf73d',
'fa-bolt': '\uf0e7',
'fa-snowflake': '\uf2dc',
'fa-smog': '\uf75f',
'fa-wind': '\uf72e',
'fa-cloud-showers-heavy': '\uf740',
'fa-question-circle': '\uf059'
};
// 下载所有图标
downloadBtn.addEventListener('click', async () => {
downloadBtn.disabled = true;
downloadBtn.innerHTML = '⏳ 正在生成PNG图片...';
try {
// 等待字体加载
await document.fonts.ready;
const zip = new JSZip();
const promises = [];
// 获取所有图标元素
const iconElements = document.querySelectorAll('.weather-icon i');
iconElements.forEach((iconEl, index) => {
const className = Array.from(iconEl.classList)
.find(cls => cls.startsWith('fa-'));
if (!className) return;
const iconName = className.replace('fa-', '');
const color = getComputedStyle(iconEl).color;
const unicodeChar = faUnicodeMap[className] || '\uf071';
// 创建Canvas
const canvas = document.createElement('canvas');
canvas.width = 48;
canvas.height = 48;
const ctx = canvas.getContext('2d');
// 设置透明背景
ctx.clearRect(0, 0, 48, 48);
// 绘制图标
ctx.font = 'normal normal 900 40px "Font Awesome 6 Free"';
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
ctx.fillStyle = color;
ctx.fillText(unicodeChar, 24, 24);
// 将Canvas转换为PNG并添加到ZIP
canvas.toBlob(blob => {
zip.file(`${iconName}.png`, blob);
}, 'image/png');
});
// 创建ZIP文件
setTimeout(async () => {
const content = await zip.generateAsync({type: 'blob'});
saveAs(content, 'weather-icons.zip');
downloadBtn.disabled = false;
downloadBtn.innerHTML = '✅ 下载完成!再次下载';
setTimeout(() => {
downloadBtn.innerHTML = '📥 下载所有图标为PNG (48x48)';
}, 3000);
}, 1000);
} catch (error) {
console.error('下载失败:', error);
downloadBtn.disabled = false;
downloadBtn.innerHTML = '❌ 下载失败,点击重试';
}
});
</script>
</body>
</html>

View File

@@ -148,10 +148,10 @@ def convert_to_bfont(namespace, input_file, output_file=None):
"bpp": bpp, # Store BPP value
}
# Update output filename if needed (only if it doesn't already include dimensions)
if output_file and not output_file.endswith(f"-{width}x{height}.bfont"):
# Update output filename if needed
if output_file and os.path.isdir(output_file):
base_name = os.path.splitext(os.path.basename(input_file))[0]
output_dir = os.path.dirname(output_file)
output_dir = output_file
output_name = f"{base_name}-{width}x{height}.bfont"
output_file = os.path.join(output_dir, output_name)
@@ -221,10 +221,10 @@ def convert_to_hfont(namespace, input_file, output_file=None):
if size > max_char_size:
max_char_size = size
# Update output filename if needed (only if it doesn't already include dimensions)
if output_file and not output_file.endswith(f"-{width}x{height}.hfont"):
# Update output filename if needed
if output_file and os.path.isdir(output_file):
base_name = os.path.splitext(os.path.basename(input_file))[0]
output_dir = os.path.dirname(output_file)
output_dir = output_file
output_name = f"{base_name}-{width}x{height}.hfont"
output_file = os.path.join(output_dir, output_name)
@@ -293,10 +293,10 @@ def convert_to_rfont(namespace, input_file, output_file=None):
bytes_per_line = (width + 7) // 8
bytes_per_char = bytes_per_line * height
# Update output filename if needed (only if it doesn't already include dimensions)
if output_file and not output_file.endswith(f"-{width}x{height}.rfont"):
# Update output filename if needed
if output_file and os.path.isdir(output_file):
base_name = os.path.splitext(os.path.basename(input_file))[0]
output_dir = os.path.dirname(output_file)
output_dir = output_file
output_name = f"{base_name}-{width}x{height}.rfont"
output_file = os.path.join(output_dir, output_name)
@@ -411,7 +411,7 @@ def convert_to_binary(input_file, output_file=None):
else:
output_path = os.path.dirname(input_file)
output_name = "" # Will be set by each conversion function
output_file = output_path
# Parse the pyfont file using exec()
namespace = {}
@@ -421,6 +421,7 @@ def convert_to_binary(input_file, output_file=None):
# Detect the font type
font_type = detect_font_type(namespace, input_file)
'''
# Generate default output file name if not provided or directory specified
if output_file is None:
base_name = os.path.splitext(os.path.basename(input_file))[0]
@@ -452,6 +453,7 @@ def convert_to_binary(input_file, output_file=None):
output_name = f"{base_name}.bin"
output_file = os.path.join(output_path, output_name)
'''
# Convert based on the detected format
if font_type == "bfont":