Files
2026-10-28 09:17:40 -06:00

76 lines
3.5 KiB
Python

"""Draw the CoreDesktop wordmark in the construction of the Federated wordmark.
Measured from Federated's logo.png (775x129): every glyph sits in a 58x57 box
starting at y=55, strokes are 13px, outer corners ~16px radius. Glyphs here are
centerline paths stroked at 13px with 9.5px arcs (16px outside, ~3px inside).
"""
import sys
S = 13 # stroke
H = S / 2 # half stroke: centerline inset
R = 9.5 # centerline corner radius
W, TOP = 58, 55 # glyph box width, top y (box height 57)
ADV = W + 16 # advance: box + gap
L, RT = H, W - H # left / right centerlines
T, B = H, 57 - H # top / bottom centerlines
M = 29 # middle bar centerline (e, s, k)
def a(x, y, sweep=1):
return f"A{R} {R} 0 0 {sweep} {x:g} {y:g}"
GLYPHS = {
# e: closed upper bowl down to the middle bar, open lower right
"e": f"M47 {B} H{L+R} {a(L, B-R)} V{T+R} {a(L+R, T)} H{RT-R} {a(RT, T+R)} V{M-R} {a(RT-R, M)} H{L}",
# c: e without the bar
"c": f"M51 {T} H{L+R} {a(L, T+R, 0)} V{B-R} {a(L+R, B, 0)} H51",
# o: a closed rounded box
"o": f"M{L+R} {T} H{RT-R} {a(RT, T+R)} V{B-R} {a(RT-R, B)} H{L+R} {a(L, B-R)} V{T+R} {a(L+R, T)} Z",
# r: full stem, top arc, short hook on the right
"r": f"M{L} 57 V{T+R} {a(L+R, T)} H{RT-R} {a(RT, T+R)} V27",
# d: lower bowl with a full-height stem on the right (bowl top at y=12)
"d": f"M{RT} 0 V{B-R} {a(RT-R, B)} H{L+R} {a(L, B-R)} V{12+H+R} {a(L+R, 12+H)} H{RT}",
# p: d turned around: upper bowl, full-height stem on the left
"p": f"M{L} 57 V{T+R} {a(L+R, T)} H{RT-R} {a(RT, T+R)} V{45-H-R} {a(RT-R, 45-H)} H{L}",
# s: top bar, upper left, middle bar, lower right, bottom bar
"s": f"M52 {T} H{L+R} {a(L, T+R, 0)} V{M-R} {a(L+R, M, 0)} H{RT-R} {a(RT, M+R)} V{B-R} {a(RT-R, B)} H6",
# k: full stem, two diagonal arms meeting it at the middle. The arms run
# past the box and are clipped to it (see CLIPPED), so their ends are flat.
"k": f"M{L} 0 V57 M{L} 28.5 L62 -9 M{L} 28.5 L62 66",
# t: offset stem, crossbar near the top, bottom bar hooking up on the right
"t": f"M17 0 V{B-R} {a(17+R, B, 0)} H{RT-R} M{RT} 34 V{B-R} {a(RT-R, B)} M0 16 H{W}",
}
STAR = ("M350 616 c-26 -126 -109 -201 -252 -231 -19 -3 -28 -12 -28 -24 0 -14 10 -20 45 -24 "
"118 -17 219 -119 240 -245 5 -31 11 -42 25 -42 13 0 19 11 24 48 8 58 55 142 99 176 "
"47 36 117 66 155 66 25 0 32 4 32 19 0 15 -11 22 -50 30 -73 16 -122 44 -168 96 "
"-40 46 -72 117 -72 162 0 16 -6 23 -19 23 -16 0 -22 -11 -31 -54z")
# glyphs whose strokes are clipped to the glyph box
CLIPPED = {"k"}
def svg(word, star_fill, ink, x0=75):
paths = []
for i, ch in enumerate(word):
clip = ' clip-path="url(#glyph-box)"' if ch in CLIPPED else ""
paths.append(f'<path transform="translate({x0 + i*ADV} {TOP})"{clip} d="{GLYPHS[ch]}"/>')
width = x0 + len(word) * ADV - 16
return f'''<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 {width} 129" width="{width}" height="129" role="img" aria-label="CoreDesktop">
<title>CoreDesktop</title>
<defs><clipPath id="glyph-box"><rect width="{W}" height="57"/></clipPath></defs>
<path transform="translate(0 80) scale(.1 -.1)" fill="{star_fill}" d="{STAR}"/>
<g fill="none" stroke="{ink}" stroke-width="{S}" stroke-linejoin="round">
{chr(10).join(" " + p for p in paths).strip()}
</g>
</svg>
'''
if __name__ == "__main__":
# python3 tools/make-logo.py static/images/coredesktop-logo.svg
out = sys.argv[1]
open(out, "w").write(svg("coredesktop", "#ff3daf", "#ffffff"))