#!/bin/bash

Help()
{
  echo ""
  echo "Usage: build_font [-t | -o] [-i] [-a] [-w] [-c] [-f FAMILYNAME] [-s NUM] [-p NUM] file.glyphs"
  echo ""
  echo "A script for building variable and static versions of the Elstob font."
  echo "It does several things that are specific to Elstob and probably unsuitable"
  echo "for other fonts. Either run this script in the sources directory or copy"
  echo "all files from the sources directory to a build directory and run it there."
  echo ""
  echo "  -t Builds static TrueType fonts instead of a variable font"
  echo "  -o Builds static CFF fonts instead of a variable font"
  echo "  -a Autohint the variable font with ttfautohint-vf"
  echo "  -n Do not hint TrueType fonts"
  echo "  -i Generate a shorter collection of instances"
  echo "  -w Create a woff2 version of the variable font"
  echo "  -c Do not clean up temporary files and directories (for debugging)"
  echo "  -f FAMILYNAME Supply a new family name"
  echo "  -s NUM (0-15) Set italic slant for static fonts (15 = more upright)"
  echo "  -p NUM (0-1)  Set width of space for static fonts (1 = wider)"
  echo "  -d PATH Directory containing source files (default is ./)"
  echo "  -z PATH Directory in which to write new fonts (default is ./dist/)"
  echo "  -b PATH Directory for temporary files (default is ./build/)"
  echo ""
}

Usage()
{
  echo
  echo "Usage: build_font [-t | -o] [-i] [-a] [-w] [-c] [-f FAMILYNAME] [-s NUM] [-p NUM] [-d PATH] [-z PATH] [-b PATH] file.glyphs"
  echo "    Type \"build_font -h\" for a longer help message."
  echo
}

delete_tmp () {
  if [ ! -z "$tmp_d" ]
  then
    echo "Deleting temporary file ${tmp_d}."
    rm -fr $tmp_d
  fi
}

if [ $# -lt 1 ]
then
    Usage
    exit 1
fi

HOMEDIR=`pwd`

SOURCEDIR=$HOMEDIR

DESTDIR=$HOMEDIR/dist

BUILDDIR=$HOMEDIR/build

outputType="v"

glyphsfile="nofile"

fontname="nofont"

familyName="Elstob"

instanceScript="del_instances_vf.xsl"

hintoption="-a"

autohint=0

createwoff=0

italslant=6

spacing=0

while getopts "htoanwcif:s:p:d:z:b:" options; do
  case "${options}" in
    h)
      Help
      exit 0
      ;;
    t)
      outputType="s"
      instanceScript="del_instances.xsl"
      ;;
    o)
      outputType="o"
      instanceScript="del_instances.xsl"
      ;;
    a)
      autohint=1
      ;;
    n)
      autohint=-1
      hintoption="-A"
      ;;
    w)
      createwoff=1
      ;;
    i)
      instanceScript="del_instances_shorter.xsl"
      ;;
    f)
      familyName=${OPTARG}
      ;;
    s)
      italslant=${OPTARG}
      ;;
    p)
      spacing=${OPTARG}
      ;;
    d)
      SOURCEDIR=${OPTARG}
      ;;
    z)
      DESTDIR=${OPTARG}
      ;;
    b)
      BUILDDIR=${OPTARG}
      ;;
  esac
done

