#!/usr/bin/perl -w

# Read raw font data from atari rom images, plus a few hand-drawn
# "text bitmaps" from __DATA__.

# Write 3 bitmap font "txt" files in the format txt2psf expects, then
# runs txt2psf on them. Results in 3 fonts:

# fauxtari-8.psf - 8x8 native size
# fauxtari-16.psf - 16x16 scaled up
# fauxtari-24.psf - 24x24 scaled up

# The fiddly bits of this are getting the Unicode mappings correct.

# ROM dumps are mapped to Atari address space at $C000, the regular
# charset starts at $E000, so it's at offset $2000 (8192) in the
# image. The XL international set is at $CC00, or offset $0C00 (3072).
# In the Arabic ROM, the Arabic font takes the place of the standard
# charset. All the charsets are 1K in size.

# Arabic ROM, plus some info about it and a mention of the Hebrew ROM:
# https://www.savetz.com/vintagecomputers/arabic65xe/

use bytes;

$fontname = "fauxtari";

sub byte2line {
	my $t = shift;
	$t = sprintf("%08b", $t);
	$t =~ y/0/-/;
	$t =~ y/1/#/;
	return $t;
}

sub scale_line {
	my $line = shift;
	my $scale = shift;
	my $one = '#' x $scale;
	my $zero = '-' x $scale;

	$line =~ s/#/$one/g;
	$line =~ s/-/$zero/g;
	return ($line x $scale);
}

sub chr2output {
	my $codepoint = shift;
	my $bytes = shift;
	my $scale = shift || 1;
	my $unicode = "";

	if(!ref $codepoint) {
		$codepoint = [ $codepoint ];
	}

	$unicode .= sprintf("[%04x];", $_) for @$codepoint;

	my $result = sprintf("%%\nUnicode: %s\nBitmap: \\\n", $unicode);
	for(0..7) {
		my $byte = $bytes->[$_];
		my $line = byte2line($byte);
		$result .= scale_line($line, $scale);
		$result .= " \\" unless $_ == 7;
		$result .= "\n";
	}
	return $result;
}

sub internal2byte {
	my $t = shift;
	$t =~ y/-/0/;
	$t =~ y/#/1/;
	return pack("B*", $t);
}

sub psf2txt_header {
	my $charcount = shift;
	my $scale = shift;
	my $w = 8 * $scale;
	my $h = 8 * $scale;
	return <<EOF;
%PSF2
Version: 0
Flags: 1
Length: $charcount
Width: $w
Height: $h
EOF
}

sub read_rom {
	my $data;
	my $filename = shift;
	my $offset = shift;
	my $charcount = shift;
	my $len = $charcount * 8;
	open my $fh, '<', $filename;
	read($fh, $data, 16384);
	close $fh;
	return substr($data, $offset, $len);
}

