diff --git a/llama.cpp/projects/logo/README.md b/llama.cpp/projects/logo/README.md index 0eb046f..de988b4 100644 --- a/llama.cpp/projects/logo/README.md +++ b/llama.cpp/projects/logo/README.md @@ -1,7 +1,10 @@ # Logo generators — llama.cpp-style brand family Two parameterised generators sharing one visual language (dark `#111`, Martian -Mono wordmark, orange accent, **embedded font — no outlines**): +Mono wordmark, orange accent). The wordmark ships two ways: as **real `` +with the font embedded** (default — editable, selectable) or, with +`--outline-text`, as **`` outlines** (font-independent, ~5× smaller — see +[Outlined wordmarks](#outlined-wordmarks---outline-text)): - **java-llama.cpp** — a 3-shard **"J"** icon (small hook top, stem, hook bottom, flush right edge) in the style of the @@ -13,14 +16,15 @@ Mono wordmark, orange accent, **embedded font — no outlines**): | File | Purpose | |---|---| -| `logolib.py` | Shared base: `BaseConfig` (canvas/font fields), font embedding, config load/write, PNG export, Martian Mono metrics, `fmt`. | +| `logolib.py` | Shared base: `BaseConfig` (canvas/font fields), font embedding, text→path outlining (`text_to_path_d`), config load/write, PNG export, Martian Mono metrics, `fmt`. | | `generate_java_llama_logo.py` | java-llama.cpp generator (shard-J geometry + wordmark). | | `java-llama-logo-config.json` | Config for the java-llama.cpp logo. | | `generate_srcmorph_logo.py` | srcmorph generator (wordmark + blurred m-in-"morph"). | | `srcmorph-logo-config.json` | Config for the srcmorph logo. | | `preview_icon.py` | Fast **shard-icon** preview (PIL, no font) — for J-shape iteration. | | `MartianMono-Regular.ttf` | Wordmark font (OFL-1.1), embedded into the SVG as base64. | -| `*-generated.svg` / `*.png` | Generated output. | +| `*-generated.svg` / `*.png` | Generated output (embedded-font wordmark). | +| `*-outlined.svg` | Generated output with the wordmark as `` outlines (`--outline-text`) — no embedded font, no ``. | **Font:** [Martian Mono](https://github.com/evilmartians/mono) by the Martian Mono Project Authors (Evil Martians), licensed under the SIL Open Font License @@ -49,18 +53,49 @@ python generate_java_llama_logo.py -c java-llama-logo-config.json \ # Write a fresh default config to edit python generate_java_llama_logo.py --write-default-config myconfig.json +# Font-independent wordmark: outlines instead of embedded font + +python generate_java_llama_logo.py -c java-llama-logo-config.json \ + --outline-text -o java-llama-cpp-outlined.svg + # Construction anchors overlay python generate_java_llama_logo.py -c java-llama-logo-config.json -o debug.svg --debug # Fast icon-shape preview while tuning geometry (no font needed) python preview_icon.py -c java-llama-logo-config.json -o preview_icon.png -# srcmorph — same flags +# srcmorph — same flags (including --outline-text) python generate_srcmorph_logo.py -c srcmorph-logo-config.json \ -o srcmorph-generated.svg --png srcmorph.png +python generate_srcmorph_logo.py -c srcmorph-logo-config.json \ + --outline-text -o srcmorph-outlined.svg python generate_srcmorph_logo.py --write-default-config srcmorph-logo-config.json ``` +## Outlined wordmarks (`--outline-text`) + +By default the wordmark is real `` with `MartianMono-Regular.ttf` +base64-embedded via `@font-face`. That blob is ~64 KB — about 98% of each +generated SVG — because it ships the *whole* font. `--outline-text` instead +converts only the glyphs actually used into `` outlines (via fontTools' +`text_to_path_d` in `logolib.py`), so the file drops to ~13–16 KB and needs no +font at all. The `srcmorph` blur is preserved: the `feGaussianBlur` filters move +from the `` onto the outlined groups (filters work on any element). + +| | Embedded font (default) | `--outline-text` | +|---|---|---| +| Wordmark markup | `` + `@font-face` | `` only | +| Self-contained / portable | ✅ | ✅ | +| Text selectable / restyleable / editable | ✅ | ❌ (frozen geometry) | +| Font binary redistributed in the file | yes (OFL-1.1, permitted) | no | +| Survives renderers that strip `{mdefs}" if style else mdefs return f""" @@ -187,6 +212,8 @@ def main() -> None: parser.add_argument("--write-default-config", type=Path, help="Write the default JSON config and exit") parser.add_argument("--png", type=Path, help="Also rasterise a PNG (needs 'pip install resvg-py')") parser.add_argument("--png-width", type=int, default=2250) + parser.add_argument("--outline-text", action="store_true", + help="Emit the wordmark as outlines (no embedded font, no )") args = parser.parse_args() if args.write_default_config: @@ -194,6 +221,9 @@ def main() -> None: return config = logolib.load_config(SrcmorphConfig, args.config) + if args.outline_text: + from dataclasses import replace + config = replace(config, outline_text=True) svg = build_svg(config) args.output.write_text(svg, encoding="utf-8") diff --git a/llama.cpp/projects/logo/java-llama-cpp-outlined.svg b/llama.cpp/projects/logo/java-llama-cpp-outlined.svg new file mode 100644 index 0000000..2e4b4d2 --- /dev/null +++ b/llama.cpp/projects/logo/java-llama-cpp-outlined.svg @@ -0,0 +1,19 @@ + + + java-llama.cpp cover + Shard J icon in the llama.cpp style with an outlined wordmark. + + + + + + + + + + + + + + diff --git a/llama.cpp/projects/logo/logolib.py b/llama.cpp/projects/logo/logolib.py index c3ec62b..95dc90b 100644 --- a/llama.cpp/projects/logo/logolib.py +++ b/llama.cpp/projects/logo/logolib.py @@ -54,6 +54,65 @@ def clamp01(v: float) -> float: return max(0.0, min(1.0, v)) +_FONT_CACHE: dict = {} + + +def _load_font(font_path: str): + """Load (and cache) a ``TTFont`` for outline extraction.""" + path = Path(font_path) if font_path else DEFAULT_FONT + key = str(path) + if key not in _FONT_CACHE: + if not path.exists(): + raise SystemExit(f"Font not found for outlining: {path}") + from fontTools.ttLib import TTFont # lazy: only needed for --outline-text + + _FONT_CACHE[key] = TTFont(key) + return _FONT_CACHE[key] + + +def text_to_path_d( + text: str, + font_size: float, + x0: float, + baseline: float, + letter_spacing: float = 0.0, + font_path: str = "", +) -> "tuple[str, float]": + """Convert a text run to one SVG path ``d`` string using the font outlines. + + Each glyph outline is baked into a shared path via a per-glyph affine that + scales font units to user units and flips y (font y-up -> SVG y-down): + ``(s, 0, 0, -s, x, baseline)`` with ``s = font_size / unitsPerEm``. Advances + come from the font's ``hmtx`` (monospaced 700/1000 for Martian Mono), so the + glyphs land on exactly the same x-positions the ```` layout produces. + + Returns ``(d, end_x)`` where ``end_x`` is the pen position after the run, so + callers can chain differently-coloured runs (e.g. ``java-`` then ``llama.cpp``). + """ + from fontTools.pens.svgPathPen import SVGPathPen + from fontTools.pens.transformPen import TransformPen + + font = _load_font(font_path) + upm = font["head"].unitsPerEm + cmap = font.getBestCmap() + glyph_set = font.getGlyphSet() + hmtx = font["hmtx"] + scale = font_size / upm + + pen = SVGPathPen(glyph_set) + x = x0 + for ch in text: + gname = cmap.get(ord(ch)) + if gname is None: + # No glyph for this codepoint: advance by the monospace default so + # spacing stays intact even if the mark is missing. + x += (MM_ADVANCE / upm) * font_size + letter_spacing + continue + glyph_set[gname].draw(TransformPen(pen, (scale, 0, 0, -scale, x, baseline))) + x += hmtx[gname][0] * scale + letter_spacing + return pen.getCommands(), x + + def font_face_rule(font_path: str, family: str, weight: int) -> str: """Return the bare ``@font-face { ... }`` rule with the font base64-embedded. diff --git a/llama.cpp/projects/logo/srcmorph-outlined.svg b/llama.cpp/projects/logo/srcmorph-outlined.svg new file mode 100644 index 0000000..a8d3fc2 --- /dev/null +++ b/llama.cpp/projects/logo/srcmorph-outlined.svg @@ -0,0 +1,15 @@ + + + srcmorph cover + Wordmark with a morphing (blurred, smearing) m in "morph". + + + + + + + + + +