if [ $(( $# - $OPTIND )) -ne 0 ]
then
  echo "Need name of Glyphs file"
  exit 1
fi
glyphsfile=${@:$OPTIND:1}
if [ ${glyphsfile##*.} != "glyphs" ]
then
   echo "${glyphsfile} appears not to be a Glyphs file"
   exit 1
fi

ff=$(basename -- $glyphsfile)
fontname=${ff%.*}

# If the arguments somehow haven't worked

if [ $glyphsfile == "nofile" ] || [ $fontname == "nofont" ]
then
    echo "Could not derive the filename or fontname."
    exit 1
fi

rm -rf $BUILDDIR
mkdir -p $BUILDDIR
[ ! -d $DESTDIR ] && mkdir $DESTDIR
cd $BUILDDIR

glyphsfile=$SOURCEDIR/$glyphsfile
instanceScript=$SOURCEDIR/$instanceScript

# If a new family name is specified, make a copy of the Glyphs file (with the
# new familyName) in a temp directory and use that copy to build the font.
# Remove the temp directory at the end of the program.

tmp_d=""
if [[ $familyName != "Elstob" ]]
then
  tmp_d=$(mktemp -d)
  tmp_f=$tmp_d/$ff
  sed -e "s/familyName = Elstob;/familyName = ${familyName};/" $glyphsfile > $tmp_f
  glyphsfile=$tmp_f
fi

# Determine whether this is the italic or the roman font

if [[ $fontname == *"Italic"* ]]
then
    fonttype="italic"
else
    fonttype="roman"
fi

# Build the designspace filename

des=$BUILDDIR/master_ufo/$fontname.designspace

echo "Generating master UFOs and designspace files"

glyphs2ufo --propagate-anchors --generate-GDEF --no-store-editor-state -m master_ufo -d $des $glyphsfile
if [ $? -ne 0 ]
then
    echo "Failed to generate UFO and designspace"
    delete_tmp
    exit 1
fi

# Need Gnu sed. The default (BSD) sed on the Mac won't cut it. There use
# Homebrew to get gsed.

sedcmd="sed"
if command -v gsed &> /dev/null
then
  sedcmd="gsed"
fi

familyname=`$sedcmd -n '1,/<source.*familyname/s/.*familyname="\([^"]*\)"[^\n]*/\1/p' $des`
echo "Building font(s) with family name \"${familyname}\""

# PERFORM EDITS ON DESIGNSPACE AND UFO FILES.

# Every glyph with a "us" anchor also needs a "_us" anchor or fontmake (glyphsLib,
# I think) will mess up the anchors for that glyph. But there is no requirement
# that anchors must be paired this way, and it's easy to imagine the extraneous
# anchors causing problems (though I don't know that it has). As it is easy to
# strip the extraneous anchors out of the UFO, it's best that we do so.

echo "Removing extraneous anchors"

for u in `$sedcmd -n '/<source.*filename/s/.*filename="\([^"]*\)"[^\n]*/\1/p' $des`
do
    for fff in `grep -l "anchor.*\"_us\"" master_ufo/$u/glyphs/*.glif`
    do
	if [[ ! $fff == *"usabovecomb.glif"* ]]
	then
	    xsltproc -o $fff $SOURCEDIR/del_usanchor.xsl $fff
	    if [ $? -ne 0 ]
	    then
        delete_tmp
        exit 1
	    fi
	fi
    done
done

# The Glyphs file has more instances than needed--some only there to hold down
# the corners of the design space. There are standard collections of instances
# for the variable font, the desktop set (ElstobD), and the web static set.

if [ $fonttype == "italic" ]
then
    sn="Grade Italic"
else
    sn="Grade"
fi
grep -q "stylename=\"${sn}\"" $des
if [ $? -eq 0 ]
then
    echo "Removing unnneeded instances"
    xsltproc -o $des $instanceScript $des
fi

if [ $outputType != "v" ];
then
  # fix-spacing.xsl sets the default spacing via the Spacing axis. Change
  # the number "sp" (use anything between 0 and 1) to change the spacing.
  # Now use -p option for this (static fonts only).

  xsltproc --param sp $spacing -o $des $SOURCEDIR/fix-spacing.xsl $des
  if [ $? -ne 0 ]
  then
    echo "fix-spacing script failed"
    delete_tmp
    exit 1
  fi

  # Set the slant of the static Italic fonts. Change the number "sl"
  # (using anything between 0 and 15) to change the slant.
  # Now use -s option for this (static fonts only).

  if [ $fonttype == "italic" ]
  then
    xsltproc --param sl $italslant -o $des $SOURCEDIR/fix-italic-slant.xsl $des
    if [ $? -ne 0 ]
    then
      echo "fix-italic-slant script failed"
      delete_tmp
      exit 1
    fi
  fi
fi

# RUN FONTMAKE TO BUILD THE FONTS (s = static TrueType; o = static CFF; v = variable TrueType).

if [ $outputType = "s" ];
then

  echo "Running fontmake to build static TrueType instances"

  fontmake -o ttf $hintoption -i -m $des
  if [ $? -ne 0 ]
  then
    echo "fontmake failed"
    delete_tmp
    exit 1
  fi

  # Add a dummny dsig table in the fonts we've just built.

  #cd instance_ttf
  #if [ $fonttype == "italic" ]
  #then
  #  echo "Adding a DSIG table to the italic font"
  #  find . -maxdepth 1 -name "${familyname}*Italic.ttf" -exec python $SOURCEDIR/add_dsig.py {} \;
  #else
  #  echo "Adding a DSIG table to the roman font"
  #  find . -maxdepth 1 -name "${familyname}*.otf" -not -name "*Italic.ttf" -exec python $SOURCEDIR/add_dsig.py {} \;
  #fi
  cp $BUILDDIR/autohinted/instance_ttf/Elstob*.ttf $DESTDIR

# Next CFF OpenType fonts, largely duplicating the moves for static TrueType.

elif [ $outputType == "o" ]
then

  echo "Running fontmake to build static CFF instances"

  xsltproc -o $des $SOURCEDIR/fix-spacing.xsl $des
  fontmake -o otf -i -m $des
  if [ $? -ne 0 ]
  then
    echo "fontmake failed"
    delete_tmp
    exit 1
  fi
  #cd instance_otf
  #if [ $fonttype == "italic" ]
  #then
  #  echo "Adding DSIG table and hinting the italic font"
  #  find . -maxdepth 1 -name "${familyname}*Italic.otf" -exec python $SOURCEDIR/add_dsig.py {} \; -exec psautohint {} \;
  #else
  #  echo "Adding DSIG table and hinting the roman font"
  #  find . -maxdepth 1 -name "${familyname}*.otf" -not -name "*Italic.otf" -exec python $SOURCEDIR/add_dsig.py {} \; -exec psautohint {} \;
  #fi
  cp $BUILDDIR/instance_otf/Elstob*.otf $DESTDIR
# Finally a variable font. We only build the TrueType flavor, since that seems
# to work everywhere.

else

  echo "Running fontmake to build variable font"

  fontmake -o variable -m $des
  if [ $? -ne 0 ]
  then
    echo "fontmake failed"
    delete_tmp
    exit 1
  fi

  cp "variable_ttf/${fontname}-VF.ttf" .

  echo "Adding dsig table"

  python $SOURCEDIR/add_dsig.py "${fontname}-VF.ttf"

  echo "Building STAT table and fixing name table"

  python $SOURCEDIR/mkstat.py $fonttype
  if [ $? -ne 0 ]
  then
    echo "Failed to build STAT table"
    delete_tmp
    exit 1
  fi

  # Hinting: if autohinting requested, check for existence of ttfautohint-vf and
  #     run it if available.
  # If autohinting not requested, run Xgridfit.
  # If hinting suppressed or either of these methods fails, user will be left
  #     with unhinted font.

  if [ $autohint == 1 ]
  then
    if command -v ttfautohint-vf &> /dev/null
    then
      echo "Running ttfautohint-vf"
      ttfautohint-vf "${fontname}-VF-withSTAT.ttf" tmp-font.ttf
      # Fix a flag in head table, as Google Fonts prescribes; then clean up.
      gftools-fix-hinting.py tmp-font.ttf
      cp tmp-font.ttf.fix "${fontname}.ttf"
    else
      echo "ttfautohint-vf (the variable-font-enabled version of ttfautohint)"
      echo "is required to auto-hint a variable font."
    fi
  elif [ $autohint -ne -1 ]
  then
    echo "Running Xgridfit"
    xgridfit -q -i "${fontname}-VF-withSTAT.ttf" -o "${fontname}.ttf" $SOURCEDIR/xgf/$fontname.yaml
    if [ $? -ne 0 ]
    then
      echo "Failed to hint with Xgridfit."
      cp "${fontname}-VF-withSTAT.ttf" "${fontname}.ttf"
    fi
  else
    echo "Skipping hinting"
    cp "${fontname}-VF-withSTAT.ttf" "${fontname}.ttf"
  fi
  if [ $createwoff == 1 ]
  then
    echo "Creating woff2 version"
    woff2_compress "${fontname}.ttf"
  fi
  cp $fontname.ttf $DESTDIR/

fi

delete_tmp

cd $HOMEDIR
