source: trunk/termtv/utils/makefont.pl@ 20107

Last change on this file since 20107 was 17407, checked in by tbretz, 11 years ago
First version.
  • Property svn:executable set to *
File size: 4.1 KB
Line 
1#!/usr/bin/perl
2use warnings;
3use strict;
4$| = 1;
5
6my ($input, $outimage, $outstats) = @ARGV;
7die "need an input file" unless $input;
8die "need an output image file" unless $outimage;
9die "need an output stats file" unless $outstats;
10
11die "output image file must have extension .png" unless $outimage =~ /\.png$/;
12
13my $skipped = 0;
14
15my %font_map;
16my $font_width;
17my $font_height;
18
19sub parse_char {
20 my ($char, $line) = @_;
21 my @lines = grep { defined and length } split /\n/, $char;
22
23 my $header = shift @lines;
24
25 my $unicode_value;
26
27 if ( $header =~ /^U\+([a-fA-F0-9]{4})$/ ) {
28 $unicode_value = unpack "n", pack "H*", $1;
29 } elsif ( length $header == 1 ) {
30 $unicode_value = ord $header;
31 } elsif ( $header =~ /^"(.)"$/ ) {
32 $unicode_value = ord $1;
33 } elsif ( $header =~ /^'(.)'$/ ) {
34 $unicode_value = ord $1;
35 } elsif ( $header eq "TODO" or $header eq "SKIP" ) {
36 $skipped++;
37 return;
38 } else {
39 die "can't handle a header of \"$header\" (line $line)";
40 }
41
42 my $height = @lines;
43 my $width = length $lines[0];
44
45 length $lines[$_] == $width or die "Non-rectangular character \"$header\" (line $line)"
46 for 0 .. $#lines;
47
48 $font_width = $width unless defined $font_width;
49 $font_height = $height unless defined $font_height;
50
51 die "Character dimensions (${width}x${height}) for \"$header\" do not match font dimensions (${font_width}x${font_height}) (line $line)"
52 if $font_width != $width or $font_height != $height;
53
54 tr/[., ]/0/, tr/[1X@MOSW]/1/ for @lines;
55
56 ($_ ne '1' and $_ ne '0') and die "Bad character value '$_' for \"$header\" (line $line)"
57 for map split(//, $_), @lines;
58
59 $font_map{$unicode_value} = \@lines;
60}
61
62open my $lf, "<", $ARGV[0] or die;
63my $char_data = '';
64my $char_line_no;
65my $line_no = 0;
66while ( <$lf> ) {
67 chomp;
68 s/\s*#.*$//;
69 if ( length ) {
70 $char_line_no = $line_no unless defined $char_line_no;
71 $char_data .= "$_\n";
72 } elsif ( length $char_data ) {
73 parse_char($char_data, $char_line_no);
74 $char_data = '';
75 undef $char_line_no;
76 }
77}
78parse_char($char_data) if length $char_data;
79close $lf;
80
81print STDERR "Characters: parsed ".scalar(keys %font_map).", skipped $skipped\n";
82print STDERR "Font size: ${font_width}x${font_height}\n";
83
84my @codepoints = sort { $a <=> $b } keys %font_map;
85
86my $width = int sqrt int scalar @codepoints;
87$width = 8 if $width < 8;
88
89print STDERR "Building image and stats...\n";
90open my $sf, ">", $outstats or die;
91
92my $this_ch_x = 0;
93my $this_ch_y = 0;
94my $image_data = '';
95my @row_bits = map +("0" x ($width*$font_width)), 1..$font_height;
96my $last_cp = 0;
97my $cp_run = 0;
98sub flush_run {
99 if ( $cp_run ) {
100 print $sf "r$cp_run\n";
101 $cp_run = 0;
102 }
103}
104for my $idx ( 0 .. $#codepoints ) {
105 my $cp = $codepoints[$idx];
106
107 # flush this row to the pbm buffer if neccessary
108 if ( $this_ch_x == $width ) {
109 $this_ch_y++;
110 $this_ch_x = 0;
111 for my $row ( @row_bits ) {
112 $row .= "0" while length($row) % 8 != 0;
113 $image_data .= pack "B*", $row;
114 $row = "0" x ($width*$font_width);
115 }
116 print "image data length: ".length($image_data)."\n";
117 flush_run();
118 print $sf "y\n";
119 }
120
121
122 # add the character to this image row
123 if ( $last_cp + 1 == $cp ) {
124 $cp_run++;
125 $last_cp = $cp;
126 } else {
127 flush_run();
128 print $sf "$cp\n";
129 $last_cp = $cp;
130 }
131
132 for my $row ( 0 .. $font_height-1 ) {
133 substr($row_bits[$row], $this_ch_x*$font_width, $font_width, $font_map{$cp}[$row]);
134 }
135
136 $this_ch_x++;
137}
138
139flush_run();
140
141if ( $this_ch_x ) {
142 # we have put a character on the last line
143 for my $row ( @row_bits ) {
144 $row .= "0" while length($row) % 8 != 0;
145 $image_data .= pack "B*", $row;
146 }
147}
148
149close $sf;
150
151print STDERR "Converting image to png...\n";
152
153open $sf, "|-", "convert", "pbm:-", "png:$outimage" or die;
154print $sf "P4 ".($font_width * $width)." ".(($this_ch_y+1) * $font_height)." ".$image_data;
155close $sf;
156
157print STDERR "Done.\n";
158
Note: See TracBrowser for help on using the repository browser.