# position in the map (array index) is the raw glyph number, in
# the order we read the font data.
# value is the Unicode codepoint. if there are multiple codepoints
# for the glyph, make the value an array ref (see 0x1B below, the
# Atari Escape glyph is both 0x0118 aka LATIN CAPITAL LETTER E WITH OGONEK,
# and 0x241b aka SYMBOL FOR ESCAPE).
sub setup_map {
	our @map = (
			0x2665, # 0x00
			0x2523, # 0x01
			0x2503, # 0x02
			0x251b, # 0x03
			0x252b, # 0x04
			0x2513, # 0x05
			0x2571, # 0x06
			0x2572, # 0x07
			0x25e2, # 0x08
			0x2597, # 0x09
			0x25e3, # 0x0a
			0x259d, # 0x0b
			0x2598, # 0x0c
			0x2594, # 0x0d
			0x2581, # 0x0e
			0x2596, # 0x0f
			0x2663, # 0x10
			0x250f, # 0x11
			0x2501, # 0x12
			0x254b, # 0x13
			0x25cf, # 0x14
			0x2584, # 0x15
			0x258e, # 0x16
			0x2533, # 0x17
			0x253b, # 0x18
			0x258c, # 0x19
			0x2517, # 0x1a
			[ 0x0118, 0x241b ], # 0x1b
			0x2191, # 0x1c
			0x2193, # 0x1d
			0x2190, # 0x1e
			0x2192, # 0x1f
			[ 0x0020, 0xa0 ], # 0x20 (plus &nbsp;)
			0x0021, # 0x21
			0x0022, # 0x22
			0x0023, # 0x23
			0x0024, # 0x24
			0x0025, # 0x25
			0x0026, # 0x26
			0x0027, # 0x27
			0x0028, # 0x28
			0x0029, # 0x29
			0x002a, # 0x2a
			0x002b, # 0x2b
			[ 0x002c, 0x00b8 ], # 0x2c (comma and cedilla)
			[ 0x002d, 0x00ad, 0x2013, 0x2014 ], # 0x2d (plus soft hyphen, en, em)
			0x002e, # 0x2e
			0x002f, # 0x2f
			0x0030, # 0x30
			0x0031, # 0x31
			0x0032, # 0x32
			0x0033, # 0x33
			0x0034, # 0x34
			0x0035, # 0x35
			0x0036, # 0x36
			0x0037, # 0x37
			0x0038, # 0x38
			0x0039, # 0x39
			0x003a, # 0x3a
			0x003b, # 0x3b
			0x003c, # 0x3c
			0x003d, # 0x3d
			0x003e, # 0x3e
			0x003f, # 0x3f
			0x0040, # 0x40
			0x0041, # 0x41
			0x0042, # 0x42
			0x0043, # 0x43
			0x0044, # 0x44
			0x0045, # 0x45
			0x0046, # 0x46
			0x0047, # 0x47
			0x0048, # 0x48
			0x0049, # 0x49
			0x004a, # 0x4a
			0x004b, # 0x4b
			0x004c, # 0x4c
			0x004d, # 0x4d
			0x004e, # 0x4e
			0x004f, # 0x4f
			0x0050, # 0x50
			0x0051, # 0x51
			0x0052, # 0x52
			0x0053, # 0x53
			0x0054, # 0x54
			0x0055, # 0x55
			0x0056, # 0x56
			0x0057, # 0x57
			0x0058, # 0x58
			0x0059, # 0x59
			0x005a, # 0x5a
			0x005b, # 0x5b
			0x005c, # 0x5c
			0x005d, # 0x5d
			0x005e, # 0x5e
			0x005f, # 0x5f
			0x25c6, # 0x60
			0x0061, # 0x61
			0x0062, # 0x62
			0x0063, # 0x63
			0x0064, # 0x64
			0x0065, # 0x65
			0x0066, # 0x66
			0x0067, # 0x67
			0x0068, # 0x68
			0x0069, # 0x69
			0x006a, # 0x6a
			0x006b, # 0x6b
			0x006c, # 0x6c
			0x006d, # 0x6d
			0x006e, # 0x6e
			0x006f, # 0x6f
			0x0070, # 0x70
			0x0071, # 0x71
			0x0072, # 0x72
			0x0073, # 0x73
			0x0074, # 0x74
			0x0075, # 0x75
			0x0076, # 0x76
			0x0077, # 0x77
			0x0078, # 0x78
			0x0079, # 0x79
			0x007a, # 0x7a
			0x2660, # 0x7b
			[ 0x007c, 0x0622, 0xfe81, 0xfe82 ], # 0x7c, pipe + arabic ﺁ
			0x21b0, # 0x7d
			0x25c0, # 0x7e
			0x25b6, # 0x7f

# next, 28 "international" characters from the xl rom $cc00 area
# á
			0x00e1, # 0x80
# ù
			0x00f9, # 0x81
# Ñ
			0x00d1, # 0x82
# É
			0x00c9, # 0x83
# ç
			0x00e7, # 0x84
# ô (or is it?)
			0x00f4, # 0x85
# ò
			0x00f2, # 0x86
# ì
			0x00ec, # 0x87
# £
			0x00a3, # 0x88
# ï
			0x00ef, # 0x89
# ü
			0x00fc, # 0x8a
# ä
			0x00e4, # 0x8b
# Ö
			0x00d6, # 0x8c
# ú
			0x00fa, # 0x8d
# ó
			0x00f3, # 0x8e
# ö
			0x00f6, # 0x8f
# Ü
			0x00dc, # 0x90
# å
			0x00e5, # 0x91
# û (?)
			0x00fb, # 0x92
# î
			0x00ee, # 0x93
# é
			0x00e9, # 0x94
# è
			0x00e8, # 0x95
# ñ
			0x00f1, # 0x96
# ê
			0x00ea, # 0x97
# ȧ
			0x0227, # 0x98
# à
			0x00e0, # 0x99
# ¡
			0x00a1, # 0x9a
# Ä
			0x00c4, # 0x9b

# hebrew rom is probably a 3rd-party hack, afaik never released by
# atari, but i'm told the glyphs look good (by someone who reads hebrew),
# so include it here.
			0x05d0, # 0x9c
			0x05d1, # 0x9d
			0x05d2, # 0x9e
			0x05d3, # 0x9f
			0x05d4, # 0xa0
			0x05d5, # 0xa1
			0x05d6, # 0xa2
			0x05d7, # 0xa3
			0x05d8, # 0xa4
			0x05d9, # 0xa5
			0x05da, # 0xa6
			0x05db, # 0xa7
			0x05dc, # 0xa8
			0x05dd, # 0xa9
			0x05de, # 0xaa
			0x05df, # 0xab
			0x05e0, # 0xac
			0x05e1, # 0xad
			0x05e2, # 0xae
			0x05e3, # 0xaf
			0x05e4, # 0xb0
			0x05e5, # 0xb1
			0x05e6, # 0xb2
			0x05e7, # 0xb3
			0x05e8, # 0xb4
			0x05e9, # 0xb5
			0x05ea, # 0xb6

# polish rom. probably a 3rd-party hack, but there are a lot of polish
# atari users out there.
			0x0179, # 0xb7
			0x0105, # 0xb8
			0x017a, # 0xb9
			0x0107, # 0xba
			0x015a, # 0xbb
			0x0119, # 0xbc
# german sharp s, not polish at all:
			0x00df, # 0xbd
			0x0141, # 0xbe
			0x0142, # 0xbf
			0x0143, # 0xc0
			0x0144, # 0xc1
			0x00d3, # 0xc3
# 0xc3 weird-looking v?
# next glyph is e with ogonek, we already have it as esc
			0x015b, # 0xc4
			0x0106, # 0xc5
			0x0104, # 0xc6
			0x017b, # 0xc7
			0x017c, # 0xc8

# the rest are from the arabic xe rom
			0x0660, # eastern arabic numeral 0
			0x0661, # eastern arabic numeral 1
			0x0662, # eastern arabic numeral 2
			0x0663, # eastern arabic numeral 3
			0x0664, # eastern arabic numeral 4
			0x0665, # eastern arabic numeral 5
			0x0666, # eastern arabic numeral 6
			0x0667, # eastern arabic numeral 7
			0x0668, # eastern arabic numeral 8
			0x0669, # eastern arabic numeral 9

# todo: figure out the arabic letter mappings. might need someone who
# actually reads arabic to make sense of them... what i've got is just
# a guess.
			[ 0x0624, 0xfe85, 0xfe86 ], # 0x3c, maybe?

			[ 0x0634, 0xfeb5, 0xfeb6, 0xfeb8 ], # 0x41
			[ 0x0648, 0xfeed, 0xfeee ], # 0x42
			[ 0x0629, 0xfe93, 0xfe94 ], # 0x43
			[ 0x064a, 0xfef1, 0xfef2, 0xfef4 ], # 0x44
			[ 0x062b, 0xfe99, 0xfe9a, 0xfe9c ], # 0x45
			[ 0x0628, 0xfe8f, 0xfe90, 0xfe92 ], # 0x46
			[ 0x0644, 0xfedd, 0xfede, 0xfee0 ], # 0x47
			[ 0x0621, 0xfe80 ], # 0x48
			[ 0x0647, 0xfee9, 0xfeea, 0xfeec ], # 0x49
			[ 0x062a, 0xfe95, 0xfe96, 0xfe98 ], # 0x4a
			[ 0x0646, 0xfee5, 0xfee6, 0xfee8 ], # 0x4b
			[ 0x0645, 0xfee1, 0xfee2, 0xfee4 ], # 0x4c
			[ 0x062c, 0xfe9d, 0xfe9e, 0xfea0 ], # 0x4d
			# xxx don't know what 0x4e is
			[ 0x062e, 0xfea5, 0xfea6, 0xfea8 ], # 0x4f
			[ 0x062d, 0xfea1, 0xfea2, 0xfea4 ], # 0x50
			[ 0x0636, 0xfebd, 0xfebe, 0xfec0 ], # 0x51
			[ 0x0642, 0xfed5, 0xfed6, 0xfed8 ], # 0x52
			[ 0x0633, 0xfeb1, 0xfeb2, 0xfeb4 ], # 0x53
			[ 0x0641, 0xfed1, 0xfed2, 0xfed4 ], # 0x54
			[ 0x0639, 0xfec9, 0xfeca, 0xfecc ], # 0x55
			[ 0x0643, 0xfed9, 0xfeda, 0xfedc ], # 0x56
			[ 0x0635, 0xfeb9, 0xfeba, 0xfebc ], # 0x57
			# xxx don't know what 0x58 is
			[ 0x063a, 0xfecd, 0xfece, 0xfed0 ], # 0x59
			[ 0x0649, 0xfeef, 0xfef0 ], # 0x5a
			[ 0x0632, 0xfeaf, 0xfeb0 ], # 0x60
			0xfeb7, # 0x61
			# xxx 0x62 isn't really both ﺩ and ﺭ but where's the atari's ﺭ at?
			[ 0x062f, 0xfea9, 0xfeaa, 0x0631, 0xfead, 0xfeae ], # 0x62
			[ 0x0630, 0xfeab, 0xfeac ], # 0x63
			0xfef3, # 0x64
			0xfe9b, # 0x65
			0xfe91, # 0x66
			0xfedf, # 0x67
			[ 0x0627, 0xfe8d, 0xfe8e ], # 0x68
			0xfeeb, # 0x69
			0xfe97, # 0x6a
			0xfee7, # 0x6b
			0xfee3, # 0x6c
			0xfe9f, # 0x6d
			[ 0xfef7, 0xf3f8 ], # 0x6e
			0xfea7, # 0x6f
			0xfea3, # 0x70
			0xfebf, # 0x71
			0xfed7, # 0x72
			0xfeb3, # 0x73
			0xfed3, # 0x74
			0xfecb, # 0x75
			0xfedb, # 0x76
			0xfebb, # 0x77
			[ 0x0637, 0xfec1, 0xfec2, 0xfec4, 0xfec3 ], # 0x78
			0xfecf, # 0x79
			[ 0x0638, 0xfec5, 0xfec6, 0xfec8, 0xfec7 ], # 0x7a
			0x061f, # 0x7f
			);
}

