"""生成字标字体对比与印章高度对比(docs/design/logo/compare/)。 用法:.work/venv/bin/python scripts/wordmark_compare.py 字体文件在 .work/fonts/(不进 git),许可证见 compare/index.html 与 logo-spec.md。 """ import sys from pathlib import Path sys.path.insert(0, str(Path(__file__).resolve().parent)) from logo_lib import CN_H, GAP, LOGO, NAVY, PY_CAP, WHITE, lockup, wordmark # noqa: E402 OUT = LOGO / "compare" OUT.mkdir(exist_ok=True) # (编号, 中文字体, 中文字重, 中文字距(em), 拼音字体, 拼音字重, 名称, 许可证, 说明) PAIRS = [ ("F1", "NotoSerifSC[wght].ttf", 900, 0.00, "Cinzel[wght].ttf", 600, "思源宋体 Black + Cinzel", "OFL", "现用。最粗的宋体,庄重、有分量"), ("F2", "NotoSerifSC[wght].ttf", 600, 0.04, "CormorantGaramond[wght].ttf", 600, "思源宋体 SemiBold + Cormorant Garamond", "OFL", "同一家族的细一档,更清秀,和印章的轻重对比更明显"), ("F3", "ZhuqueFangsong.ttf", None, 0.06, "CormorantSC-SemiBold.ttf", None, "朱雀仿宋 + Cormorant SC", "OFL", "仿宋,招标文件和公文的正文字体,文书感最强"), ("F4", "HuiwenMincho.ttf", None, 0.04, "LibreCaslonText[wght].ttf", 700, "汇文明朝体 + Libre Caslon", "授权需复核", "老铅字印刷的宋体,带油墨感,和印章最搭;授权说明不规范"), ("F5", "LXGWWenKai-Medium.ttf", None, 0.06, "EBGaramond[wght].ttf", 600, "霞鹜文楷 + EB Garamond", "OFL", "楷书,书卷气,亲切但不够硬朗"), ("F6", "ZCOOLXiaoWei-Regular.ttf", None, 0.04, "MarcellusSC-Regular.ttf", None, "站酷小薇 LOGO 体 + Marcellus SC", "OFL", "为标志设计的宋体,笔画更有个性;但「标」的木字旁写成带钩的连笔,容易被看成「扌」,不建议"), ("F7", "NotoSansSC[wght].ttf", 900, 0.02, "Montserrat[wght].ttf", 600, "思源黑体 Black + Montserrat", "OFL", "黑体,现代、稳重,和传统印章形成反差"), ("F8", "SmileySans-Oblique.ttf", None, 0.02, "SmileySans-Oblique.ttf", None, "得意黑(中英同一字体)", "OFL", "带倾斜的现代黑体,年轻、有速度感"), ] # 1. 印章高度对比(字体 F1) body, w, h = wordmark(PAIRS[0], NAVY) cn_h = CN_H variants = [ ("H0", "现状:96%,上下没对齐", lockup(body, w, h, h * 0.961, (h - h * 0.961) / 2 + 0.6)), ("H1", "等高对齐:印章上下边对齐中文顶端和拼音底部", lockup(body, w, h, h, 0)), ("H2", "等高 + 光学补偿 2%:抵消印章颗粒边缘显虚", lockup(body, w, h, h * 1.02, -h * 0.01)), ("H3", "放大到 115%:图形主导", lockup(body, w, h, h * 1.15, -h * 0.075)), ("H4", "书法落款式:印章只与中文同高", lockup(body, w, h, cn_h, 0)), ] for vid, _, svg in variants: (OUT / f"height-{vid}.svg").write_text(svg) # 2. 字体对比(统一用 H2) for p in PAIRS: for color, dark, suffix in ((NAVY, False, ""), (WHITE, True, "-reverse")): body, w, h = wordmark(p, color) (OUT / f"font-{p[0]}{suffix}.svg").write_text(lockup(body, w, h, h * 1.02, -h * 0.01, on_dark=dark)) # 3. 对比页 rows_h = "".join(f'
{t}
{vid} {t}
' for vid, t, _ in variants) rows_f = "".join( f'

{p[0]} · {p[6]}

{p[8]}{p[7]}

' f'
{p[6]} 浅色底
' f'
{p[6]} 深色底
' f'
' for p in PAIRS) html = f""" 字标与比例对比

字标与比例对比

两个问题:一、印章和右边文字的高度关系;二、字标字体。所有版本都用同一枚印章,文字已转成路径。

一、印章高度

字体统一用 F1。H0 是现在的版本,H2 是建议的版本。

{rows_h}

二、字标字体

比例统一用 H2。每组下面一行是 200px 和 120px 宽度的实际效果。

