From dfbe240c3b73e75ef05e3329126fff0a6d28a153 Mon Sep 17 00:00:00 2001 From: Cliff Brake Date: Tue, 18 Aug 2026 14:20:31 -0400 Subject: [PATCH] update logo --- CLAUDE.md | 3 ++ gitplm-logo-square.png | Bin 0 -> 5332 bytes gitplm-logo-square.svg | 7 +++ gitplm-logo.png | Bin 4997 -> 6052 bytes gitplm-logo.svg | 110 ++--------------------------------------- scripts/gen-logo.py | 74 +++++++++++++++++++++++++++ 6 files changed, 89 insertions(+), 105 deletions(-) create mode 100644 gitplm-logo-square.png create mode 100644 gitplm-logo-square.svg create mode 100644 scripts/gen-logo.py diff --git a/CLAUDE.md b/CLAUDE.md index 332a8e3..12b4700 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -143,3 +143,6 @@ Format: `CCC-NNN-VVVV` where N is 3-4 digits, V is always 4 digits. - File search uses `fs.WalkDir` from `./` and does NOT follow symlinks - Hooks use `/bin/sh -c` (Linux/macOS only) - `gocsv` library handles CSV marshal/unmarshal via struct tags +- `scripts/gen-logo.py` regenerates `gitplm-logo.svg` and + `gitplm-logo-square.svg` from Fira Code glyph outlines (fontTools); its + docstring has the `rsvg-convert` commands for the PNG derivatives diff --git a/gitplm-logo-square.png b/gitplm-logo-square.png new file mode 100644 index 0000000000000000000000000000000000000000..c5e634292c446f5d108b0aa09a8d0afbd060762f GIT binary patch literal 5332 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 + + + + + + diff --git a/gitplm-logo.png b/gitplm-logo.png index d76bd7ead27bc83c46c5b7eb9daa180da83745e7..4b1d35baf0c03c8a094bb91b8665f0fd095495f4 100644 GIT binary patch literal 6052 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 diff --git a/gitplm-logo.svg b/gitplm-logo.svg index 3c1c042..7e49a59 100644 --- a/gitplm-logo.svg +++ b/gitplm-logo.svg @@ -1,107 +1,7 @@ - - - - - - - - Git - PLM - - - + + + + + diff --git a/scripts/gen-logo.py b/scripts/gen-logo.py new file mode 100644 index 0000000..fd9dd16 --- /dev/null +++ b/scripts/gen-logo.py @@ -0,0 +1,74 @@ +"""Generate the [gitplm] logo assets at the repo root. + +Renders "[gitplm]" as embedded glyph outlines (no font dependency in the +SVG) using Fira Code Medium, in phosphor green on black like a classic +CRT terminal. + +Usage: + python scripts/gen-logo.py + rsvg-convert -w 400 gitplm-logo.svg -o gitplm-logo.png + rsvg-convert -w 360 -h 360 gitplm-logo-square.svg -o gitplm-logo-square.png + +Requires fontTools and the Fira Code font (path below). +""" +from pathlib import Path + +from fontTools.misc.transform import Transform +from fontTools.pens.boundsPen import BoundsPen +from fontTools.pens.svgPathPen import SVGPathPen +from fontTools.pens.transformPen import TransformPen +from fontTools.ttLib import TTFont + +FONT = "/usr/share/fonts/TTF/FiraCodeNerdFont-Medium.ttf" +TEXT = "[gitplm]" +COLOR = "#33ff33" # phosphor green +BG = "#000000" + +ROOT = Path(__file__).resolve().parent.parent + +font = TTFont(FONT) +cmap = font.getBestCmap() +glyphs = font.getGlyphSet() + +# Build one combined path, y-flipped (font coords -> SVG coords), advancing x. +pen = SVGPathPen(glyphs) +bpen = BoundsPen(glyphs) +x = 0 +for ch in TEXT: + g = glyphs[cmap[ord(ch)]] + t = Transform(1, 0, 0, -1, x, 0) + g.draw(TransformPen(pen, t)) + g.draw(TransformPen(bpen, t)) + x += g.width +path = pen.getCommands() +xmin, ymin, xmax, ymax = bpen.bounds +w, h = xmax - xmin, ymax - ymin + + +def svg(width, height, scale, tx, ty): + return f""" + + + + + + +""" + + +# Wide wordmark, normalized to 100 px tall. +pad = 0.30 * h +s = 100.0 / (h + 2 * pad) +W = round((w + 2 * pad) * s, 2) +(ROOT / "gitplm-logo.svg").write_text( + svg(W, 100, s, (pad - xmin) * s, (pad - ymin) * s) +) +print(f"wrote gitplm-logo.svg {W} x 100") + +# Square logo: 360x360, text ~85% of width, centered. +SQ = 360 +s2 = (SQ * 0.85) / w +tx = (SQ - w * s2) / 2 - xmin * s2 +ty = (SQ - h * s2) / 2 - ymin * s2 +(ROOT / "gitplm-logo-square.svg").write_text(svg(SQ, SQ, s2, tx, ty)) +print("wrote gitplm-logo-square.svg 360x360")