aboutsummaryrefslogtreecommitdiff
path: root/xP/gen-ircfmt.awk
blob: cc9a5a0874513937657693f31ada07386528ef91 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# gen-ircfmt.awk: generate a supplementary font for IRC formatting characters
#
# Copyright (c) 2022, Přemysl Eric Janouch <p@janouch.name>
# SPDX-License-Identifier: 0BSD
#
# Usage: awk -v Output=static/ircfmt.woff2 -f gen-ircfmt.awk
# Clean up SVG byproducts yourself.

BEGIN {
	if (!Output) {
		print "Error: you must specify the output filename"
		exit 1
	}
}

function glyph(name, code, path,    filename, actions, cmd) {
	filename = Output "." name ".svg"

	# Inkscape still does a terrible job at the stroke-to-path conversion.
	actions = \
		"select-by-id:group;" \
		"selection-ungroup;" \
		"select-clear;" \
		"select-by-id:path;" \
		"object-stroke-to-path;" \
		"select-by-id:clip;" \
		"path-intersection;" \
		"select-all;" \
		"path-combine;" \
		"export-overwrite;" \
		"export-filename:" filename ";" \
		"export-do"

	# These dimensions fit FontForge defaults, and happen to work well.
	cmd = "inkscape --pipe --actions='" actions "'"
	print "<?xml version='1.0' encoding='UTF-8' standalone='no'?>\n" \
		"<svg version='1.1' xmlns='http://www.w3.org/2000/svg'\n" \
		" width='1000' height='1000' viewBox='0 0 1000 1000'>\n" \
		"  <rect x='0' y='0' width='1000' height='1000' />\n" \
		"  <g id='group' transform='translate(200 200) scale(60, 60)'>\n" \
		"    <rect id='clip' x='0' y='0' width='10' height='10' />\n" \
		"    <path id='path' stroke-width='2' fill='none' stroke='#fff'\n" \
		"     d='" path "' />\n" \
		"  </g>\n" \
		"</svg>\n" | cmd
	close(cmd)

	print "Select(0u" code ")\n" \
		"Import('" filename "')" | FontForge
}

BEGIN {
	FontForge = "fontforge -lang=ff -"
	print "New()" | FontForge

	# Designed a 10x10 raster, going for maximum simplicity.
	glyph("B", "02", "m 6,5 c 0,0 2,0 2,2 0,2 -2,2 -2,2 h -3 v -8 h 2.5 c 0,0 2,0 2,2 0,2 -2,2 -2,2 h -2 Z")
	glyph("C", "03", "m 7.6,7 A 3,4 0 0 1 4.25,8.875 3,4 0 0 1 2,5 3,4 0 0 1 4.25,1.125 3,4 0 0 1 7.6,3")
	glyph("I", "1D", "m 3,9 h 4 m 0,-8 h -4 m 2,-1 v 10")
	glyph("M", "11", "m 2,10 v -10 l 3,6 3,-6 v 10")
	glyph("O", "0F", "m 1,9 l 8,-8 M 2,5 a 3,3 0 1 0 6,0 3,3 0 1 0 -6,0 z")
	#glyph("R", "0F", "m 3,10 v -9 h 2 c 0,0 2.5,0 2.5,2.5 0,2.5 -2.5,2.5 -2.5,2.5 h -2 2.5 l 2.5,4.5")
	glyph("S", "1E", "m 7.5,3 c 0,-1 -1,-2 -2.5,-2 -1.5,0 -2.5,1 -2.5,2 0,3 5,1 5,4 0,1 -1,2 -2.5,2 -1.5,0 -2.5,-1 -2.5,-2")
	glyph("U", "1F", "m 2.5,0 v 6.5 c 0,1.5 1,2.5 2.5,2.5 1.5,0 2.5,-1 2.5,-2.5 v -6.5")
	glyph("V", "16", "m 2,-1 3,11 3,-11")

	# In practice, your typical browser font will overshoot its em box,
	# so to make the display more cohesive, we need to do the same.
	# Sadly, sf->use_typo_metrics can't be unset from FontForge script--
	# this is necessary to prevent the caret from jumping upon the first
	# inserted non-formatting character in xP's textarea.
	# https://iamvdo.me/en/blog/css-font-metrics-line-height-and-vertical-align
	print "SelectAll()\n" \
		"Scale(115, 115, 0, 0)\n" \
		"SetOS2Value('WinAscentIsOffset', 1)\n" \
		"SetOS2Value('WinDescentIsOffset', 1)\n" \
		"SetOS2Value('HHeadAscentIsOffset', 1)\n" \
		"SetOS2Value('HHeadDescentIsOffset', 1)\n" \
		"CorrectDirection()\n" \
		"AutoWidth(100)\n" \
		"AutoHint()\n" \
		"AddExtrema()\n" \
		"RoundToInt()\n" \
		"SetFontNames('IRCFormatting-Regular'," \
		" 'IRC Formatting', 'IRC Formatting Regular', 'Regular'," \
		" 'Copyright (c) 2022, Premysl Eric Janouch')\n" \
		"Generate('" Output "')\n" | FontForge
	close(FontForge)
}