{rows_f}
""" (OUT / "index.html").write_text(html) print("ok", len(PAIRS), "fonts,", len(variants), "height variants") # 4. 英文字体对比:中文固定为 F2(思源宋体 SemiBold),比例 H2 # (编号, 英文字体, 字重, 名称, 对应的经典字体 / 类型, 说明) EN_OPTIONS = [ ("E0", "CormorantGaramond[wght].ttf", 600, "Cormorant Garamond", "Garamond 类 · 古典衬线", "现选(F2)。纤细优雅,笔画对比高"), ("E1", "Cinzel[wght].ttf", 500, "Cinzel", "Trajan 类 · 罗马碑刻大写", "庄重、权威,金融和教育机构常用的气质"), ("E2", "MarcellusSC-Regular.ttf", None, "Marcellus SC", "Optima / Albertus 类 · 半衬线", "笔画末端微微张开,介于衬线和无衬线之间,和宋体很合拍"), ("E3", "TenorSans-Regular.ttf", None, "Tenor Sans", "Optima 类 · 人文无衬线", "无衬线但有书法韵味,现代而不冷"), ("E4", "EBGaramond[wght].ttf", 600, "EB Garamond", "Garamond · 古典衬线", "比 E0 更结实、更正统的 Garamond"), ("E5", "LibreCaslonText[wght].ttf", 600, "Libre Caslon", "Caslon · 老派衬线", "英国老字号和出版社的经典选择,沉稳"), ("E6", "SourceSerif4[opsz,wght].ttf", 600, "Source Serif 4", "与思源宋体同属 Adobe Source 家族", "和中文出自同一设计体系,最协调、最「工整」"), ("E7", "BodoniModa[opsz,wght].ttf", 600, "Bodoni Moda", "Didot / Bodoni 类 · 现代高对比", "时尚、精致,奢侈品和杂志常用"), ("E8", "Jost[wght].ttf", 500, "Jost", "Futura 类 · 几何无衬线", "现代、干净,和传统印章形成反差"), ] cn = PAIRS[1] # F2 for eid, ef, ew, *_ in EN_OPTIONS: pair = (eid, cn[1], cn[2], cn[3], ef, ew) for color, dark, suffix in ((NAVY, False, ""), (WHITE, True, "-reverse")): body, w, h = wordmark(pair, color) (OUT / f"en-{eid}{suffix}.svg").write_text(lockup(body, w, h, h * 1.02, -h * 0.01, on_dark=dark)) rows_e = "".join( f'

{e[0]} · {e[3]}

{e[4]}。{e[5]}OFL

' f'
{e[3]} 浅色底
' f'
{e[3]} 深色底
' f'
' for e in EN_OPTIONS) (OUT / "english.html").write_text(html.split("

")[0] + f"""

英文字体对比(H2 + F2)

中文固定为思源宋体 SemiBold,比例固定为 H2,只换下方英文。全部是 Google Fonts 上的 SIL OFL 1.1 字体,可以免费商用、可以用在 logo 里。

{rows_e} """) print("ok", len(EN_OPTIONS), "english options") # 5. 英文特写:只显示拼音这一行,放大比较字形 py_top, py_h = CN_H * (1 + GAP), CN_H * PY_CAP for eid, ef, ew, *_ in EN_OPTIONS: body, w, h = wordmark((eid, cn[1], cn[2], cn[3], ef, ew), NAVY) (OUT / f"en-{eid}-detail.svg").write_text( f'{body}') detail = "".join(f'
{e[3]} 特写
{e[0]} {e[3]}
' for e in EN_OPTIONS) page = (OUT / "english.html").read_text() page = page.replace("", f'

英文特写

只看拼音这一行,放大比较字形细节。

{detail}
') (OUT / "english.html").write_text(page) print("ok detail") # 6. 英文视觉对齐补偿(H2 + F2 + E5) # 实测:中文两端只有细横画尖,英文两端是 B、I 的粗竖画;按墨迹浓度算英文左超 6.5、右超 7.7(中文字高 = 100) E5 = next(e for e in EN_OPTIONS if e[0] == "E5") ALIGN = [ ("C0", (0.0, 0.0), "不补偿:几何两端对齐(现状)"), ("C1", (3.5, 4.0), "补偿一半:左 3.5、右 4.0"), ("C2", (5.0, 5.8), "补偿约 3/4:左 5.0、右 5.8"), ("C3", (6.5, 7.7), "完全补偿:按墨迹浓度边缘对齐,左 6.5、右 7.7"), ] CN_VISUAL = (8.6, 315.4) # 中文「浓度 ≥ 15%」的视觉边缘(实测) pair_e5 = ("E5", cn[1], cn[2], cn[3], E5[1], E5[2]) for cid, ins, _ in ALIGN: for color, dark, suffix in ((NAVY, False, ""), (WHITE, True, "-reverse")): body, w, h = wordmark(pair_e5, color, inset=ins) (OUT / f"align-{cid}{suffix}.svg").write_text(lockup(body, w, h, h * 1.02, -h * 0.01, on_dark=dark)) # 带辅助线的字标特写:红线 = 中文视觉边缘,灰线 = 中文几何边界 body, w, h = wordmark(pair_e5, NAVY, inset=ins) guides = (f'' f'' f'' f'') (OUT / f"align-{cid}-guides.svg").write_text( f'{body}{guides}') rows_a = "".join( f'

{c[0]} · {c[2]}

' f'
{c[0]} 浅色底
' f'
{c[0]} 辅助线
' f'
' for c in ALIGN) (OUT / "alignment.html").write_text(html.split("

")[0] + f"""

英文视觉对齐补偿(H2 + F2 + E5)

右侧特写的辅助线:灰色虚线是中文的几何边界(最外的墨迹),红线是中文的视觉边缘(墨迹浓度达到行高 15% 的位置)。 补偿越多,英文越往红线靠。建议不看辅助线、只看左侧的整体效果做判断。

{rows_a} """) print("ok alignment")