#! /usr/bin/perl

#  Makes the image files for a given font in the given sizes
#  (or all sizes, if no specific sizes are given)
#  
#  Usage:  ./makePNG font [sizes]

$font = shift;

if (!$font) {
  print "Usage:  ./makePNG font [sizes]\n";
  exit;
}

sub MakeFontFiles {
  my $font = shift;
  open(FF,">MathJax.ff");
  print FF <<"  EOF;";
    Open("../../OTF/TeX/$font");
    Reencode("compacted",1);
    Reencode("compacted",1);
    Generate("MathJax.pfb","",0x10001);
  EOF;
  close(FF);
  `fontforge -lang=ff -script MathJax.ff 2>/dev/null`;
}

sub RemoveFontBlock {
  open(FF,">MathJax.ff");
  print FF <<"  EOF;";
    Open("MathJax.pfb");
    Select(".notdef"); Clear();
    Select(0,255); Clear();
    Reencode("compacted",1);
    Reencode("compacted",1);
    Generate("MathJax.pfb","",0x10001);
  EOF;
  close(FF);
  `fontforge -lang=ff -script MathJax.ff 2>/dev/null`;
}

sub GetUnicodePoints {
  my @name = (); $more = 0;
  open(AFM,"MathJax.afm");
  while ($line = <AFM>) {
    chomp($line);
    if ($line =~ m/^C (-?\d+) ; .* ; N ([^ ]*) ; /) {
      if ($1 eq "-1") {$more = 1; last}
      my $name = $2; next if $name eq ".notdef" || $name =~ m/uniEFF[DEF]/;
      if ($name =~ m/^uni(E.*)/) {push(@name,"Print(0x$1);")}
        else {push(@name,"Print(UnicodeFromName('$name'));")}
    }
  }
  close(AFM);
  open(FF,">MathJax.ff");
  print FF join("\n",@name,"");
  close(FF);
  my $unicode = `fontforge -lang=ff -script MathJax.ff 2>/dev/null`;
  chomp($unicode);
  return split(/\n/,$unicode);
}

sub MakeTeXfile {
  my $end = shift;
  open(TEX,">MathJax.tex");
  print TEX <<"  EOF;";
    \\documentclass{article}
    \\nonstopmode
    \\usepackage{amsmath,amsfonts,amssymb}
    \\usepackage[active,textmath,displaymath]{preview}
    \\begin{document}
      \\newcount\\CharNo \\CharNo=0
      \\newcount\\MaxChar \\MaxChar=$end
      \\font\\theFont=MathJax
      \\loop\\ifnum\\CharNo<\\MaxChar
        \\(\\hbox{\\theFont\\char\\CharNo}\\)
        \\advance\\CharNo by 1
      \\repeat
    \\end{document}
  EOF;
  close(TEX);
  `latex MathJax`;
}

sub MakePNGfiles {
  my $size = shift;
  $depths = `dvipng --gamma 1.5 -q -bgTransparent -D$size --depth -o PNG/%03d.png MathJax`;
  $depths =~ s/^[^\n]*\n//; $depths =~ s/\s//g; $depths =~ s/^depth=//;
  my @depths = split(/depth=/,$depths);
  while (my $unicode = shift) {$depth{$unicode}{$size} = shift(@depths)}
}

sub RenameFiles {
  my $dir = shift; my $i = 1;
  while ($x = shift) {
    my $old = sprintf("PNG/%03d.png",$i);
    my $new = sprintf("$dir/%04X.png",$x);
#    `convert '$old' '$new'`;  # converts to 8-bit RGBA, which IE6 can use
    rename($old,$new);
    $i++;
  }
}

sub SaveDepths {
  my $dir = shift;
  open(DEPTH,">$dir/depths.pl");
  foreach $unicode (sort {$a <=> $b} (keys %depth)) {
    print DEPTH "\$depth{",sprintf("0x%04X",$unicode),"} = [",
      join(',',map {$depth{$unicode}{$_}} (sort {$a <=> $b} (keys %{$depth{$unicode}}))),
    "];\n";
  }
  close(DEPTH);
}

sub GetDirectory {
  my $dir = shift; my $size = shift;
  $dir .= "-Regular" unless $dir =~ m/-/;
  $dir =~ s!MathJax_!TeX/png/!; $dir =~ s!STIX!STIX/png/!; $dir =~ s!-!/!;
  $dir .= sprintf("/%03d",$size) if $size;
  checkDir($dir);
  return $dir;
}

sub checkDir {
  my @path = split(/\//,shift);
  foreach my $i (0..$#path) {
    my $dir = join("/",@path[0..$i]);
    mkdir $dir unless -e $dir;
  }
}

mkdir "PNG";

@sizes = (50,60,71,85,100,120,141,168,200,238,283,336,400,476); # 566
@sizes = @ARGV if @ARGV;

$name = $font; $name =~ s/\..*//; $name =~ s!.*/!!;
print "$name:";
MakeFontFiles($font);
while (@unicode = GetUnicodePoints) {
  print " [";
  MakeTeXfile(scalar(@unicode));
  foreach $size (@sizes) {
    print " $size";
    MakePNGfiles($size,@unicode);
    $directory = GetDirectory($name,$size);
    RenameFiles($directory,@unicode);
  }
  RemoveFontBlock;
  print " ]";
}
SaveDepths(GetDirectory($name));
print "\n";

`rm MathJax.*`;
`rm -rf PNG`;

1;
