Refactor BeRTOS to be in his own directory.
[bertos.git] / bertos / fonts / convbdf
diff --git a/bertos/fonts/convbdf b/bertos/fonts/convbdf
new file mode 100755 (executable)
index 0000000..61307cd
--- /dev/null
@@ -0,0 +1,209 @@
+#! /usr/bin/perl -w
+#
+# Convert BDF files to nano-X font files
+# modified by G Haerr from bdftobogl for 16 bit MWIMAGEBITS
+# modified on 2/10/00 by K Harris to accept any size input character
+# modified on 3/26/00 by G Haerr added ascent field, fixed $IMAGE_BITS
+# modified on 2/15/06 by <bernie@develer.com> for DevLib.
+# originally from BOGL - Ben's Own Graphics Library <pfaffben@debian.org>.
+#
+
+use POSIX;
+
+if ($#ARGV < 0) {
+       print "Usage: convbdf font.bdf > font.c\n";
+       exit -1;
+}
+
+$LAST_CHAR = 0xff;
+$IMAGE_BITS = 8;
+$IMAGE_NIBBLES = $IMAGE_BITS/4;
+$IMAGE_MASK = 0xff;
+$IMAGE_VERTICAL = 1;
+
+$file = $ARGV[0];
+
+$font = $file;
+$font =~ s#.*/##; # remove path name
+$font =~ s/\.bdf//;
+$font =~ tr/a-zA-Z0-9_/_/cs;
+
+print "/* Generated by convbdf on ", substr(`date`, 0, -1), ". */\n";
+print "#include <gfx/font.h>\n\n";
+
+open BDF, "<$file" || die;
+while (<BDF>) {
+       chop;
+       $pixel_size = $1 if /^PIXEL_SIZE (\d+)$/;
+       $font_ascent = $1 if /^FONT_ASCENT (\d+)$/;
+       $font_descent = $1 if /^FONT_DESCENT (\d+)$/;
+       $font_name = $1 if /^FONT (.*)$/;
+       $default_char = $1 if /^DEFAULT_CHAR (\d+)$/;
+
+       last if /^CHARS /;
+}
+
+print "/* Font information:\n\n";
+print "   name: $font_name\n";
+print "   pixel size: $pixel_size\n";
+print "   ascent: $font_ascent\n";
+print "   descent: $font_descent\n";
+print "*/\n\n";
+
+print "/* Font character bitmap data. */\n";
+print "static const PROGMEM uint8_t font_${font}_glyphs[] = {\n";
+
+$ch_height = $font_ascent + $font_descent;
+$ofs = 0;
+$maxwidth = 0;
+$proportional = 0;
+$firstchar = -1;
+while (<BDF>) {
+       chop;
+       undef $encoding, undef $width, undef $bbx, undef $bby, undef $bbw, undef $bbh if /^STARTCHAR /;
+       $encoding = $1 if /^ENCODING (\d+)/;
+       last if defined $encoding && $encoding > $LAST_CHAR;
+       $width = $1 if /^DWIDTH (-?\d+)/;
+       ($bbw, $bbh, $bbx, $bby) = ($1, $2, $3, $4) if /^BBX (-?\d+) (-?\d+) (-?\d+) (-?\d+)/;
+
+       if (/^BITMAP$/) {
+               next if !defined $encoding;
+               $firstchar = $encoding if $firstchar < 0;
+               $encoding_tab[$encoding] = $ofs;
+               $width -= $bbx, $bbx = 0 if $bbx < 0;
+               $width[$encoding] = $width;
+               $maxwidth != 0 and $width != $maxwidth and $proportional = 1;
+               $maxwidth = $width if $width > $maxwidth;
+               $ch_words  = int (($width+$IMAGE_BITS-1)/$IMAGE_BITS);
+               $ch_bits   = $ch_words*$IMAGE_BITS;
+               for (my $i = 0; $i < $ch_height; $i++) {
+                       for (my $k = 0; $k < $ch_words; $k++) {
+                               $bm[$i][$k] = 0;
+                       }
+               }
+               for (my $i = 0; ; $i++) {
+                       $_ = <BDF>;
+                       chop;
+                       last if /^ENDCHAR$/;
+
+                       @hexnibbles = split //,$_;
+                       for (my $k=0; $k<$ch_words; $k++) {
+                               $ndx = $k*$IMAGE_NIBBLES;
+                               $padnibbles = @hexnibbles - $ndx;
+                               # if bbx pushes bits into next word
+                               # and no more bits from bdf file
+                               last if $padnibbles <= 0;
+                               $padnibbles = 0 if $padnibbles >= $IMAGE_NIBBLES;
+                               $value = hex join '',@hexnibbles[$ndx..($ndx+$IMAGE_NIBBLES-1-$padnibbles)];
+                               $value = $value << ($padnibbles*$IMAGE_NIBBLES);        
+                               $bm[$ch_height - $font_descent - $bby - $bbh + $i][$k] |= 
+                                       $value >> ($bbx);       
+                               if ($bbx) {     # handle overflow into next image_word
+                                       $bm[$ch_height - $font_descent - $bby - $bbh + $i][$k+1] =
+                                               ($value << ($IMAGE_BITS - $bbx)) & $IMAGE_MASK; 
+                               }
+                       }
+               }
+
+               # GLYPH PREVIEW
+###            printf "\n/* Character %c (0x%02x): ", $encoding, $encoding;
+               printf "\n/* Character (0x%02x): ", $encoding;
+               print "bbw=$bbw, bbh=$bbh, bbx=$bbx, bby=$bby, width=$width */\n";
+       
+               # GLYPH DATA
+               if ($IMAGE_VERTICAL) {
+                       my $bitstring = "";
+                       for (my $k = 0; $k < int(($ch_height + $IMAGE_BITS - 1) / $IMAGE_BITS); $k++) {
+                               for (my $x = 0; $x < $width; $x++) {
+                                       my $v = 0;
+                                       for (my $y = 0; $y < $IMAGE_BITS && ($y + $k * $IMAGE_BITS < $ch_height); ++$y) {
+                                               my $bit = ($bm[$k * $IMAGE_BITS + $y][int($x / $IMAGE_BITS)] & (1 << ($IMAGE_BITS - ($x % $IMAGE_BITS) - 1))) ? 1 : 0;
+                                               $bitstring .= $bit ? '*' : ' ';
+                                               $v |= $bit << $y;
+                                       }
+                                       $ofs++;
+                                       printf "0x%02x, ", $v;
+                               }
+                               # Preview
+                               printf "/* $bitstring */\n";
+                       }
+                       
+               }
+               else { # IMAGE_HORIZONTAL
+
+                       # Preview
+                       print "   +", ("-" x $ch_bits), "+\n";
+                       for (my $i = 0; $i < $ch_height; $i++) {
+                               print "   |";
+                               for (my $k = 0; $k < $ch_words; $k++) {
+                                       for (my $j = $IMAGE_BITS - 1; $j >= 0; $j--) {
+                                               print $bm[$i][$k] & (1 << $j) ? "*" : " ";
+                                       }
+                               }
+                               print "|\n";
+                       }
+                       print "   +", ("-" x $ch_bits), "+ */\n";
+
+                       for (my $i = 0; $i < $ch_height; $i++) {
+                               for (my $k=0; $k<$ch_words; $k++) {
+                                       $ofs++;
+                                       printf "0x%02x, ", $bm[$i][$k];
+                               }
+                               printf "\n";
+                       }
+               }
+   }
+}
+
+print "};\n\n";
+
+#print STDERR "Maximum character width=$maxwidth\n";
+
+if ($proportional) {
+       print "/* Character->glyph data. */\n";
+       print "static const PROGMEM uint16_t ${font}_offset[] = {\n";
+       for (my $i = $firstchar; $i <= $LAST_CHAR; $i++) {
+               my $char = $i;
+               my $ofs = $encoding_tab[$i];
+               $ofs = $encoding_tab[$default_char], $char = $default_char if !defined $ofs;
+               ### printf "  $ofs,\t/* %c (0x%02x) */\n", $char, $i;
+               printf "  $ofs,\t/* (0x%02x) */\n", $i;
+       }
+       print "};\n\n";
+
+       print "/* Character width data. */\n";
+       print "static const PROGMEM uint8_t ${font}_width[] = {\n";
+       for (my $i = $firstchar; $i <= $LAST_CHAR; $i++) {
+               my $char = $i;
+               my $width = $width[$i];
+               $width = $width[$default_char], $char = $default_char if !defined $encoding_tab[$i];
+               ### printf "  $width,\t/* %c (0x%02x) */\n", $char, $i;
+               printf "  $width,\t/* (0x%02x) */\n", $i;
+       }
+       print "};\n\n";
+
+       $font_offset = "${font}_offset";
+       $font_width = "${font}_width";
+} else {
+       $font_offset = "NULL";
+       $font_width = "NULL";
+}
+
+$lastchar = $LAST_CHAR;
+#$size = $lastchar - $firstchar + 1;
+
+print <<EOF
+/* Font structure definition. */
+EXTERN_CONST Font font_${font} =
+{
+       /* .glyph  = */ font_${font}_glyphs,
+       /* .name   =    "$font", */
+       /* .width  = */ $maxwidth,
+       /* .height = */ $ch_height,
+       /* .ascent =    $font_ascent, */
+       /* .first  = */ $firstchar,
+       /* .last   = */ $lastchar,
+       /* .offset = */ $font_offset,
+       /* .width  = */ $font_width,
+};
+EOF