#!/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 is now outputs Canon format fonts; see font.h for a definition. # use warnings; use strict; use Getopt::Long; my $font_width = 8; my $font_height = 12; my @font_range = 0x20 .. 0x7E; # only US ASCII is supported my $font_chars = @font_range; my $font_type = 'const unsigned'; my $font_name = 'font'; 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, .display_width = $font_width, .bitmap = { $bytes }, }, } print <charmap), .bitmap_size = sizeof(((${font_name}_body_t*)0)->bitmaps), }; static const ${font_name}_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' - 0x20) * sizeof(((${font_name}_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__