#! /usr/bin/perl -w

use POSIX;

if ($#ARGV < 0) {
    print "Usage: bdftobogl font.bdf > font.c\n";
    exit -1;
}

$file = $ARGV[0];

$font = $file;
$font =~ s/\.bdf//;
$font =~ tr/a-zA-Z0-9_/_/cs;

print "/* Generated by bdftobogl on ", substr(`date`, 0, -1), ". */\n";
print "#include \"bogl.h\"\n\n";

open BDF, "<$file" || die;
while (<BDF>) {
    chop;
    $pixel_size = $1 if /^PIXEL_SIZE (\d+)$/;
    $font_ascent = $1 if /^FONT_ASCENT (\d+)$/;
    $font_descent = $1 if /^FONT_DESCENT (\d+)$/;
    $font_name = $1 if /^FONT (.*)$/;
    $default_char = $1 if /^DEFAULT_CHAR (\d+)$/;
    
    last if /^CHARS /;
}

print "/* Font information:\n\n";
print "   name: $font_name\n";
print "   pixel size: $pixel_size\n";
print "   ascent: $font_ascent\n";
print "   descent: $font_descent\n";
print "*/\n\n";

print "/* Font character content data. */\n";
print "static unsigned long ${font}_content[] = {\n";

$pixel_size = $font_ascent + $font_descent;
$ofs = 0;
$maxwidth = 0;
while (<BDF>) {
    chop;
    undef $encoding, undef $width, undef $bbx, undef $bby, undef $bbw, undef $bbh if /^STARTCHAR /;
    $encoding = $1 if /^ENCODING (\d+)/;
    $width = $1 if /^DWIDTH (-?\d+)/;
    ($bbw, $bbh, $bbx, $bby) = ($1, $2, $3, $4) if /^BBX (-?\d+) (-?\d+) (-?\d+) (-?\d+)/;

    if (/^BITMAP$/) {
	next if !defined $encoding;
	$encoding_tab[$encoding] = $ofs;
	$width -= $bbx, $bbx = 0 if $bbx < 0;
	$width[$encoding] = $width;
	$maxwidth = $width if $width > $maxwidth;
	for (my $i = 0; $i < $pixel_size; $i++) {
	    $bm[$i] = 0;
	}
	for (my $i = 0; ; $i++) {
	    $_ = <BDF>;
	    chop;
	    last if /^ENDCHAR$/;
	
	    $value = hex($_);
	    $bm[$pixel_size - $font_descent - $bby - $bbh + $i] = $value << (32 - 4 * length($_) - $bbx);
	}

	printf "\n/* Character %c (0x%02x):\n", $encoding, $encoding;
	print "   bbw=$bbw, bbh=$bbh, bbx=$bbx, bby=$bby, width=$width\n";
	print "   +", ("-" x 32), "+\n";
	for (my $i = 0; $i < $pixel_size; $i++) {
	    print "   |";
	    for ($j = 31; $j >= 0; $j--) {
		print $bm[$i] & (1 << $j) ? "*" : " ";
	    }
	    print "|\n";
	}
	print "   +", ("-" x 32), "+ */\n";

	for (my $i = 0; $i < $pixel_size; $i++) {
	    $ofs++;
	    printf "0x%08x,\n", $bm[$i];
	}
    }
}

print "};\n\n";

#print STDERR "Maximum character width=$maxwidth\n";

print "/* Character->glyph data. */\n";
print "static short ${font}_ofs[256] = {\n";
for (my $i = 0; $i < 256; $i++) {
    my $char = $i;
    my $ofs = $encoding_tab[$i];
    $ofs = $encoding_tab[$default_char], $char = $default_char if !defined $ofs;
    printf "  $ofs,\t/* %c (0x%02x) */\n", $char, $i;
}
print "};\n\n";

print "/* Character width data. */\n";
print "static unsigned char ${font}_width[256] = {\n";
for (my $i = 0; $i < 256; $i++) {
    my $char = $i;
    my $width = $width[$i];
    $width = $width[$default_char], $char = $default_char if !defined $encoding_tab[$i];
    printf "  $width,\t/* %c (0x%02x) */\n", $char, $i;
}
print "};\n\n";

print "/* Exported structure definition. */\n";
print "const struct bogl_font font_${font} = {\n";
print "  \"$font\",\n";
print "  $pixel_size,\n";
print "  ${font}_content,\n";
print "  ${font}_ofs,\n";
print "  ${font}_width,\n";
print "};\n";
