How to generate a subset of an emoji font using Python
If you want to use an emoji font (like Noto Emoji or Noto Color Emoji) on your website but you only need a few of the characters, you’ll save a lot of bandwidth by generating a new font using only your chosen subset of characters. Here’s how to do that in Python 3.
Install the Python modules
fonttools
andbrotli
. e.g.:python3 -m pip install fonttools brotli
Download the font. e.g. on the Noto Emoji page at Google Fonts, click the “Download family” button, and unzip the downloaded file. Inside is a
static
directory. We’re going to make a subset of a single one of the.ttf
fonts inside it:NotoEmoji-Regular.ttf
You could either run the code below in the shell (type
python
on the command line) or put it in a file likecreate_font.py
and run it from the command line withpython create_font.py
You’ll need to change three things in the code:
- The path to the downloaded
.ttf
file to use as the source. - The path to where you want the
.woff2
file the code creates to be saved. - The list of emojis you want in the created font. Note that you need quote marks around each one. You could generate this list programmatically if, for example, they’re stored in a database.
- The path to the downloaded
from fontTools import subset
# One of the files downloaded from Google Fonts:
source_font_path = "path/to/NotoEmoji-Regular.ttf"
# Where we want to write our new file to. Note, it's woff2:
detination_font_path = "path/to/NotoEmoji-Regular-Custom.woff2"
# The only emojis that we want in our new font:
emojis = ["😀", "🧑🤝🧑", "👩👩👧👦", "🇬🇧", "⤴️", "🎂"]
# Create a list of unicode codes representing the characters in our emojis:
codes = []
for emoji in all_emojis:
for e in emoji:
codes.append(f"U+{:X}".format(ord(e)))
unicodes = ",".join(codes)
args = [
source_font_path,
f"--output-file={destination_font_path}",
f"--unicodes={unicodes}",
"--flavor=woff2",
]
subset.main(args)
The original .ttf
files are 877 KB in size.
I generated a .woff2
file for ooh.directory that contained 155 emojis and it was only 59 KB.
You could drag your generated file onto Wakamaifondue to check which emoji are in it, and other details.
This was mostly pieced together from Stack Overflow answers. The one wrinkle doing this with emoji, compared to standard characters, is that each emoji could be made up of between 1 and 10 separate characters. So we need to cycle through each character within each emoji and ensure we have them all in our new font.
Now what?
Once you’ve put the new font on your server (e.g. in a /fonts/
directory) you can use it in your website’s CSS something like this:
@font-face {
font-family: "Noto Emoji";
src: url("/fonts/NotoEmoji-Regular-Custom.woff2") format("woff2");
}
.emoji {
font-family: "Noto Emoji", sans-serif;
}
And then in your HTML if you do this:
<span class="emoji">😀</span>
Your emoji will be a Noto Emoji emoji instead of your OS’s standard style.
If you use an emoji that you haven’t built into your custom font file then it will appear as standard.
Thanks etc.
Thanks to Richard Rutter whose post “How to subset a variable font” was what first made me realise this kind of thing is even possible.
I’m definitely not an expert on either fonts or emojis so if you notice something that could be better please do comment (while they’re open) or email me.