### main()
setup_map();

@scale1 = ();
@scale2 = ();
@scale3 = ();

$raw .= read_rom("atarixl.rom", 0x2200, 32);
$raw .= read_rom("atarixl.rom", 0x2000, 32);
$raw .= read_rom("atarixl.rom", 0x2100, 32);
$raw .= read_rom("atarixl.rom", 0x2300, 32);
$raw .= read_rom("atarixl.rom", 0xe00, 26);
$raw .= read_rom("atarixl.rom", 0xf00, 1);
$raw .= read_rom("atarixl.rom", 0xfd8, 1);

$raw .= read_rom("xl_hebrew.rom", 0xf00, 27);

$raw .= read_rom("xl_polish.rom", 0xe00, 6);
$raw .= read_rom("xl_polish.rom", 0xe50, 5);
$raw .= read_rom("xl_polish.rom", 0xe80, 1);
$raw .= read_rom("xl_polish.rom", 0xe98, 1);
$raw .= read_rom("xl_polish.rom", 0xeb0, 3);
$raw .= read_rom("xl_polish.rom", 0xed0, 1);

$raw .= read_rom("xe_arabic.rom", 0x2000+8*15, 10);
$raw .= read_rom("xe_arabic.rom", 0x2000+8*0x3c, 1);
$raw .= read_rom("xe_arabic.rom", 0x2000+8*0x41, 13);
$raw .= read_rom("xe_arabic.rom", 0x2000+8*0x4f, 9);
$raw .= read_rom("xe_arabic.rom", 0x2000+8*0x59, 2);
$raw .= read_rom("xe_arabic.rom", 0x2000+8*0x60, 27);
$raw .= read_rom("xe_arabic.rom", 0x2000+8*0x7f, 1);

