Skip to content

Instantly share code, notes, and snippets.

@rsms
Created March 9, 2020 17:06
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rsms/6baadd90116e8c2d54574ee52f1d8be7 to your computer and use it in GitHub Desktop.
Save rsms/6baadd90116e8c2d54574ee52f1d8be7 to your computer and use it in GitHub Desktop.
Terribly hacky script for generating GIFs of font changes over time
#!/bin/bash -e
#
# Generate GIFs of font changes over time
#
# HERE BE DRAGONS!
# This is a hack of a script. It won't just run for you. Edit it to suit your system and needs.
#
pushd "$(dirname "$0")" >/dev/null
chardiffdir=$PWD
pushd "../.." >/dev/null
srcdir=$PWD
fontsample=$srcdir/misc/tools/fontsample/fontsample
popd >/dev/null
popd >/dev/null
outfile=$1
text=$2
xscale=$3
yscale=$4
fontscale=$5
tracking=$6
tile=$7
if [[ "$outfile" == "" ]] || [[ "$text" == "" ]] || [[ "$outfile" == "-h" ]]; then
echo "usage: $0 <outfile.gif> <text> [<scale> | <xscale> <yscale> [<fontscale> [<tracking> [<tile>]]]]" >&2
echo "<tile> The number of rows to tile over. Defaults to 1." >&2
exit 1
fi
if [[ "$xscale" == "" ]]; then xscale=1; fi
if [[ "$yscale" == "" ]]; then yscale=$xscale; fi
if [[ "$fontscale" == "" ]]; then fontscale=$yscale; fi
if [[ "$tracking" == "" ]]; then tracking=0; fi
if [[ "$tile" == "" ]]; then tile=1; fi
fontsize=$(echo 200 '*' $fontscale | bc -l)
width=$(echo 196 '*' $xscale | bc -l)
height=$(echo 256 '*' $yscale | bc -l)
tracking=$(echo "$tracking * $fontscale" | bc -l)
if [[ "${tracking:0:1}" != "-" ]]; then
# imagemagick requires positive numbers to be prefixed with + (I think?)
tracking="+${tracking}"
fi
# space in unscaled pixels to add at bottom for label
labelpadding=40
workdir="$chardiffdir/work"
rm -rf "$workdir"
# workdir=$(mktemp -d "$chardiffdir/work.XXXXXX")
# echo "using workdir $workdir"
# function cleanup_workdir {
# echo "removing workdir $workdir"
# rm -r "$workdir"
# }
# trap cleanup_workdir EXIT
# ABCDEFGHIJKLMNOPQRSTUVWXYZ
# abcdefghijklmnopqrstuvwxyz
mkdir -p "$workdir/subframe"
mkdir -p "$workdir/frame"
pushd "${chardiffdir}/fonts" >/dev/null
# generate images
echo "render ${#text} glyphs"
for (( i=0; i<${#text}; i++ )); do
letter=${text:$i:1}
# echo "render \"$letter\""
for v in *.*; do
framenum=$i
if [[ ${#framenum} -eq 1 ]]; then
framenum=00${framenum}
elif [[ ${#framenum} -eq 2 ]]; then
framenum=0${framenum}
fi
$fontsample -t "$letter" \
-z $fontsize \
-width $width \
-height $height \
-o "$workdir/subframe/$v-$framenum.png" "$PWD/$v/"*"Regular.otf" >/dev/null &
done
done
# count versions while we wait for fontsample to finish
numversions=0
for v in *.*; do
((numversions++))
done
# wait for fontsample to finish
wait
# compose frames
i=0
framewidth=
frameheight=
echo "compositing ${numversions} frames"
for v in *.*; do
ver_major=${v/.*/}
ver_minor=${v#*.}
# echo "compose frame $(expr $i '+' 1)/${numversions} (v${ver_major}.$(expr ${ver_minor}))"
if [[ $i -eq 0 ]]; then
# first frame montage in main process so we can set framewidth and frameheight in main env
montage "$workdir/subframe/$v-"*".png" -mode Concatenate -background "#fff" -geometry $tracking+0 -tile "x${tile}" "$workdir/frame/$v.png"
framewidth=$(identify -format '%W' "$workdir/frame/$v.png")
frameheight=$(identify -format '%H' "$workdir/frame/$v.png")
echo "final size: ${framewidth}×$(expr $frameheight '+' $labelpadding)px"
fi
(
if [[ $i -gt 0 ]]; then
montage "$workdir/subframe/$v-"*".png" -mode Concatenate -background "#fff" -geometry $tracking+0 -tile "x${tile}" "$workdir/frame/$v.png"
fi
# extent here adds space at bottom for the label
convert \
-gravity North \
-extent "${framewidth}x$(echo "$labelpadding + $frameheight" | bc -l)" \
-gravity SouthWest \
-fill "#0008" -annotate +20+10 "Inter v${ver_major}.$(expr ${ver_minor})" \
-font /Users/rsms/src/inter/build/fonts/const/Inter-Regular.otf -pointsize 22 \
"$workdir/frame/$v.png" "$workdir/frame/$v.png"
) &
# montage "$workdir/subframe/$v-"*".png" -mode Concatenate -background "#fff" -geometry $tracking+0 -tile "x${tile}" "-" | \
# convert \
# -fill "#0008" -annotate +20+10 "Inter v${ver_major}.$(expr ${ver_minor})" \
# -gravity SouthWest \
# -font /Users/rsms/src/inter/build/fonts/const/Inter-Regular.otf -pointsize 22 \
# "-" "$workdir/frame/$v.png" &
((i++))
done
wait
popd >/dev/null
echo "build GIF animation"
# https://imagemagick.org/Usage/anim_opt/
convert -delay 5 -loop 0 -coalesce -layers OptimizeFrame -layers OptimizeTransparency "$workdir/frame/"*".png" "$outfile"
gifsicle -O2 "$outfile" -o "$outfile"
eval $(stat -s "$outfile")
echo "wrote $outfile ($(expr ${st_size} '/' 1024)kB)"
# need gifsicle? Try `brew install gifsicle`
# # rename font/version folders
# # cd fonts
# # for v in *.*; do
# # major=${v/.*/}
# # minor=${v#*.}
# # if [ ${#minor} -eq 1 ]; then
# # minor=0${minor}
# # fi
# # name2="${major}.${minor}"
# # echo mv "$v" "${name2}"
# # done
# # cd ..
# # montage tiles_*.jpg -geometry 0 -tile 10x result.jpg
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment