From e6bf88673f31e62050333f98d6bcd407ac34c13d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C5=99emysl=20Eric=20Janouch?= Date: Thu, 22 Sep 2022 18:57:14 +0200 Subject: [PATCH] xP: produce a custom font for IRC formatting Given that the generated file needs a manual adjustment, its small size, and the dependencies involved, it will be checked in to the repository. --- xC.c | 1 + xP/Makefile | 4 +- xP/gen-ircfmt.awk | 89 +++++++++++++++++++++++++++++++++++++++++ xP/public/ircfmt.woff2 | Bin 0 -> 1240 bytes xP/public/xP.css | 11 ++++- 5 files changed, 102 insertions(+), 3 deletions(-) create mode 100644 xP/gen-ircfmt.awk create mode 100644 xP/public/ircfmt.woff2 diff --git a/xC.c b/xC.c index 77d2a08..d01c780 100644 --- a/xC.c +++ b/xC.c @@ -15025,6 +15025,7 @@ process_formatting_escape (const struct pollfd *fd, struct app_context *ctx) case 'u': case '_': CALL_ (ctx->input, insert, "\x1f"); break; case 'v': CALL_ (ctx->input, insert, "\x16"); break; + case 'r': case 'o': CALL_ (ctx->input, insert, "\x0f"); break; default: diff --git a/xP/Makefile b/xP/Makefile index eb0c8f5..34de55a 100644 --- a/xP/Makefile +++ b/xP/Makefile @@ -2,7 +2,7 @@ .SUFFIXES: outputs = xP proto.go public/proto.js public/mithril.js -all: $(outputs) +all: $(outputs) public/ircfmt.woff2 xP: xP.go proto.go go build -o $@ @@ -10,6 +10,8 @@ proto.go: ../xC-gen-proto.awk ../xC-gen-proto-go.awk ../xC-proto awk -f ../xC-gen-proto.awk -f ../xC-gen-proto-go.awk ../xC-proto > $@ public/proto.js: ../xC-gen-proto.awk ../xC-gen-proto-js.awk ../xC-proto awk -f ../xC-gen-proto.awk -f ../xC-gen-proto-js.awk ../xC-proto > $@ +public/ircfmt.woff2: gen-ircfmt.awk + awk -v Output=$@ -f gen-ircfmt.awk public/mithril.js: curl -Lo $@ https://unpkg.com/mithril/mithril.js clean: diff --git a/xP/gen-ircfmt.awk b/xP/gen-ircfmt.awk new file mode 100644 index 0000000..cc9a5a0 --- /dev/null +++ b/xP/gen-ircfmt.awk @@ -0,0 +1,89 @@ +# gen-ircfmt.awk: generate a supplementary font for IRC formatting characters +# +# Copyright (c) 2022, Přemysl Eric Janouch +# 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 "\n" \ + "\n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + "\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) +} diff --git a/xP/public/ircfmt.woff2 b/xP/public/ircfmt.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..d4262bc20928103770b236922b23f78f82bf5169 GIT binary patch literal 1240 zcmXT-cQayOWME)mV7bA-3!=F)7#LVuAYvdsDzoQ)3W?jO+=y)^ZU*t*EekF~9YJeM*uG?s5DDNkqds1n^9y<0o)x8wT#+YLqZ z%ARLL_6yq8T=KaPGF_#$FYN7Bh0OJ{Wj`-&x>je}X0@P6>*2rIi%$q}db)~cIqbd2 zVs=q!;?xbZYmHsfJMJ=^P}n&mM}FSa;^lnYlWmKqSJ`eqX?i>9U&`~Em23V)satcG zb+z1@7OvdCqmVJ?D67fWjXO8h9FjQHc&)BaC_Tz^(aMxbQSy4%UN%4ZQv3bS-cWt- zxTotP|K8oRXj8YI%?uZhINxIz{vM8Mov)&jc>mmbuSab4LF-i4M)2LV$ea*=z3{56 zUHR;ApIK_|PN^I7njIoD*Tv31zB<(_&(QCYc5v|R46#%bvp@0|tAii#+&C=zbUvfN zq{I!P&$oQ~`Q_B}iy;qgxn2yZxwiFqdFTZP8TE$;&B_y{|F>>mJzrD*3qvopwadWiCqlyu`mh`{`bnospI=YStWUW4r(U^K7p_$?5Xn&wf13`LXQN_s#m&x@Om2 zYi|s`{qo($S1<3aH2)-gvwG=~hD?Pu9A&QMUe9!T9#~(wU>v;t&jWpxCzdw6i+6wG zc{FS8*h(my?hTzC9l?9|Z~d5f=uTh*>x`D`zCKr4XR{ar$oa8x z_lx%MCiiAfFOhr8-$_mCQGY=y2Tq>u~AZ<$xP6`8Pe>$fs3x zEV(}P>V+RM-fG{MihTHyl`_AufkW+xVbS6z9yKeEc(`jOOjsDc(&zAphwZ_^&mKI^ zsj06H__gZM^6r}ZA570mJ!ba45#@xn z_O@p@n1-6KcvHCR?xjN~zFvziVKBWJemzTZiguPnOJT0z%5w|8$Ov`6oMmO;CHq9o z%=OCDSMMh~pYCsH^J5Mxo}%SAKj_c}x6K2tFayLHD{`joXc6JeM=aPxpi#>OQuF~pKr}gRKLRt07Yj`Hvj+t literal 0 HcmV?d00001 diff --git a/xP/public/xP.css b/xP/public/xP.css index 87cfec2..1f4dae8 100644 --- a/xP/public/xP.css +++ b/xP/public/xP.css @@ -1,7 +1,14 @@ +@font-face { + src: url('ircfmt.woff2') format('woff2'); + font-family: 'IRC Formatting'; + font-weight: normal; + font-style: normal; +} body { margin: 0; padding: 0; - font-family: sans-serif; + /* Firefox only renders C0 within the textarea, why? */ + font-family: 'IRC Formatting', sans-serif; font-size: clamp(0.5rem, 2vw, 1rem); } .xP { @@ -133,7 +140,7 @@ button:hover:active { font-family: monospace; overflow-y: auto; } -.log, .content { +.log, .content, .completions { /* Note: https://bugs.chromium.org/p/chromium/issues/detail?id=1261435 */ white-space: break-spaces; overflow-wrap: break-word;