#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""将青柳隷書字体中的文字转换为 SVG 路径并生成 logo"""
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:
return None, None
glyph_name = cmap[codepoint]
glyf_table = font['glyf']
glyph = glyf_table[glyph_name]
hmtx = font['hmtx']
advance_width, lsb = hmtx[glyph_name]
try:
coords, endPts, flags = glyph.getCoordinates(glyf_table)
except:
return None, None
path_parts = []
start_idx = 0
for end_pt in endPts:
contour_coords = coords[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}
# 加载字体
font = TTFont('public/fonts/AoyagiReisho.ttf')
chars = ['睿', '新', '致', '遠']
glyphs_data = []
for char in chars:
path, metrics = get_glyph_path(font, char)
if path and metrics:
glyphs_data.append({'char': char, 'path': path, 'metrics': metrics})
font.close()
# 生成主标题 SVG 路径
scale = 48 / 1000
total_width = sum(g['metrics']['advance'] for g in glyphs_data) * scale
svg_title_paths = []
x_offset = 0
for g in glyphs_data:
svg_title_paths.append(f'''
''')
x_offset += g['metrics']['advance'] * scale
# 生成印章内文字 (较小尺寸)
scale_seal = 26 / 1000
# 睿新
svg_seal_line1 = []
x_offset = 0
for char in ['睿', '新']:
g = next((x for x in glyphs_data if x['char'] == char), None)
if g:
svg_seal_line1.append(f'''
''')
x_offset += g['metrics']['advance'] * scale_seal
# 致遠
svg_seal_line2 = []
x_offset = 0
for char in ['致', '遠']:
g = next((x for x in glyphs_data if x['char'] == char), None)
if g:
svg_seal_line2.append(f'''
''')
x_offset += g['metrics']['advance'] * scale_seal
# 计算印章文字居中偏移
line1_width = sum(g['metrics']['advance'] for g in glyphs_data if g['char'] in ['睿', '新']) * scale_seal
line2_width = sum(g['metrics']['advance'] for g in glyphs_data if g['char'] in ['致', '遠']) * scale_seal
seal_center = 43 # 印章中心 x 坐标
line1_x = seal_center - line1_width / 2
line2_x = seal_center - line2_width / 2
# 生成完整 SVG
svg_content = f''''''
# 写入文件
with open('public/logo.svg', 'w', encoding='utf-8') as f:
f.write(svg_content)
print("✅ 已生成 public/logo.svg")
# 生成白色版本 (logo-white.svg)
svg_white = svg_content.replace('fill="#C41E3A"', 'fill="currentColor"')
with open('public/logo-white.svg', 'w', encoding='utf-8') as f:
f.write(svg_white)
print("✅ 已生成 public/logo-white.svg")
print(f"\n标题总宽度: {total_width:.2f}px")