#!/usr/bin/perl
#
# Generate a program-space font definition from a textual representation.
# For speed in representation, each 8-line character is split into
# separate bytes, stripped by the line number.
#
# This outputs Canon format fonts (see fonts.h).
use warnings;
use strict;
use Getopt::Long;
my $font_width = 8;
my $font_height = 12;
my @font_range = 97 .. 111; # a-n
my $font_chars = @font_range;
my $font_type = 'const unsigned';
my $font_name = 'menu_icons';
GetOptions(
"name=s" => \$font_name,
"width=i" => \$font_width,
"height=i" => \$font_height,
) or die "$0: Bad argument\n";
# Round the bitmap size up since we might have a partial byte
my $font_bytes = int(($font_width + 7) / 8);
my $font_bitmap_size = $font_bytes * $font_height;
# Paragraph mode
$/ = "\n\n";
my $index = 0;
my $base = ord( ' ' );
my $offset = 0;
my %cmaps;
while(<>)
{
my ($key,@rows) = split /\n/;
my ($pos) = $key =~ /^(.) =/;
my $bytes = "\n";
for my $line (0..$font_height-1)
{
my $row = $rows[ $line ] || ( ' ' x $font_width );
# Pad with spaces to the width of the font
$row .= ' ' x (64 - length($row));
my $bits = $row;
$bits =~ s/[^ ]/1/g;
$bits =~ s/[ ]/0/g;
# Fix $pos for special chars
$pos = "\\$pos" if $pos eq '\\' or $pos eq '\'';
my @array;
for my $i (1..$font_bytes)
{
my $b = substr($bits, 0, 8);
substr($bits, 0, 8, '');
push @array, sprintf "0x%02x", ord(pack("B*",$b));
}
# Strip trailing spaces for display
$row =~ s/ *$//;
$bytes .= join (", ", @array) . ", // $row\n";
}
$cmaps{$pos} = <<"";
{
// '$pos'
.width = $font_width,
.height = $font_height,
.yoff = 3,
.display_width = $font_width,
.bitmap = { $bytes
},
},
}
print <<EOH;
/** Autogenerated: Do not edit */
#include "font.h"
#include "dryos.h"
/* unused
const canon_font_t ${font_name} = {
.magic = CANON_FONT_MAGIC,
.name = "$font_name",
.height = $font_height,
.charmap_offset = sizeof(canon_font_t), // (uint8_t*) &${font_name}_body - (uint8_t*) &${font_name},
.charmap_size = sizeof(((canon_font_body_t*)0)->charmap),
.bitmap_size = sizeof(((canon_font_body_t*)0)->bitmaps),
};
*/
const canon_font_body_t
${font_name}_body __attribute__((used)) =
{
EOH
# Print the present map
print "\t.charmap = {\n";
for my $c (@font_range)
{
my $char = chr($c);
$char = "\\$char" if $char =~ /['\\]/; # Quote the quote!
print "\t\t'$char',\n";
}
print "\t},\n";
# Print the offset map
print "\t.offsets = {\n";
for my $c (@font_range)
{
my $char = chr($c);
$char = "\\$char" if $char =~ /['\\]/; # Quote the quote!
my $font = $cmaps{chr($c)}
or print "\t\t0x0, // '$char' not present\n"
and next;
print "\t\t('$char' - 97) * sizeof(((canon_font_body_t*)0)->bitmaps[0]),\n";
}
print "\t},\n";
# Now print each of the characters
print "\t.bitmaps = {\n";
for my $c (@font_range)
{
my $char = chr($c);
my $font = $cmaps{chr($c)} || <<"";
{ // '$char' not present
.width = 0,
},
print $font;
}
print <<"";
},
};
__END__