#!/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''' {chr(10).join(svg_seal_line1)} {chr(10).join(svg_seal_line2)} {chr(10).join(svg_title_paths)} NOVALON ''' # 写入文件 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")