2c01752017
将 TTF 字体转换为更高效的 WOFF2 格式,添加字体子集化脚本以减小文件大小 优化字体预加载和显示策略,改进无障碍标签
135 lines
3.6 KiB
Python
135 lines
3.6 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
字体子集化脚本 - 优化 AoyagiReisho 字体
|
|
只保留网站实际使用的汉字字符,大幅减小字体文件大小
|
|
"""
|
|
|
|
import os
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
try:
|
|
from fontTools.ttLib import TTFont
|
|
from fontTools.subset import Subsetter, Options
|
|
except ImportError:
|
|
print("❌ 缺少 fonttools 库")
|
|
print("请运行: pip install fonttools brotli")
|
|
sys.exit(1)
|
|
|
|
|
|
def create_font_subset(
|
|
input_font: str,
|
|
output_font: str,
|
|
chars_file: str,
|
|
output_format: str = "woff2"
|
|
):
|
|
"""
|
|
创建字体子集
|
|
|
|
Args:
|
|
input_font: 输入字体文件路径
|
|
output_font: 输出字体文件路径
|
|
chars_file: 包含所需字符的文本文件
|
|
output_format: 输出格式 (ttf, woff, woff2)
|
|
"""
|
|
print(f"📝 正在读取字符列表: {chars_file}")
|
|
|
|
# 读取所需字符
|
|
with open(chars_file, 'r', encoding='utf-8') as f:
|
|
chars = set(f.read())
|
|
|
|
# 移除空白字符
|
|
chars = chars - {'\n', '\r', '\t', ' '}
|
|
|
|
print(f"✅ 共需保留 {len(chars)} 个字符")
|
|
|
|
# 加载字体
|
|
print(f"📥 正在加载字体: {input_font}")
|
|
font = TTFont(input_font)
|
|
|
|
original_size = os.path.getsize(input_font) / 1024 / 1024
|
|
print(f"📊 原始字体大小: {original_size:.2f} MB")
|
|
|
|
# 创建子集化器
|
|
options = Options()
|
|
# 不删除必要的表
|
|
options.flavor = output_format
|
|
|
|
subsetter = Subsetter(options=options)
|
|
|
|
# 添加所需字符
|
|
subsetter.populate(chars)
|
|
|
|
# 执行子集化
|
|
print("⚙️ 正在创建字体子集...")
|
|
subsetter.subset(font)
|
|
|
|
# 保存字体
|
|
print(f"💾 正在保存字体: {output_font}")
|
|
font.save(output_font)
|
|
font.close()
|
|
|
|
# 统计结果
|
|
new_size = os.path.getsize(output_font) / 1024 / 1024
|
|
reduction = (1 - new_size / original_size) * 100
|
|
|
|
print(f"\n✨ 优化完成!")
|
|
print(f"📊 新字体大小: {new_size:.2f} MB")
|
|
print(f"📉 减小比例: {reduction:.1f}%")
|
|
print(f"💾 节省空间: {(original_size - new_size):.2f} MB")
|
|
|
|
|
|
def main():
|
|
# 项目根目录
|
|
project_root = Path(__file__).parent.parent
|
|
|
|
# 输入输出路径
|
|
input_font = project_root / "public/fonts/AoyagiReisho.ttf"
|
|
output_dir = project_root / "public/fonts"
|
|
chars_file = project_root / "scripts/font-chars.txt"
|
|
|
|
# 检查文件是否存在
|
|
if not input_font.exists():
|
|
print(f"❌ 字体文件不存在: {input_font}")
|
|
sys.exit(1)
|
|
|
|
if not chars_file.exists():
|
|
print(f"❌ 字符文件不存在: {chars_file}")
|
|
sys.exit(1)
|
|
|
|
# 创建输出目录
|
|
output_dir.mkdir(parents=True, exist_ok=True)
|
|
|
|
# 创建 WOFF2 格式
|
|
output_woff2 = output_dir / "AoyagiReisho.woff2"
|
|
print("\n🎨 创建 WOFF2 格式字体 (推荐)")
|
|
create_font_subset(
|
|
str(input_font),
|
|
str(output_woff2),
|
|
str(chars_file),
|
|
output_format="woff2"
|
|
)
|
|
|
|
# 创建 TTF 格式 (作为备选)
|
|
output_ttf = output_dir / "AoyagiReisho-subset.ttf"
|
|
print("\n🎨 创建 TTF 格式字体 (备选)")
|
|
create_font_subset(
|
|
str(input_font),
|
|
str(output_ttf),
|
|
str(chars_file),
|
|
output_format=None
|
|
)
|
|
|
|
print("\n" + "="*60)
|
|
print("✅ 所有字体优化完成!")
|
|
print("="*60)
|
|
print(f"\n📁 输出文件:")
|
|
print(f" - WOFF2: {output_woff2}")
|
|
print(f" - TTF: {output_ttf}")
|
|
print(f"\n💡 建议: 在 CSS 中优先使用 WOFF2 格式")
|
|
print(f" font-display: swap 可确保字体加载时文字可见")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|