#!/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 ""
}

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

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

outputType="v"

glyphsfile="nofile"

fontname="nofont"

familyName="Elstob"

instanceScript="del_instances_vf.xsl"

hintoption="-a"

autohint=0

createwoff=0

cleanupafter=1

italslant=6

spacing=0

while getopts "htoanwcif:s:p:" 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
      ;;
    c)
      cleanupafter=0
      ;;
    i)
      instanceScript="del_instances_shorter.xsl"
      ;;
    f)
      familyName=${OPTARG}
      ;;
    s)
      italslant=${OPTARG}
      ;;
    p)
      spacing=${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

# 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/$glyphsfile
  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="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"
    exit 1
fi

# If this line fails, maybe you need sed instead of gsed. But in any case you need
# Gnu sed.

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}\""

# 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 del_usanchor.xsl $fff
	    if [ $? -ne 0 ]
	    then
		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

# build the fonts. First things to do for both static types

if [ $outputType != "v" ];
then
  # fix-spacing.xsl sets the default spacing via the Spacing axis. Change
  # the number in l. 14 of the script (use anything between 0 and 1) to
  # change the spacing.

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

  # Set the slant of the static Italic fonts. Change the number in l. 14
  # of the script (using anything between 0 and 15) to change the slant.

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

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"
    exit 1
  fi

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

  cd autohinted/instance_ttf
  if [ $fonttype == "italic" ]
  then
    echo "Adding a DSIG table to the italic font"
    find . -maxdepth 1 -name "${familyname}*Italic.ttf" -exec python ../../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 ../../add_dsig.py {} \;
  fi
  cd ../..

# 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 fix-spacing.xsl $des
  fontmake -o otf -i -m $des
  if [ $? -ne 0 ]
  then
    echo "fontmake failed"
    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 ../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 ../add_dsig.py {} \; -exec psautohint {} \;
  fi
  cd ..

# 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"
    exit 1
  fi

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

  echo "Adding dsig table"

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

  echo "Building STAT table and fixing name table"

  python mkstat.py $fonttype
  if [ $? -ne 0 ]
  then
    echo "Failed to build STAT table"
    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"
      if [ $cleanupafter -ne 0 ]
      then
        rm tmp-font.ttf.fix
      fi
    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" "xgf/Elstob-${fonttype}-all.xgf"
    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
  if [ $cleanupafter -ne 0 ]
  then
    rm -f "${fontname}-VF.ttf"
    rm -f "${fontname}-VF-withSTAT.ttf"
  fi
fi

if [ $cleanupafter -ne 0 ]
then
  rm -fr master_ufo
  rm -fr variable_ttf
  if [ ! -z "$tmp_d" ]
  then
    rm -fr $tmp_d
  fi
fi
