Skip to content

Instantly share code, notes, and snippets.

@scturtle
Created December 5, 2025 03:34
Show Gist options
  • Select an option

  • Save scturtle/9eb2c1acff7a6b8e413857dc2996e70a to your computer and use it in GitHub Desktop.

Select an option

Save scturtle/9eb2c1acff7a6b8e413857dc2996e70a to your computer and use it in GitHub Desktop.
unifont
import sys
import re
def parse_bdf_and_convert(input_file, output_file):
MAX_CHARS = 65536
font_data = [[0, 0, 0, 0] for _ in range(MAX_CHARS)]
font_wide = [False] * MAX_CHARS
current_char = -1
in_bitmap = False
bitmap_lines = []
for line in open(input_file, 'r', encoding='utf-8', errors='ignore'):
line = line.strip()
if not line:
continue
parts = line.split()
keyword = parts[0]
if keyword == 'ENCODING':
current_char = int(parts[1])
elif keyword == 'DWIDTH':
font_wide[current_char] = (int(parts[1]) >= 16)
elif keyword == 'BITMAP':
in_bitmap = True
elif keyword == 'ENDCHAR':
process_bitmap(current_char, bitmap_lines, font_data)
in_bitmap = False
bitmap_lines = []
elif in_bitmap:
bitmap_lines.append(line)
write_c_file(output_file, font_data, font_wide, MAX_CHARS)
def process_bitmap(char_idx, lines, font_data):
if char_idx >= len(font_data):
return
for i in range(4):
combined_val = 0
for row_offset in range(4):
line_idx = i * 4 + row_offset
if line_idx < len(lines):
hex_str = lines[line_idx]
val = int(hex_str, 16)
shift_amount = row_offset * 16
combined_val |= (val << shift_amount)
font_data[char_idx][i] = combined_val
def write_c_file(filename, font_data, font_wide, max_chars):
with open(filename, 'w') as f:
f.write('#include <stdint.h>\n')
f.write('#include <stdbool.h>\n\n')
f.write(f'static uint64_t unifont_data[{max_chars}][4] = {{\n')
for i in range(max_chars):
d = font_data[i]
f.write(f' {{ 0x{d[0]:016x}, 0x{d[1]:016x}, 0x{d[2]:016x}, 0x{d[3]:016x} }},\n')
f.write('};\n\n')
f.write(f'static bool unifont_wide[{max_chars}] = {{\n')
for i in range(0, max_chars, 16):
chunk = font_wide[i:i+16]
line_str = ", ".join(["1" if x else "0" for x in chunk])
f.write(f' {line_str},\n')
f.write('};\n')
if __name__ == "__main__":
if len(sys.argv) < 2:
print("Usage: python bdf2c.py <input.bdf> [output.c]")
else:
input_bdf = sys.argv[1]
output_c = sys.argv[2] if len(sys.argv) > 2 else "unifont.c"
parse_bdf_and_convert(input_bdf, output_c)
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include "unifont.c"
void print_unifont_char(uint32_t codepoint) {
int width = unifont_wide[codepoint] ? 16 : 8;
printf("+"); for (int i = 0; i < width; i++) printf("--"); printf("+\n");
for (int i = 0; i < 4; i++) {
uint16_t *ptr = (uint16_t *)&unifont_data[codepoint][i];
for (int j = 0; j < 4; j++) {
uint16_t data = ptr[j];
printf("|");
for (int bit = width - 1; bit >= 0; bit--)
printf((data >> bit) & 1 ? "**" : " ");
printf("|\n");
}
}
printf("+"); for (int i = 0; i < width; i++) printf("--"); printf("+\n\n");
}
int main() {
print_unifont_char('A');
print_unifont_char(0x6C38);
print_unifont_char('@');
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment