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,180 @@
|
||||
#!/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''' <g transform="translate({x_offset:.2f}, 0) scale({scale})">
|
||||
<path d="{g['path']}" fill="currentColor"/>
|
||||
</g>''')
|
||||
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''' <g transform="translate({x_offset:.2f}, 0) scale({scale_seal})">
|
||||
<path d="{g['path']}" fill="white"/>
|
||||
</g>''')
|
||||
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''' <g transform="translate({x_offset:.2f}, 0) scale({scale_seal})">
|
||||
<path d="{g['path']}" fill="white"/>
|
||||
</g>''')
|
||||
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'''<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 480 120" width="480" height="120">
|
||||
<defs>
|
||||
<!-- 印章纹理滤镜 -->
|
||||
<filter id="sealTexture" x="0%" y="0%" width="100%" height="100%">
|
||||
<feTurbulence type="fractalNoise" baseFrequency="0.1" numOctaves="3" result="noise"/>
|
||||
<feDisplacementMap in="SourceGraphic" in2="noise" scale="2" xChannelSelector="R" yChannelSelector="G"/>
|
||||
</filter>
|
||||
</defs>
|
||||
|
||||
<!-- 红色印章 - 手绘不规则风格 -->
|
||||
<g transform="translate(12, 12)">
|
||||
<!-- 印章外框 - 不规则手绘路径 -->
|
||||
<path d="M8,2
|
||||
C25,-2 45,-2 72,3
|
||||
C82,5 85,12 84,25
|
||||
C83,40 85,55 84,70
|
||||
C83,82 78,88 65,89
|
||||
C45,91 25,90 10,88
|
||||
C2,86 -2,78 1,65
|
||||
C3,50 2,35 1,20
|
||||
C0,10 3,4 8,2 Z"
|
||||
fill="#C41E3A"/>
|
||||
<!-- 印章内框 - 手绘风格 -->
|
||||
<path d="M14,10
|
||||
C28,8 55,8 72,12
|
||||
C78,14 79,20 78,30
|
||||
C77,45 78,60 77,72
|
||||
C76,80 72,84 62,85
|
||||
C45,86 28,85 16,83
|
||||
C10,82 8,76 9,65
|
||||
C10,50 9,35 8,22
|
||||
C7,15 10,11 14,10 Z"
|
||||
fill="none" stroke="#fff" stroke-width="1.5" opacity="0.5"/>
|
||||
<!-- 睿新 - 书法字体路径 -->
|
||||
<g transform="translate({line1_x:.2f}, 38)">
|
||||
{chr(10).join(svg_seal_line1)}
|
||||
</g>
|
||||
<!-- 致遠 - 书法字体路径 -->
|
||||
<g transform="translate({line2_x:.2f}, 70)">
|
||||
{chr(10).join(svg_seal_line2)}
|
||||
</g>
|
||||
</g>
|
||||
|
||||
<!-- 公司名称 -->
|
||||
<g transform="translate(110, 60)">
|
||||
<!-- 睿新致遠 - 书法字体路径 -->
|
||||
<g transform="translate(0, 0)">
|
||||
{chr(10).join(svg_title_paths)}
|
||||
</g>
|
||||
<!-- NOVALON - 英文字体 -->
|
||||
<text x="24" y="42" font-family="Arial, sans-serif" font-size="14.5" font-weight="500" fill="currentColor" letter-spacing="10.5">NOVALON</text>
|
||||
</g>
|
||||
</svg>'''
|
||||
|
||||
# 写入文件
|
||||
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")
|
||||
Reference in New Issue
Block a user