#!/bin/sh

# mkvtxfont for VideoteXt
#
# $Id: mkvtxfont,v 1.1 1996/11/03 23:55:18 mb Exp mb $
#
# Copyright (c) 1994-96 Martin Buck  <martin-2.buck@student.uni-ulm.de>
# Read COPYING for more information

# This little GAWK-script converts a font stored in a PBM-file into two BDF-files (single & double
# height). The PBM-file must consist of 256 characters, 32 characters per line with fixed width &
# height, no spaces between characters. The width & height of the characters are detected
# automatically.


if [ $# -ne 4 ]; then
  echo Usage: $0 '<pbm-file> <bdf-normal> <bdf-doubleht> <vtx-font>' >&2
  exit 1
fi

exec gawk -v "nfile=$2" -v "dfile=$3" -v "vfile=$4" -f - << "THIS_IS_THE_END" "$1"

function print_header(xsize, ysize, ptsize, width, file) { # Print BDF-File header
  print "STARTFONT 2.1" > file
  print "FONT -misc-videotext-medium-r-" width "--" ysize "-" ptsize "-75-75-c-" xsize * 10 "-misc-fontspecific" > file
  print "SIZE " ptsize " 75 75" > file
  print "FONTBOUNDINGBOX " xsize " " ysize " 0 0" > file
  print "STARTPROPERTIES 5" > file
  print "FONT_ASCENT " ysize > file
  print "FONT_DESCENT 0" > file
  print "DEFAULT_CHAR 32" > file
  print "COPYRIGHT \"Copyright (c) " strftime("%Y") " Martin Buck\"" > file
  print "NOTICE \"This font was created automatically from a PBM-File by mkvtxfont  DO NOT EDIT\"" > file
  print "ENDPROPERTIES" > file
  print "CHARS 256" > file
}

function print_charpref(char, xsize, ysize, file) { # Print prefix for each character-bitmap
  print "STARTCHAR CHR" char > file
  print "ENCODING " char > file
  printf "SWIDTH %d 0\n", xsize / (ysize / 1000 * 75 / 72) > file
  print "DWIDTH " xsize " 0" > file
  print "BBX " xsize " " ysize " 0 0" > file
  print "BITMAP" > file
}

function bindec(bin,  dec, binlen, bitpos) { # Convert bin (MSBfirst) to decimal
  dec = 0
  binlen = length(bin)
  for (bitpos = 1; bitpos <= binlen; bitpos++) {
    dec = 2 * dec + substr(bin, bitpos, 1)
  }
  return dec
}


BEGIN {
  MAGIC = 0 # Constants for currently parsed sections
  XSIZE = 1
  YSIZE = 2
  BITMAP = 3
  finished = 1
  bitpos = 0 # This is necessary, because it is used as array-index
}


/#/ { # Remove comments
      gsub(/#.*$/, "")
    }

/\r/ { # Remove MS-LOSS CRs
       gsub(/\r/, "")
     }

{
  field = 1
  while ($field != "") {
    if (fieldtype == BITMAP && !finished) { # Parse character-bitmap
      bits = bits $field           # Append new bits until enough for one character (xsize)...
      if (length(bits) == xsize) { 
        if (length(bits) % 8)
          bits = bits substr("00000000", 1, 8 - (length(bits) % 8))
        tmpbits[bitpos] = bits     # ... & store them (in the PBM-file they are in the wrong order)
        bitpos++
        bits = ""
        if (bitpos == 32 * ysize) { # Start dumping bitmaps, if enough lines (ysize) have been read
          for (char = 0; char <= 31; char++) {
            printf "[" char + chroffs "] "
            print_charpref(char + chroffs, xsize, ysize, nfile)
            print_charpref(char + chroffs, xsize, ysize * 2, dfile)
            for (line = 0; line < ysize; line++) {
              pixelrow = tmpbits[char + line * 32]
              hexval = ""
              for (pos = 1; pos <= xsize ; pos += 8) {
                byte = bindec(substr(pixelrow, pos, 8))
                hexval = hexval sprintf("%02X", byte)
                printf "%c", byte > vfile
              }
              print hexval > nfile
              print hexval > dfile
              print hexval > dfile
            }
            print "ENDCHAR" > nfile
            print "ENDCHAR" > dfile
          }
          chroffs += 32 # Next row of characters
          if (chroffs == 256) {
            print "ENDFONT" > nfile
            print "ENDFONT" > dfile
            printf "\nAll characters processed\n"
            finished = 1
          }
          bitpos = 0
        }
      }
    } else if (fieldtype == MAGIC) { # Search for PBM-ASCII magic number
      if ($field != "P1") {
        print "Couldn't find magic number"
        exit 1
      }
      fieldtype++
    } else if (fieldtype == XSIZE) { # Search for width of image (must be divisible by 32
      xsize = $field                 # -> 32 characters per line)
      if (xsize % 32) {
        print "PBM-File has invalid width"
        exit 1
      }
      xsize /= 32
      fieldtype++
    } else if (fieldtype == YSIZE) { # Search for height of image (must be divisible by 8
      ysize = $field                 # -> 8 lines of characters)
      if (ysize % 8) {
        print "PBM-File has invalid height"
        exit 1
      }
      ysize /= 8
      ptsize = int(ysize * 720 / 75)
      print "This seems to be a " xsize "x" ysize " font"
      print_header(xsize, ysize, ptsize, "normal", nfile)
      print_header(xsize, ysize * 2, ptsize * 2, "half", dfile)
      printf "VTXFONTV1%c%c", xsize, ysize > vfile
      finished = 0
      fieldtype++
    }
    field++
  }
}


END {
  if (!finished)
    printf "\nUnexpected EOF\n"
  close(nfile)
  close(dfile)
  close(vfile)
}

THIS_IS_THE_END
