[2021-11-09] Making console8x16 Work With mrxvt

mrxvt is my favorite terminal-emulator to use on Lucifer because it is fast and supports multiple tabs. I like to pair it with the bitmapped font console8x16 from Konsole because that font looks good in my opinion while giving me the nostalgia kick of using an OldSkool PC font. Unfortunately, the two do not work well together when it comes to displaying box-drawing characters. Until now.

Motivation

mrxvt is quite fast, especially when paired with a bitmapped font – try repeatedly executing something like time cat /usr/man/man1/xterm.1 in mrxvt (of course,after warming up the file-cache to make it a fair comparison) and then in some other terminal. It does not depend on heavy GUI-toolkits like Gtk+ or Qt and only uses X for rendering content. On old hardware like Lucifer, it provides a snappy UX compared to other terminal-emulators and that is why I prefer it. Sadly it has not been actively developed for many years and lacks some features like proper UTF-8 support, which is a deal-breaker for many folks (though not for me).

I really like the glyphs on console8x16 and it is my favorite bitmapped font to use on older hardware with a lower display-resolution. Lars Doelle, the creator of Konsole, used the old VGA BIOS font as a base (the same as that used by the Linux VGA console or the Linux Framebuffer with the VGA8x16 font) and then extended it beyond code-point 255 to support various characters. It was used in Konsole till at least KDE 3.5.10.

Some glyphs from the console8x16 font.

Sadly it has become quite hard to find it these days as most people have moved on from using bitmapped fonts to using proportional fonts. So I preserved a copy of the source for the font here. Recently however, I was once again able to find a copy of the source preserved in the Git-repository of the Trinity Desktop Environment (KDE 3.5 lives!) here. I was also able to find a copy in the source-archives for kdebase-3.5.10 as the file kdebase-3.5.10/konsole/fonts/console8x16.bdf. (All these copies of the file should have an MD5-checksum of b961b8a1f45973c637a36542db632b29.)

Problem

While console8x16 does provide the box-drawing characters and both Konsole and xterm are able to correctly render them while using console8x16 as a font, mrxvt is not. The reason is that when asked to switch to the VT100 Alternate Character Set (ACS) by a terminal-based application via the ANSI escape-sequence ESC ( 0 in order to render the box-drawing characters and then given the characters corresponding to the lines, mrxvt simply tries to load the glyph at code-point <ASCII-code> - 0x5f for each such character, which is normally reserved for various control-characters. Since console8x16 does not provide glyphs for these code-points, mrxvt is not able to render lines and the display gets messed up. (xterm uses a more sophisticated fallback-mechanism in such cases in order to correctly render lines.)

For example, here is how mrxvt renders the output of the command dialog --msgbox 'Hello World!' 0 0 when using console8x16:

Botched up rendering of a dialog-box.

Here is a small shell-script that lets you check the glyphs from ACS as rendered by your terminal-emulator:

#!/usr/bin/env bash
# Check the rendering of box-drawing characters on a terminal:
#   https://en.wikipedia.org/wiki/Box-drawing_character#Unix,_CP/M,_BBS
for n in $(seq 95 126); do
  x=$(printf "%x" $n)
  y=$(expr $n - 95)
  printf "%03d (0x$x) -> %02d (0x%02x): \x$x -> \x1b(0\x$x\x1b(B\n" $n $y $y
done

When I run this script, this is what I see with mrxvt using the console8x16 font:

Botched up rendering of box-drawing characters.

Solution

Since BDF is a text-based file-format, I was able to edit the source for console8x16 to insert the right glyphs at the code-points expected by mrxvt, so that the latter could correctly render the box-drawing characters. You can find the source for the updated font here. You can compile it to a format that can be used by X by running:

bdftopcf -t -o mconsole8x16.pcf mconsole8x16.bdf && \
  gzip --best mconsole8x16.pcf

Copy it over to a directory that is in the font-path of your X server (do not forget to run mkfontdir on the directory after copying over the font).

I did not bother to populate all the characters in the ACS, so this is what I now see when I run the script above in mrxvt using the modified mconsole8x16 font:

Fixed rendering of box-drawing characters.

However, this limited fix-up is good enough to render the box-drawing characters in most applications. For example, the botched-up dialog-box shown earlier now renders as:

Fixed rendering of the dialog-box.

Now that mrxvt can properly render (a patched) console8x16, I am happily using the dynamic duo once again on Lucifer.

Epilogue

By the way, console8x16 was originally edited using XmBDFEditor by Mark Leisher, which seems to be no longer available. I came to know later that it was replaced by gbdfed, which uses Gtk+ instead of the Motif toolkit used by xmbdfed, and provides more features. Before I stumbled upon gbdfed though, I tried searching for the sources of xmbdfed and was finally able to snag a copy of the xmbdfed-4.7 sources via the Internet Archive Wayback Machine. The sources need to be patched up a bit before they can be compiled on a modern Linux desktop. Once you have that, you can use it explore a BDF font, modify it, create your own glyphs or fonts, etc. (Of course, gbdfed works better on a modern system.) If you simply want to see the glyphs provided by a font, use the standard xfd utility instead.

Update (2021-11-14): Added a few screen-shots to the post to illustrate the problem and the solution. Added a pointer to gbdfed that supersedes xmbdfed.

Other Posts from 2021