$cnt = 0;
while($raw =~ /(.{8})/gc) {
	my @bytes;
	my $got = $1;
	my $chr = $map[$cnt++];
	die "$0: incomplete map" unless defined $chr;
	#warn $got;
	push @bytes, ord(substr($got, $_, 1)) for(0..7);
	#warn $_ for @bytes;
	push @scale1, chr2output($chr, \@bytes, 1);
	push @scale2, chr2output($chr, \@bytes, 2);
	push @scale3, chr2output($chr, \@bytes, 3);
}

while(<DATA>) {
	push @scale1, $_;
	$cnt++ if /^%/;
	if(/^\s*[-#]/) {
		push @scale2, scale_line($_, 2);
		push @scale3, scale_line($_, 3);
	} else {
		push @scale2, $_;
		push @scale3, $_;
	}
}

#warn "$cnt characters\n";
#warn "(padding to 256 characters)\n" unless $cnt >= 256;
#warn "(padding to 512 characters)\n" unless $cnt >= 512;

# 512 glyphs is the max for a PSF font. There can be more
# *codepoints*, because the Unicode directory allows the same
# glyph to represent multiple codepoints (e.g. space and
# non-breaking space).
if($cnt > 512) {
	die "$0: too many glyphs ($cnt > 512)";
}

# The kernel refuses to load a font that isn't exactly
# 256 or 512 glyphs, so we have to pad with junk glyphs.
while($cnt < 512) {
	my $fake = "%\nUnicode: [0000];\nBitmap: ";
	push @scale1, $fake . (("-" x 8) x 8) . "\n";
	push @scale2, $fake . (("-" x 16) x 16) . "\n";
	push @scale3, $fake . (("-" x 24) x 24) . "\n";
	$cnt++;
}

#warn "$cnt characters with padding\n";

# What is dupglyphs.pl for?
# PSF allows the same glyph to represent multiple codepoints (e.g.
# space and NBSP, or hyphen/soft-hyphen/en-dash). We only get 512
# glyphs max for a PSF, so we definitely want to use this.
# BDF on the other hand doesn't allow this. So if the same glyph
# data is to be used for multiple codepoints in BDF, the glyph data
# has to be repeated for each codepoint. Bloats the font, but not
# too much. The BDF is also what gets made into the TTF. I'm pretty
# sure TTF supports multiple codepoints per glyph, but until I
# learn some other way besides bitmapfont2ttf to generate the TTF,
# it also will have dup glyph bloat. On the bright side, dupglyphs.pl
# removes all the padding characters required by the psf font.
sub mkfonts {
	my $px = shift;
	my $scaled_data = shift;
	my $scale = shift;

	open $fh, '>', "$fontname-$px.txt" or die $!;
	print $fh psf2txt_header($cnt, $scale);
	print $fh $_ for(@$scaled_data);
	close $fh;

	system("txt2psf $fontname-$px.txt $fontname-$px.psf");
	system("perl dupglyphs.pl $fontname-$px.txt | perl sorttxtfont.pl | txt2psf | psf2bdf --defchar=0 --iso10646 --fontname=$fontname-$px | perl ./fixbdf.pl $px > $fontname-$px.bdf");
}

mkfonts(8, \@scale1, 1);
mkfonts(16, \@scale2, 2);
mkfonts(24, \@scale3, 3);

exit 0;

__DATA__
%
// dotted-box (no such glyph)
Unicode: [0000];
Bitmap: \
        -------- \
        -##-###- \
        -#------ \
        ------#- \
        -#------ \
        ------#- \
        -###-##- \
        --------
%
// backtick
Unicode: [0060];
Bitmap: \
        -------- \
        --##---- \
        --##---- \
        ---##--- \
        -------- \
        -------- \
        -------- \
        --------
%
// curlies
Unicode: [007b];
Bitmap: \
        ----##-- \
        ---##--- \
        ---##--- \
        --##---- \
        ---##--- \
        ---##--- \
        ----##-- \
        --------
%
Unicode: [007d];
Bitmap: \
        --##---- \
        ---##--- \
        ---##--- \
        ----##-- \
        ---##--- \
        ---##--- \
        --##---- \
        --------
%
// tilde
Unicode: [007e];
Bitmap: \
        -------- \
        -###--## \
        ##-##-## \
        ##--###- \
        -------- \
        -------- \
        -------- \
        --------
%
// euro
Unicode: [20ac];
Bitmap: \
        ---####- \
        --##---- \
        -#####-- \
        --##---- \
        -#####-- \
        --##---- \
        ---####- \
        --------
%
// spanish left-quote
Unicode: [00ab];
Bitmap: \
        -------- \
        -------- \
        -------- \
        -##--##- \
        ##--##-- \
        -##--##- \
        -------- \
        --------
%
// spanish right-quote
Unicode: [00bb];
Bitmap: \
        -------- \
        -------- \
        -------- \
        ##--##-- \
        -##--##- \
        ##--##-- \
        -------- \
        --------
%
// spanish inverted question mark
Unicode: [00bf];
Bitmap: \
        -------- \
        ---##--- \
        -------- \
        ---##--- \
        ----##-- \
        -##--##- \
        --####-- \
        --------
%
// copyright
Unicode: [00a9];
Bitmap: \
        -#####-- \
        #-----#- \
        #--##-#- \
        #-#---#- \
        #--##-#- \
        #-----#- \
        -#####-- \
        --------
%
// registered
Unicode: [00ae];
Bitmap: \
        -#####-- \
        #-----#- \
        #-##--#- \
        #-#-#-#- \
        #-##--#- \
        #-#-#-#- \
        -#####-- \
        --------
%
// degrees
Unicode: [00b0];[00ba];
Bitmap: \
        -------- \
        ---##--- \
        --#--#-- \
        ---##--- \
        -------- \
        -------- \
        -------- \
        --------
%
// cents
Unicode: [00a2];
Bitmap: \
        -------- \
        ---##--- \
        --#####- \
        -##----- \
        -##----- \
        --#####- \
        ---##--- \
        --------
%
// "currency sign"
// FIXME: not bold enough
Unicode: [00a4];
Bitmap: \
        -------- \
        -#----#- \
        --####-- \
        --#--#-- \
        --#--#-- \
        --####-- \
        -#----#- \
        --------
%
// yen
Unicode: [00a5];
Bitmap: \
        -##--##- \
        -##--##- \
        ---##--- \
        -######- \
        ---##--- \
        -######- \
        ---##--- \
        --------
%
// broken bar
Unicode: [00a6];
Bitmap: \
        -------- \
        ---##--- \
        ---##--- \
        -------- \
        ---##--- \
        ---##--- \
        ---##--- \
        --------
%
// section sign
// FIXME: not bold enough
Unicode: [00a7];
Bitmap: \
        ---###-- \
        --#----- \
        ---##--- \
        --#--#-- \
        ---##--- \
        -----#-- \
        --###--- \
        --------
%
// diaresis (cha, cha, cha!)
Unicode: [00a8];
Bitmap: \
        -------- \
        -##--##- \
        -##--##- \
        -------- \
        -------- \
        -------- \
        -------- \
        --------
%
// feminine ordinal (superscript a)
Unicode: [00aa];
Bitmap: \
        -------- \
        --####-- \
        ----###- \
        --##-##- \
        ---####- \
        -------- \
        -------- \
        --------
%
// "not" sign
Unicode: [00ac];
Bitmap: \
        -------- \
        -------- \
        -------- \
        -######- \
        -----##- \
        -------- \
        -------- \
        --------
%
// macron
Unicode: [00af];
Bitmap: \
        -------- \
        -######- \
        -------- \
        -------- \
        -------- \
        -------- \
        -------- \
        --------
%
// plus-minus
Unicode: [00b1];
Bitmap: \
        -------- \
        ---##--- \
        -######- \
        ---##--- \
        -------- \
        -######- \
        -------- \
        --------
%
// superscript 2
// FIXME: not bold enough
Unicode: [00b2];
Bitmap: \
        -------- \
        --##---- \
        -#--#--- \
        ---#---- \
        --#----- \
        -####--- \
        -------- \
        --------
%
// FIXME: not bold enough
// superscript 3
Unicode: [00b3];
Bitmap: \
        -------- \
        --##---- \
        -#--#--- \
        ---#---- \
        -#--#--- \
        --##---- \
        -------- \
        --------
%
// acute
Unicode: [00b4];
Bitmap: \
        -------- \
        ----##-- \
        ---##--- \
        -------- \
        -------- \
        -------- \
        -------- \
        --------
%
// mu
Unicode: [00b5];
Bitmap: \
        -------- \
        -------- \
        -##--##- \
        -##--##- \
        -##--##- \
        --#####- \
        -----##- \
        --------
%
// paragraph
Unicode: [00b6];
Bitmap: \
        -------- \
        --##-##- \
        -###-##- \
        -###-##- \
        --##-##- \
        ---#-##- \
        ---#-##- \
        --------
%
// middle dot
Unicode: [00b7];
Bitmap: \
        -------- \
        -------- \
        -------- \
        ---##--- \
        ---##--- \
        -------- \
        -------- \
        --------
%
// superscript 1
Unicode: [00b9];
Bitmap: \
        -------- \
        ---##--- \
        --###--- \
        ---##--- \
        --####-- \
        -------- \
        -------- \
        --------
// FIXME: MISSING fractions, 00bc/00bd/00bc, ¼ ½ ¾, hard to do in 8x8
%
// A with grave
Unicode: [00c0];
Bitmap: \
        -------- \
        --##---- \
        ---##--- \
        --####-- \
        -##--##- \
        -######- \
        -##--##- \
        --------
%
// A with acute
Unicode: [00c1];
Bitmap: \
        -------- \
        ----##-- \
        ---##--- \
        --####-- \
        -##--##- \
        -######- \
        -##--##- \
        --------
%
// A with circumflex
Unicode: [00c2];
Bitmap: \
        --####-- \
        -#----#- \
        ---##--- \
        --####-- \
        -##--##- \
        -######- \
        -##--##- \
        --------
%
// A with tilde
Unicode: [00c3];
Bitmap: \
        --##-##- \
        -##-##-- \
        ---##--- \
        --####-- \
        -##--##- \
        -######- \
        -##--##- \
        --------
%
// A with ring
Unicode: [00c5];
Bitmap: \
        ---##--- \
        --#--#-- \
        ---##--- \
        --####-- \
        -##--##- \
        -######- \
        -##--##- \
        --------
%
// AE ligature
Unicode: [00c6];
Bitmap: \
        -------- \
        --#####- \
        -####--- \
        ##-##--- \
        #######- \
        ##-##--- \
        ##-####- \
        --------
// FIXME: this is hideous!
%
// C with cedilla
Unicode: [00c7];
Bitmap: \
        -------- \
        --####-- \
        -##--##- \
        -##----- \
        -##--##- \
        --####-- \
        ---##--- \
        --##----
%
// E with circumflex
Unicode: [00ca];
Bitmap: \
        --####-- \
        -#----#- \
        -######- \
        -##----- \
        -#####-- \
        -##----- \
        -######- \
        --------
// FIXME: ugly!
%
// E with umlaut
Unicode: [00cb];
Bitmap: \
        --##-##- \
        -------- \
        -######- \
        -##----- \
        -#####-- \
        -##----- \
        -######- \
        --------
%
// I with grave
Unicode: [00cc];
Bitmap: \
        --##---- \
        ---##--- \
        -######- \
        ---##--- \
        ---##--- \
        ---##--- \
        -######- \
        --------
%
// I with acute
Unicode: [00cd];
Bitmap: \
        ----##-- \
        ---##--- \
        -######- \
        ---##--- \
        ---##--- \
        ---##--- \
        -######- \
        --------
%
// I with circumflex
Unicode: [00ce];
Bitmap: \
        --####-- \
        -#----#- \
        -######- \
        ---##--- \
        ---##--- \
        ---##--- \
        -######- \
        --------
// FIXME: ugly!
%
// I with umlaut
Unicode: [00cf];
Bitmap: \
        --##-##- \
        -------- \
        -######- \
        ---##--- \
        ---##--- \
        ---##--- \
        -######- \
        --------
%
// capital eth
Unicode: [00d0];
Bitmap: \
        -------- \
        -####--- \
        -##-##-- \
        -##--##- \
        ####-##- \
        -##-##-- \
        -####--- \
        --------
%
// O with grave
Unicode: [00d2];
Bitmap: \
        -##----- \
        --####-- \
        -#-#-##- \
        -##--##- \
        -##--##- \
        -##--##- \
        --####-- \
        --------
// FIXME: MISSING Ô Õ
%
// multiplication
Unicode: [00d7];
Bitmap: \
        -------- \
        -##--##- \
        --####-- \
        ---##--- \
        --####-- \
        -##--##- \
        -------- \
        --------
// FIXME: MISSING Ø
%
// U with grave
Unicode: [00d9];
Bitmap: \
        --##---- \
        ---##--- \
        -##--##- \
        -##--##- \
        -##--##- \
        -##--##- \
        -######- \
        --------
%
// U with acute
Unicode: [00da];
Bitmap: \
        ----##-- \
        ---##--- \
        -##--##- \
        -##--##- \
        -##--##- \
        -##--##- \
        -######- \
        --------
// FIXME: MISSING Û
%
// Y with acute
Unicode: [00dd];
Bitmap: \
        ----##-- \
        ---##--- \
        -##--##- \
        -##--##- \
        --####-- \
        ---##--- \
        ---##--- \
        --------
%
// capital thorn
Unicode: [00de];
Bitmap: \
        -------- \
        -##----- \
        -#####-- \
        -##--##- \
        -#####-- \
        -##----- \
        -##----- \
        --------
%
// a with circumflex
Unicode: [00e2];
Bitmap: \
        --####-- \
        -#----#- \
        -------- \
        --####-- \
        ----###- \
        --##-##- \
        ---####- \
        --------
%
// a with tilde
Unicode: [00e3];
Bitmap: \
        --##-##- \
        -##-##-- \
        -------- \
        --####-- \
        ----###- \
        --##-##- \
        ---####-
// FIXME: touches bottom
%
// ae ligature
Unicode: [00e6];
Bitmap: \
        -------- \
        -------- \
        -###-##- \
        ---##-## \
        -######- \
        ##-##--- \
        -######- \
        --------
// FIXME: fugly
%
// e with umlaut
Unicode: [00eb];
Bitmap: \
        -##--##- \
        -------- \
        --####-- \
        -##--##- \
        -######- \
        -##----- \
        --####-- \
        --------
%
// i with acute
Unicode: [00ed];
Bitmap: \
        ----##-- \
        ---##--- \
        -------- \
        --###--- \
        ---##--- \
        ---##--- \
        --####-- \
        --------
%
// lowercase eth
Unicode: [00f0];
Bitmap: \
        -##-#--- \
        --##---- \
        -#-##--- \
        --####-- \
        -##--##- \
        -##--##- \
        --####-- \
        --------
%
// o with tilde
Unicode: [00f5];
Bitmap: \
        --##-##- \
        -##-##-- \
        -------- \
        --####-- \
        -##--##- \
        -##--##- \
        --####-- \
        --------
%
// division
Unicode: [00f7];
Bitmap: \
        -------- \
        ---##--- \
        -------- \
        -######- \
        -------- \
        ---##--- \
        -------- \
        --------
// FIXME: MISSING ø
%
// y with acute
Unicode: [00fd];
Bitmap: \
        ----##-- \
        ---##--- \
        -------- \
        -##--##- \
        -##--##- \
        --#####- \
        ----##-- \
        -####---
%
// lowercase thorn
Unicode: [00fe];
Bitmap: \
        -##----- \
        -##----- \
        -####--- \
        -##-##-- \
        -####--- \
        -##----- \
        -##----- \
        --------
%
// y with umlaut
Unicode: [00ff];
Bitmap: \
        -##--##- \
        -------- \
        -##--##- \
        -##--##- \
        -##--##- \
        --#####- \
        ----##-- \
        -####---
%
// left single curly quote
Unicode: [2018];
Bitmap: \
        -------- \
        --##---- \
        ---##--- \
        ----##-- \
        -------- \
        -------- \
        -------- \
        --------
%
// right single curly quote
Unicode: [2019];
Bitmap: \
        -------- \
        ----##-- \
        ---##--- \
        --##---- \
        -------- \
        -------- \
        -------- \
        --------
%
// left double curly quote
Unicode: [201c];
Bitmap: \
        -------- \
        -##--##- \
        -##--##- \
        --##--## \
        -------- \
        -------- \
        -------- \
        --------
%
// right double curly quote
Unicode: [201d];
Bitmap: \
        -------- \
        -##--##- \
        -##--##- \
        ##--##-- \
        -------- \
        -------- \
        -------- \
        --------
%
// spanish left single quote
Unicode: [2039];
Bitmap: \
        -------- \
        -------- \
        -------- \
        ---##--- \
        --##---- \
        ---##--- \
        -------- \
        --------
%
// spanish right single quote
Unicode: [203a];
Bitmap: \
        -------- \
        -------- \
        -------- \
        ---##--- \
        ----##-- \
        ---##--- \
        -------- \
        --------
%
// replacement character for missing glyphs
Unicode: [fffd];
Bitmap: \
        --####-- \
        -##--##- \
        -#-##-#- \
        -###-##- \
        -######- \
        -###-##- \
        --####-- \
        --------