chore: 上线前测试修复与部署配置更新
- fix(test): 添加 useSearchParams mock,修正联系链接断言 - style(nav): 将"联系我们"改为"联系" - chore(deploy): 更新 Nginx 配置和部署文档 - style(logo): 更新 Logo SVG 文件 - feat(scripts): 添加字体处理和站点配置脚本
This commit was merged in pull request #9.
This commit is contained in:
@@ -0,0 +1,134 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""将青柳隷書字体中的文字转换为 SVG 路径"""
|
||||
|
||||
from fontTools.ttLib import TTFont
|
||||
from fontTools.ttLib.tables import _h_m_t_x, _g_a_s_p
|
||||
import os
|
||||
|
||||
# 修补表解析
|
||||
original_hmtx = _h_m_t_x.table__h_m_t_x.decompile
|
||||
def patched_hmtx(self, data, ttFont):
|
||||
try: return original_hmtx(self, data, ttFont)
|
||||
except: self.metrics = {}
|
||||
_h_m_t_x.table__h_m_t_x.decompile = patched_hmtx
|
||||
|
||||
original_gasp = _g_a_s_p.table__g_a_s_p.decompile
|
||||
def patched_gasp(self, data, ttFont):
|
||||
try: return original_gasp(self, data, ttFont)
|
||||
except: self.gaspRanges = {}
|
||||
_g_a_s_p.table__g_a_s_p.decompile = patched_gasp
|
||||
|
||||
def get_glyph_path(font, char):
|
||||
"""获取字符的 SVG 路径"""
|
||||
cmap = font.getBestCmap()
|
||||
codepoint = ord(char)
|
||||
|
||||
if codepoint not in cmap:
|
||||
print(f"警告: 字符 '{char}' (U+{codepoint:04X}) 不在字体中")
|
||||
return None, None
|
||||
|
||||
glyph_name = cmap[codepoint]
|
||||
|
||||
# 获取 glyf 表
|
||||
glyf_table = font['glyf']
|
||||
glyph = glyf_table[glyph_name]
|
||||
|
||||
# 获取度量
|
||||
hmtx = font['hmtx']
|
||||
advance_width, lsb = hmtx[glyph_name]
|
||||
|
||||
# 获取边界框
|
||||
if hasattr(glyph, 'xMin') and glyph.xMin is not None:
|
||||
bbox = (glyph.xMin, glyph.yMin, glyph.xMax, glyph.yMax)
|
||||
else:
|
||||
bbox = (0, 0, advance_width, 1000)
|
||||
|
||||
# 获取字形轮廓
|
||||
try:
|
||||
coords, endPts, flags = glyph.getCoordinates(glyf_table)
|
||||
except:
|
||||
print(f" 无法获取轮廓: {glyph_name}")
|
||||
return None, None
|
||||
|
||||
# 构建 SVG 路径
|
||||
path_parts = []
|
||||
start_idx = 0
|
||||
|
||||
for end_pt in endPts:
|
||||
contour_coords = coords[start_idx:end_pt + 1]
|
||||
contour_flags = flags[start_idx:end_pt + 1]
|
||||
|
||||
if len(contour_coords) > 0:
|
||||
path_parts.append(f"M {contour_coords[0][0]:.2f} {-contour_coords[0][1]:.2f}")
|
||||
|
||||
for i in range(1, len(contour_coords)):
|
||||
x, y = contour_coords[i]
|
||||
path_parts.append(f"L {x:.2f} {-y:.2f}")
|
||||
|
||||
path_parts.append("Z")
|
||||
|
||||
start_idx = end_pt + 1
|
||||
|
||||
return " ".join(path_parts), {'advance': advance_width, 'lsb': lsb, 'bbox': bbox}
|
||||
|
||||
# 加载字体
|
||||
font_path = 'public/fonts/AoyagiReisho.ttf'
|
||||
font = TTFont(font_path)
|
||||
|
||||
print("=" * 60)
|
||||
print("青柳隷書 字形路径提取")
|
||||
print("=" * 60)
|
||||
|
||||
chars = ['睿', '新', '致', '遠']
|
||||
glyphs_data = []
|
||||
|
||||
for char in chars:
|
||||
print(f"\n字符: {char} (U+{ord(char):04X})")
|
||||
path, metrics = get_glyph_path(font, char)
|
||||
if path and metrics:
|
||||
print(f" Advance: {metrics['advance']}, LSB: {metrics['lsb']}")
|
||||
print(f" BBox: {metrics['bbox']}")
|
||||
print(f" Path length: {len(path)} chars")
|
||||
glyphs_data.append({
|
||||
'char': char,
|
||||
'path': path,
|
||||
'metrics': metrics
|
||||
})
|
||||
|
||||
font.close()
|
||||
|
||||
# 生成 SVG
|
||||
print("\n" + "=" * 60)
|
||||
print("生成 SVG 文件...")
|
||||
print("=" * 60)
|
||||
|
||||
# 计算总宽度
|
||||
total_width = sum(g['metrics']['advance'] for g in glyphs_data)
|
||||
scale = 48 / 1000 # 缩放因子
|
||||
|
||||
svg_paths = []
|
||||
x_offset = 0
|
||||
|
||||
for g in glyphs_data:
|
||||
m = g['metrics']
|
||||
# 计算字符居中偏移
|
||||
char_width = m['advance'] * scale
|
||||
path = g['path']
|
||||
|
||||
# 缩放路径
|
||||
scaled_path = path
|
||||
for coord in [('M', 'L')]:
|
||||
pass # 路径已经是正确的格式
|
||||
|
||||
svg_paths.append(f''' <!-- {g['char']} -->
|
||||
<g transform="translate({x_offset:.2f}, 0) scale({scale})">
|
||||
<path d="{path}" fill="currentColor"/>
|
||||
</g>''')
|
||||
|
||||
x_offset += char_width
|
||||
|
||||
print(f"\n总宽度: {total_width * scale:.2f}px")
|
||||
print("\nSVG 路径组:")
|
||||
print("\n".join(svg_paths[:2]))
|
||||
print("...")
|
||||
Reference in New Issue
Block a user