#!/usr/bin/perl -w

#
# Simple convertor from bdf to loadable GD font format.
#
# Author: Lincoln Stein <lstein@cshl.edu>, heavily adopted from bdftogd from
# Jan Pazdziora <adelton@fi.muni.cz>
#
# Example of use:
# fstobdf -s fontserverhost:7100 -fn 8x16 | bdftofnt > myfont.fnt
#

use strict;

our $VERSION = '1.00';

my ($width, $height);
my (@data, @left, @bottom);
my ($globalleft, $globaltop);

my ($minchar, $maxchar);

my ($copyright, $fontdef);

my $currentchar;
my $gobitmap = 0;


while (<>)
  {
    chomp;
    s/\r$//;
    next unless $_;
    my ($tag, $value) = split / /, $_, 2;
    die "Font is not fixed width\n"
      if $tag eq 'SPACING' and not $value =~ /[CM]/i;

    $currentchar = $value if $tag eq 'ENCODING';
    $minchar = $currentchar if not defined $minchar
      or ($currentchar < $minchar && $currentchar >= 0);
    $maxchar = $currentchar if not defined $maxchar
      or ($currentchar > $maxchar && $currentchar >= 0);
	
    if ($tag eq 'ENDCHAR')
      {
	next if $currentchar < 0;
	$gobitmap = 0;
	my $bottom = $globaltop - $bottom[$currentchar];
		

	if ($bottom > 0)
	  { $data[$currentchar] = substr $data[$currentchar], 0, length($data[$currentchar]) - $bottom * $width; }
	else
	  { $data[$currentchar] .= '0' x (-$bottom * $width); }
      }

    if ($tag eq 'FONTBOUNDINGBOX')
      {
	my ($tag, $wid, $hei, $left, $top) = split / /;
	if (defined $top)
	  {
	    $globalleft = $left;
	    $globaltop = $top;
	    $height = $hei;
	    $width = $wid;
	  }
      }
    if ($tag eq 'FONT' and not defined $fontdef)
      { $fontdef = $value; }
    if ($tag eq 'COPYRIGHT' and not defined $copyright)
      { $copyright = $value; }
	
    if ($tag eq 'BBX')
      {
	my ($tag, $wid, $hei, $left, $bottom) = split / /;
	if (defined $bottom)
	  {
	    $left[$currentchar] = $left;
	    $bottom[$currentchar] = $bottom;
	  }
      }

    if ($gobitmap)
      {
	my $value = pack 'H*', $_;
	my $bits = unpack 'B*', $value;
	$bits = ('0' x $left[$currentchar]) . $bits;
	$bits .= '0' x ($width - length $bits);
	$bits = substr $bits, 0, $width;
	$data[$currentchar] .= $bits;
      }
	
    if ($tag eq 'BITMAP')
      {
	$gobitmap = 1;
	$data[$currentchar] = '';
      }
  }

$minchar = 0   unless defined $minchar;
$maxchar = 255 unless defined $maxchar;

binmode STDOUT;  # for DOS/Windows systems
my $length = $maxchar-$minchar+1;

warn "length=$length, minchar=$minchar, width=$width, height=$height\n";

print pack ('VVVV',$length,$minchar,$width,$height);  # header

for (my $i = $minchar; $i <= $maxchar; $i++) {
  $data[$i] = '' unless defined $data[$i];
  $data[$i] = '0' x ($width * $height - length $data[$i]) . $data[$i];
  print pack('C*',split '',$data[$i]);
}


__END__

for (my $i = $minchar; $i <= $maxchar; $i++)
	{
	$data[$i] = '' unless defined $data[$i];
	$data[$i] = '0' x ($width * $height - length $data[$i]) . $data[$i];
	
	print FILEC "/* Char $i */\n";
	for my $line (0 .. $height - 1)
		{ print FILEC join ',', split(//, substr($data[$i], $line * $width, $width)), "\n"; }

	print FILEC "\n";

	next;
	
	for my $line (0 .. $height - 1)
		{ print substr($data[$i], $line * $width, $width), "\n"; }
	}

my $capdef = "\U_${filename}_H_";

print FILEC <<"EOF";

};

gdFont ${gdname}Rep = {
	@{[ $maxchar - $minchar + 1]},
	$minchar,
	$width,
	$height,
	${gdname}Data
};

gdFontPtr ${gdname} = &${gdname}Rep;

/* This file has not been truncated. */

EOF


close FILEC;

print FILEH <<"EOF";

#ifndef $capdef
#define $capdef 1

$info

#include "gd.h"

extern gdFontPtr $gdname;

#endif

EOF

1;
