diff options
author | P. J. McDermott <pj@pehjota.net> | 2014-07-11 13:50:09 (EDT) |
---|---|---|
committer | P. J. McDermott <pj@pehjota.net> | 2014-07-11 13:50:09 (EDT) |
commit | 54e15c8da9a7c1bf1e291c4a174f17e6d2186d7a (patch) | |
tree | 5bd224a56a22ef30fd708f2af97aacf87f734d81 /bin |
Initial commit
Diffstat (limited to 'bin')
-rwxr-xr-x | bin/bdf2fbcon | 299 |
1 files changed, 299 insertions, 0 deletions
diff --git a/bin/bdf2fbcon b/bin/bdf2fbcon new file mode 100755 index 0000000..364ccab --- /dev/null +++ b/bin/bdf2fbcon @@ -0,0 +1,299 @@ +#!/usr/bin/perl + +=head1 NAME + +bdf2fbcon - Convert Glyph Bitmap Distribution Format fonts to Linux fbcon fonts + +=cut + +use strict; +use warnings; + +use Getopt::Long; + +use constant { + BDF_2_1_SECTION_NONE => 0, + BDF_2_1_SECTION_PROPERTIES => 1, + BDF_2_1_SECTION_CHAR => 2, +}; + +my $VERSION; +$VERSION = '0.1.0'; + +sub main +{ + my %opts; + my %convert_opts; + my $input; + my $output; + + $SIG{'__WARN__'} = \&warning; + + Getopt::Long::Configure("no_ignore_case", "bundling", "gnu_compat", + "no_getopt_compat"); + if (not GetOptions(\%opts, + "o=s", + "s=s", + "h|help", + "V|version", + )) { + usage(*STDERR); + exit(4); + } + + if (exists($opts{'h'})) { + help(*STDOUT); + exit(0); + } + if (exists($opts{'V'})) { + version(*STDOUT); + exit(0); + } + if (exists($opts{'s'})) { + $convert_opts{'w'} = $convert_opts{'h'} = $opts{'s'}; + $convert_opts{'w'} =~ s/x.*//; + $convert_opts{'h'} =~ s/.*x//; + } + + if ($#ARGV lt 0) { + error(4, "No input files\n"); + } + + if (exists($opts{'o'})) { + if ($#ARGV gt 0) { + error(4, "Cannot specify -o with multiple files\n"); + } + convert($ARGV[0], $opts{'o'}, %convert_opts); + } else { + for $input (@ARGV) { + $output = $input; + $output =~ s/\.bdf$/.c/; + convert($input, $output, %convert_opts); + } + } +} + +sub usage +{ + my ($fh) = @_; + + printf($fh "Usage: %s [-o <output>] <input> ...\n", $0); +} + +sub help +{ + my ($fh) = @_; + + usage($fh); + print($fh "Options:\n"); + print($fh " -o <output> Place the output into <output>\n"); + print($fh " -s <w>x<h> Override the font size\n"); + print($fh " -h, --help Display this information\n"); + print($fh " -V, --version Display version information\n"); +} + +sub version +{ + my ($fh) = @_; + + printf($fh "bdf2fbcon %s\n", $VERSION); + print($fh "Copyright (C) 2013, 2014 Patrick \"P. J.\" McDermott\n"); + print($fh "License GPLv3+: GNU GPL version 3 or later " . + "<http://gnu.org/licenses/gpl.html>.\n"); + print($fh "This is free software: you are free to change and " . + "redistribute it.\n"); + print($fh "There is NO WARRANTY, to the extent permitted by law.\n"); +} + +sub warning +{ + my ($fmt, @args) = @_; + + printf(STDERR "bdf2fbcon: Warning: " . $fmt . "\n", @args); +} + +sub error +{ + my ($status, $fmt, @args) = @_; + + printf(STDERR "bdf2fbcon: Error: " . $fmt . "\n", @args); + exit($status); +} + +sub convert +{ + my ($input, $output, %opts) = @_; + my $input_fh; + my $output_fh; + my $line; + + if ($input eq $output and $input ne "-") { + warning("Input and output files are equal"); + } + + if ($input eq "-") { + $input_fh = *STDIN; + } else { + if (not open($input_fh, "<", $input)) { + error(4, "%s: %s", $input, $!); + } + } + if ($output eq "-") { + $output_fh = *STDOUT; + } else { + if (not open($output_fh, ">", $output . "~")) { + error(4, "%s: %s", $output . "~", $!); + } + } + + $line = readline($input_fh); + if ($line =~ m/^STARTFONT 2.[12]$/) { + convert_bdf_2_1($input_fh, $output_fh, %opts); + } else { + error(4, "Unsupported input format"); + } + + if ($input ne "-") { + close($input_fh); + } + if ($output ne "-") { + close($output_fh); + if (not rename($output . "~", $output)) { + error(4, "%s: %s", $output, $!); + } + } +} + +sub convert_bdf_2_1 +{ + my ($input_fh, $output_fh, %opts) = @_; + my $font_w; + my $font_h; + my $section; + my $found_end; + my $line; + my $stmt; + my $arg; + my @argv; + my $font_idx; + my $font_name; + + $font_w = $opts{'w'} if (exists($opts{'w'})); + $font_h = $opts{'h'} if (exists($opts{'h'})); + + $section = BDF_2_1_SECTION_NONE; + $found_end = 0; + while ($line = readline($input_fh)) { + chomp($line); + ($stmt, $arg) = split(/[ \t]+/, $line, 2); + $arg =~ s/^"(.*)"$/$1/ if ($arg); + ($stmt, @argv) = split(/[ \t]+/, $line); + if ($section == BDF_2_1_SECTION_NONE) { + if ($stmt eq 'FONTBOUNDINGBOX') { + $font_w = $argv[0] unless ($font_w); + $font_h = $argv[1] unless ($font_h); + } elsif ($stmt eq 'COMMENT') { + printf($output_fh "/* %s */\n", $arg); + } elsif ($stmt eq 'STARTPROPERTIES') { + print($output_fh + "/* Generated by bdf2fbcon */\n\n"); + print($output_fh "#include <linux/font.h>\n\n"); + $section = BDF_2_1_SECTION_PROPERTIES; + } elsif ($stmt eq 'CHARS') { + # XXX + printf($output_fh "#define FONTDATAMAX %d\n\n", + 0); + printf($output_fh "static const unsigned char" . + " fontdata_%s[FONTDATAMAX] = {\n", + $font_name); + } elsif ($stmt eq 'STARTCHAR') { + $section = BDF_2_1_SECTION_CHAR; + } elsif ($stmt eq 'ENDFONT') { + $found_end = 1; + last; + } + } elsif ($section == BDF_2_1_SECTION_PROPERTIES) { + if ($stmt eq 'FONT_NAME') { + $font_idx = uc($arg); + $font_idx =~ s/[^A-Z0-9_]//g; + $font_name = lc($arg); + $font_name =~ s/[^a-z0-9_]/_/g; + } elsif ($stmt eq 'ENDPROPERTIES') { + $section = BDF_2_1_SECTION_NONE; + } + } elsif ($section == BDF_2_1_SECTION_CHAR) { + if ($stmt eq 'ENDCHAR') { + $section = BDF_2_1_SECTION_NONE; + } + } + } + + warning("Missing end of font") unless ($found_end); + + printf($output_fh "\n};\n\n"); + printf($output_fh "const struct font_desc font_%s = {\n", $font_name); + printf($output_fh "\t.idx\t= %s_IDX,\n", $font_idx); + printf($output_fh "\t.name\t= \"%s\",\n", $font_idx); + printf($output_fh "\t.width\t= %d,\n", $font_w); + printf($output_fh "\t.height\t= %d,\n", $font_h); + printf($output_fh "\t.data\t= fontdata_%s,\n", $font_name); + # XXX + printf($output_fh "\t.pref\t= ???,\n"); + printf($output_fh "};\n"); +} + +main(); + +__END__ + +=head1 SYNOPSIS + +B<bdf2fbcon> +[B<-o> I<output>] [B<-s> I<w>xI<h>] +I<input> ... + +=head1 DESCRIPTION + +B<bdf2fbcon> converts Glyph Bitmap Distribution Format fonts to Linux fbcon +fonts. + +=head1 OPTIONS + +=over 4 + +=item B<-o> I<output> + +Place the output into I<output>. + +=item B<-s> I<w>xI<h> + +Override the font size. + +=item B<-h>, B<--help> + +Display help information. + +=item B<-V>, B<--version> + +Display version information. + +=back + +=head1 COPYRIGHT + +Copyright (C) 2013, 2014 Patrick "P. J." McDermott + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see <http://www.gnu.org/licenses/>. + +=cut |