#!/usr/bin/perl use warnings; use strict; my %bitno = (0 => 0); for (0 .. 31) { $bitno{1 << $_} = $_; } my $last_ch = -1; open U, '<', 'unifont.hex' or open U, '<', '/usr/share/unifont/unifont.hex' or die $!; open O, '>', 'unifont.pixelfont' or die $!; while () { my ($ch, $hex) = /^([[:xdigit:]]+):([[:xdigit:]]+)$/; if (!defined $ch) { print "Bad line: $_"; next; } $ch = hex($ch); if ($ch == 256) { close O; open O, '<', 'unifont.pixelfont' or die $!; open P, '>', 'preload_font.h' or die $!; print P "static const unsigned char fontdata_preloaded[] = {"; my $c = 0; while () { for (split //, $_) { if ($c++ % 8 == 0) { print P "\n "; } printf P "% 4d,", ord $_; } } print P "\n};\n"; close P; close O; open O, '>', 'unifont.pixelfont' or die $!; } while (++$last_ch < $ch) { # print "Missing entry for ".($last_ch - 1 )."\n"; print O pack 'C', 0x00; } # $len is 0, 2 or 4 my $len = length($hex) / 16; my $packcode; if ($len == 4) { $packcode = 'n'; } elsif ($len == 2) { $packcode = 'C'; } elsif ($len == 0) { $packcode = ''; } else { die "No handling for len = $len\n"; } my $data = ''; my $start; my $n = 0; my $pixels_set = 0; my $width = $len * 4; if ($len) { my @data = (); for (0 .. 15) { my $c = substr($hex, (15 - $_) * $len, $len); my $row = hex($c); $pixels_set |= $row; if (!defined $start) { # Skip blank rows at the bottom. next unless $row; $start = $_; } $n = $_ if $row; push @data, $row; # my $b = sprintf $fmt, $row; # $b =~ y/01/ @/; # print "\t$b\n"; } my $left_gap = 0; my $lsb_used = $pixels_set & -$pixels_set; my $msb_used = 1 << ($len * 4 - 1); while ($msb_used > $pixels_set) { $msb_used >>= 1; ++$left_gap; } $data = join '', map {pack($packcode, $_ << $left_gap)} @data; my $right_gap = $bitno{$lsb_used} + $left_gap; $right_gap = 0 if ($left_gap == 16); $width -= $right_gap; } else { $width -= 2; } if (!defined $start) { # No set pixels. print O pack 'C', ($len * 4 - 4); die "not really empty!" unless $hex =~ /^0*$/; } else { die "really empty!" if $hex =~ /^0*$/; $n = $n + 1 - $start; print O pack 'C', (($len / 2) << 6) | $width; print O pack 'C', ($start << 4) | ($n - 1); die "too little data (".length($data)." < ".$n."*".($len/2).")" if length($data) < $n * $len/2; print O substr($data, 0, $n * $len / 2); } } close O or die $!;