while designing yet another serial interface stack for one of my mcu projects, i came up with sort of a solution to move 8 bit characters with only 7 bits available in a byte (8th bit is used for sync purposes). 7-bit is good enough for the lower 128 char slots so pretty much all english characters work (point of this is configuration of firmware settings over a terminal connection), but there are situations where you want special chars of the extended set. what ive kinda done to support 8-bit chars is to use one of the seldom used escape codes to indicate that the current character is to be ignored and the next character will have 128 added to it to allow access to the special chars. this essentially requires a second byte to store the new char value.
apply this sort of thing to freespace, where an 8 bit char is used. if a character was of a specific value (a special unused character), then this character would be ignored and the next would have a pre-defined value added to it. so if you used the device control 1 character (an unused char from the dot matrix printer era), then the next char would be its value + 256, dc2 may indicate to add 512 to the value of the next char and so on (depending on how many characters you need). internally the game would just see an 8-bit string, only text rendering code need be told what these special characters mean.
as for font files, depending on how many characters are supported, you may need to have multiple font sets for the same logical font. first file would contain chars 0-255, second file would contain chars 256-511 and so on, to correspond to what control character was used before it. kind of hackish, but would allow support of character sets that would otherwise be impossible without unicode.