https://bitbucket.org/hudson/magic-lantern
Raw File
Tip revision: 5e164a63a53ac66522e2ca02d01678b0d67d07bd authored by Trammell Hudson on 24 March 2011, 13:29:27 UTC
Allow enable-liveview to be toggled on and off
Tip revision: 5e164a6
mkfont
#!/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 <<EOH;
/** Autogenerated: Do not edit */
#include "font.h"

typedef struct {
	uint32_t charmap[$font_chars];
	uint32_t offsets[$font_chars];
	struct {
		uint16_t width;
		uint16_t height;
		uint16_t display_width;
		uint16_t xoff;
		uint16_t yoff;
		uint8_t bitmap[$font_bitmap_size];
	} bitmaps[$font_chars];
} ${font_name}_body_t;

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(((${font_name}_body_t*)0)->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__
back to top