#! /usr/bin/perl -w # # Convert BDF files to incore MWCFONT structure # Copyright (c) 2002 by Greg Haerr # # from The Microwindows Project (http://microwindows.org) # # modified on 09/10/02 by G Haerr # - fixed DWIDTH 0 parsing # - don't limit font size to 0x7e characters # - changed offset data to unsigned long for large fonts # - don't generate width table if fixed-width # - added defaultchar to output # - added bits_size member for loadable fonts # modified on 3/26/00 by G Haerr added ascent field, fixed $IMAGE_BITS # modified on 2/10/00 by K Harris to accept any size input character # modified by G Haerr from bdftobogl for 16 bit MWIMAGEBITS # originally from BOGL - Ben's Own Graphics Library . use POSIX; if ($#ARGV < 0) { print "Usage: convbdf font.bdf > font.c\n"; exit -1; } ##$LAST_CHAR = 0x7e; $IMAGE_BITS = 16; $IMAGE_NIBBLES = $IMAGE_BITS/4; $IMAGE_MASK = 0xffff; $file = $ARGV[0]; $font = $file; $font =~ s/\.bdf//; $font =~ tr/a-zA-Z0-9_/_/cs; print "/* Generated by convbdf on ", substr(`date`, 0, -1), ". */\n"; print "#include \"font.h\"\n\n"; open BDF, "<$file" || die; while () { 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+)$/; ($fbbw, $fbbh, $fbbx, $fbby) = ($1, $2, $3, $4) if /^FONTBOUNDINGBOX (-?\d+) (-?\d+) (-?\d+) (-?\d+)/; last if /^CHARS /; } $font_width = $fbbw - $fbbx; undef $fbbw, undef $fbbh, undef $fbbx, undef $fbby; print "/* Font information:\n\n"; print " name: $font_name\n"; print " pixel size: $pixel_size\n" if defined $pixel_size; print " ascent: $font_ascent\n"; print " descent: $font_descent\n"; print "*/\n\n"; print "/* Font character bitmap data. */\n"; print "static MWIMAGEBITS ${font}_bits[] = {\n"; $ch_height = $font_ascent + $font_descent; $ofs = 0; $maxwidth = 0; $firstchar = -1; $lastchar = -1; while () { 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+)/; $width = $font_width if defined $width && $width <= 0; ($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; $lastchar = $encoding if $lastchar < $encoding; $encoding_tab[$encoding] = $ofs; $width -= $bbx, $bbx = 0 if $bbx < 0; $width[$encoding] = $width; $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++) { $_ = ; chop; last if /^ENDCHAR$/; @hexnibbles = split //,$_; for (my $k=0; $k<$ch_words; $k++) { $ndx = $k*$IMAGE_NIBBLES; $padnibbles = @hexnibbles - $ndx; last if $padnibbles <= 0; # if bbx pushes bits into next word # and no more bits from bdf file $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; } } } ### printf "\n/* Character %c (0x%02x):\n", $encoding, $encoding; printf "\n/* Character (0x%02x):\n", $encoding; print " bbw=$bbw, bbh=$bbh, bbx=$bbx, bby=$bby, width=$width\n"; 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 ($k=0; $k<$ch_words; $k++) { $ofs++; printf "0x%04x, ", $bm[$i][$k]; } printf "\n"; } } } print "};\n\n"; ##print STDERR "Maximum character width=$maxwidth\n"; print "/* Character->glyph mapping. */\n"; print "static unsigned long ${font}_offset[] = {\n"; for (my $i = $firstchar; $i <= $lastchar; $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"; $gen_width_table = 0; for (my $i = $firstchar; $i <= $lastchar; $i++) { my $char = $i; my $width = $width[$i]; $width = $width[$default_char], $char = $default_char if !defined $encoding_tab[$i]; $gen_width_table = 1 if $width != $maxwidth } if ($gen_width_table) { print "/* Character width data. */\n"; print "static unsigned char ${font}_width[] = {\n"; for (my $i = $firstchar; $i <= $lastchar; $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"; } $size = $lastchar - $firstchar + 1; print "/* Exported structure definition. */\n"; print "MWCFONT font_${font} = {\n"; print " \"$font\",\n"; print " $maxwidth,\n"; print " $ch_height,\n"; print " $font_ascent,\n"; print " $firstchar,\n"; print " $size,\n"; print " ${font}_bits,\n"; print " ${font}_offset,\n"; if ($gen_width_table) { print " ${font}_width,\n"; } else { print " 0, /* fixed width*/\n"; } print " $default_char,\n"; print " sizeof(${font}_bits)/sizeof(MWIMAGEBITS),\n"; print "};\n";