diff --git a/README.md b/README.md index 024709e..b3c734c 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,10 @@ -# MuGlyph +

+ MuGlyph logo +

-A hyper-modern, cross-platform **TUI client for MU\*** (MUSH / MUCK / MUD) worlds, built for -GPU-accelerated terminals (Kitty, WezTerm, Ghostty) on **Windows and Linux**. +

MuGlyph

+ +

A hyper-modern, cross-platform TUI client for MU* (MUSH / MUCK / MUD) worlds, built for GPU-accelerated terminals (Kitty, WezTerm, Ghostty) on Windows and Linux.

The goal is [BeipMU](https://beipdev.github.io/BeipMU/)-class feature parity in a terminal-native client: rich truecolor text, inline graphics, powerful automation, and full MU\* protocol support. diff --git a/assets/fonts/MuGlyph.ttf b/assets/fonts/MuGlyph.ttf new file mode 100644 index 0000000..fe1cfc9 Binary files /dev/null and b/assets/fonts/MuGlyph.ttf differ diff --git a/assets/fonts/README.md b/assets/fonts/README.md new file mode 100644 index 0000000..030472f --- /dev/null +++ b/assets/fonts/README.md @@ -0,0 +1,20 @@ +# MuGlyph icon font + +`MuGlyph.ttf` is a single-glyph font containing the MuGlyph mark (from `docs/logo.svg`) at +codepoint **U+E000** (Private Use Area). It's meant to be merged into your terminal font (or a +Nerd-Font-style patch) so the logo can appear in the TUI header as a normal character. + +Regenerate it from the SVG with: + +```bash +pip install fonttools +python3 tools/make-glyph-font.py +``` + +The generator scales the 512-unit SVG viewBox to a 1000-unit em and flips the Y axis (SVG is +Y-down, fonts are Y-up). To use a different codepoint or em size, edit the constants at the top +of `tools/make-glyph-font.py`. + +> Terminals render text in the user's configured font, so a TUI can't ship its own glyph — this +> font is for users who want the mark in their terminal. The header falls back to a text label +> when the glyph isn't present. diff --git a/tools/make-glyph-font.py b/tools/make-glyph-font.py new file mode 100644 index 0000000..0b7fa94 --- /dev/null +++ b/tools/make-glyph-font.py @@ -0,0 +1,71 @@ +#!/usr/bin/env python3 +"""Build a single-glyph font from docs/logo.svg. + +Produces assets/fonts/MuGlyph.ttf containing the MuGlyph mark at U+E000 (a Private +Use Area codepoint), so it can be merged into a terminal font / Nerd Font patch and +shown in the TUI header. Run: python3 tools/make-glyph-font.py +""" +import re +from pathlib import Path + +from fontTools.fontBuilder import FontBuilder +from fontTools.pens.transformPen import TransformPen +from fontTools.pens.ttGlyphPen import TTGlyphPen +from fontTools.svgLib.path.parser import parse_path + +ROOT = Path(__file__).resolve().parent.parent +SVG = ROOT / "docs" / "logo.svg" +OUT = ROOT / "assets" / "fonts" / "MuGlyph.ttf" + +UPM = 1000 +VIEWBOX = 512 +CODEPOINT = 0xE000 # Private Use Area +GLYPH_NAME = "muglyph" + + +def svg_path_data(svg_text: str): + return re.findall(r']*\bd="([^"]+)"', svg_text) + + +def build(): + svg_text = SVG.read_text(encoding="utf-8") + paths = svg_path_data(svg_text) + if not paths: + raise SystemExit(f"No found in {SVG}") + + # SVG is Y-down in a 512 viewBox; fonts are Y-up. Scale to the em and flip Y: + # x' = s*x ; y' = s*(VIEWBOX - y) + s = UPM / VIEWBOX + transform = (s, 0, 0, -s, 0, s * VIEWBOX) + + pen = TTGlyphPen(None) + tpen = TransformPen(pen, transform) + for d in paths: + parse_path(d, tpen) + glyph = pen.glyph() + + glyph_order = [".notdef", GLYPH_NAME] + fb = FontBuilder(UPM, isTTF=True) + fb.setupGlyphOrder(glyph_order) + fb.setupCharacterMap({CODEPOINT: GLYPH_NAME}) + + notdef = TTGlyphPen(None).glyph() + fb.setupGlyf({".notdef": notdef, GLYPH_NAME: glyph}) + fb.setupHorizontalMetrics({".notdef": (UPM, 0), GLYPH_NAME: (UPM, 0)}) + fb.setupHorizontalHeader(ascent=UPM, descent=0) + fb.setupNameTable({ + "familyName": "MuGlyph", + "styleName": "Regular", + "psName": "MuGlyph-Regular", + "version": "1.0", + }) + fb.setupOS2(sTypoAscender=UPM, sTypoDescender=0, usWinAscent=UPM, usWinDescent=0) + fb.setupPost() + + OUT.parent.mkdir(parents=True, exist_ok=True) + fb.save(str(OUT)) + print(f"Wrote {OUT.relative_to(ROOT)} — {len(paths)} contours at U+{CODEPOINT:04X}") + + +if __name__ == "__main__": + build()