I came across this use-case where we had to use a specific custom font but it was only available in .otf
. However, we want to support multiple formats to ensure even deprecated browsers can load the font. Otf has a global coverage of 97.89% but we didn't want to take any chances of the font not loading as it's a crucial feature in our app.
I wanted to convert the font to support the following browsers:
- woff2 - Latest browsers 🚀
- woff - Modern browsers 👍
- ttf - Apple and mobile OS 🍎📱
-
svg- older safari and ios support 😢 - eot - older IE support 😢
I am skipping svg as I found no converter package, fulfilling the same requirements as the others (available from Ubuntu repositories without additional sources).
The goal
Consider my font being custom.otf
then the font face should look like the following:
@font-face {
font-family: 'Custom';
src: url('custom.woff2') format('woff2'),
url('custom.woff') format('woff'),
url('custom.ttf') format('truetype'),
url('custom.otf') format('truetype'),
url('custom.eot') format('embedded-opentype');
}
The loading order is from latest to oldest so the majority should get the woff2/woff files.
Why not using an online converter?
Now I know there are many converters out there but I have some issues with them
- I can't upload the font, since the license forbids it
- I don't know what I download with the font into my system
- I don't have the time to check each of them
Let's see what Ubuntu provides out of the box
I immediatley thought I should check my Ubuntu repositories and do some research on tools to convert into all the required types:
package | command | description |
---|---|---|
eot-utils |
mkeot |
convert otf to eot |
eot2ttf |
eot2ttf |
convert eot to ttf |
woff-tools |
sfnt2woff |
convert otf to woff |
woff2 |
woff2_compress |
convert ttf to woff2 |
- | - | convert any of them to svg |
Let's create a simple bash script
The script should take in a single otf file and convert it to separate oet, ttf, woff and woff2 files on a given destination folder.
It should furthermore check, if the inputs are correct and the packages are installed.
The next parts are showing the script from top to bottom, split by some comments. If you combine all the parts into one file you will get the final script.
First of all, we create a new file
$ touch convertOtf.sh
Then we open it with our editor of choice, add the shebang and set the script to exit on the first error:
#!/usr/bin/env bash
set -e
Now check the parameters and create local variables from them:
SOURCE=$1
DESTINATION=$2
FILENAME=$(basename "${SOURCE%.otf}")
# we omit mime check since we use this script only locally and assume it's otf
if [[ ${SOURCE: -4} != ".otf" ]]; then
echo "usage: convertOtf input.otf /path/to/output/"
exit 1
fi
# check the destination is a folder
if [[ ! -d "$DESTINATION" ]]; then
echo "usage: convertOtf input.otf /path/to/output/"
exit 1
fi
We could directly add installing the commands into the script but it should be kept simple so we just warn of missing packages and exit:
ALLCOMMANDS=(
mkeot
eot2ttf
sfnt2woff
woff2_compress
)
# iterate the ALLCOMMANDS list to check for each required command
# skip as soon as a command is not found
for CMD in "${ALLCOMMANDS[@]}"
do
:
if [[ ! -f $(command -v "$CMD") ]];then
echo "Cannot convert ($CMD). The following packages are required: eot-utils eot2ttf woff-tools woff2"
exit 1
fi
done
Now that we've covered the requirements to convert our file we can now run the tools. Note, that they have to be in the right order, because some depend on the ouput of one another:
EOT_PATH="$DESTINATION/$FILENAME.eot"
echo "[OTF ---> EOT]: (over-)write to $EOT_PATH"
mkeot ${SOURCE} > ${EOT_PATH}
TTF_PATH="$DESTINATION/$FILENAME.ttf"
echo "[EOT ---> TTF]: (over-)write to $TTF_PATH"
eot2ttf ${EOT_PATH} ${TTF_PATH}
WOFF_PATH="$DESTINATION/$FILENAME.woff"
echo "[OTF --> WOFF]: (over-)write to $WOFF_PATH"
sfnt2woff ${SOURCE} > ${WOFF_PATH}
WOFF2_PATH="$DESTINATION/$FILENAME.woff2"
echo "[TTF -> WOFF2]: (over-)write to $WOFF2_PATH"
woff2_compress ${TTF_PATH} > ${WOFF2_PATH}
exit 0
Running the script
First, make the script executable, then run it with our otf font as first input and a destination folder as second input:
$ chmod +x ./convertOtf.sh
$ ./convertOtf.sh custom.otf ./out
[OTF ---> EOT]: (over-)write to ./out/custom.eot
[EOT ---> TTF]: (over-)write to ./out/custom.ttf
[OTF --> WOFF]: (over-)write to ./out/custom.woff
[TTF -> WOFF2]: (over-)write to ./out/custom.woff2
Compressed 25698 to 16389.
Summary
The script is a simple way to convert an otf to multiple webfont formats using only tools that Ubuntu brings with it's default repositories.
I am no bash guru, so please comment if you think there are parts in the code (or in the article in general) that can be improved 🙇
Resources used for this article
https://caniuse.com/
https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face
https://css-tricks.com/snippets/css/using-font-face/
https://github.com/ikatyang/emoji-cheat-sheet
https://stackoverflow.com/
https://help.ubuntu.com/stable/ubuntu-help/addremove-install-synaptic.html.en
Top comments (2)
Thanks for this article, way better than converting online, which somehow never works. I think there is an error with the WOFF format, the command
sfnt2woff
does not allow to specify a destination folder and the>
did not work for me.I replaced this with
Maybe its helpful to someone else. I have put the file in a repo here: github.com/dcts/font-converter-ubuntu
Wow, thanks for pointing this out ❤️