Skip to content

Instantly share code, notes, and snippets.

@MurphyMc
Created January 8, 2023 06:57
Show Gist options
  • Select an option

  • Save MurphyMc/4da20634587250a4985dfe353dd06b9e to your computer and use it in GitHub Desktop.

Select an option

Save MurphyMc/4da20634587250a4985dfe353dd06b9e to your computer and use it in GitHub Desktop.
rfbLoadConsoleFont() replacement for better Linux PSF console font file support in libvncserver
// rfbLoadConsoleFont()'s documentation says that it loads a Linux console
// font, but this is only kind of true. It's limited to loading 256 glyphs,
// which... okay. It's also limited to fonts which are 8x16, which many are.
// More annoyingly, however, it can't actually load from a PSF font file used
// by Linux console fonts, since it doesn't account for the header. In many
// cases, this means that just skipping the first four bytes would make it
// work (it would have been nice if there were just a parameter to tell it
// to do this, or if there was a version you could give a prepared FILE *).
// This function *does* actually load from a PSF file. It wouldn't be too
// hard to make it support v2, but it currently only supports v1 (however,
// the fonts I tried during testing were all v1). It only supports the
// first 256 glyphs even if there are more, and it ignores the Unicode and
// character mapping stuff (again, I got away with this on the fonts I
// tried since I am only immediately worried about ASCII support). It
// does, however, support fonts of different heights.
// TLDR: This lets you load at least some normal Linux .psf console fonts
// for use with libvncserver if all you care about is ASCII.
bool loadPSF (rfbFontDataPtr fon, char * file)
{
memset(fon, 0, sizeof(*fon));
FILE * f = fopen(file, "rb");
if (!f) return false;
int magic1 = fgetc(f);
int magic2 = fgetc(f);
/*int mode =*/ fgetc(f);
int charsize = fgetc(f);
if (magic1 != 0x36 || magic2 != 0x04)
{
// It's not a PSF1 font
fclose(f);
return false;
}
char * data = malloc(256*charsize + 256*5*4);
int * meta = (int *)(data + 256*charsize);
fon->data = data;
fon->metaData = meta;
fread(data, 256*charsize, 1, f);
for (int i = 0; i < 256; ++i)
{
meta[i*5+0] = i*charsize;
meta[i*5+1] = 8; // PSF1 is always 8 pixels wide
meta[i*5+2] = charsize;
meta[i*5+3] = 0;
meta[i*5+4] = 0;
}
fclose(f);
return true;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment