There a handful of "bitmap in font" standards - embedded bitmaps at various sizes, embedded SVGs, etc. Our goal is to convert the Apple font into something that can be read by Chrome and/or Firefox on Linux systems.
There are two modes of running:
- With Docker
- Without Docker
As long as you have a copy of the emoji font (say, Apple Color Emoji.ttc
), then you can run:
./run-in-docker.sh [/path/to/input/file]
After the image builds and runs, you should get a finished file in assets/AppleColorEmoji.ttf
.
Note: I've only tested this on macOS directly, but the Docker image runs on Ubuntu so should theoretically work elsewhere.
fontforge
ttx
(part offonttools
)xmlstarlet
- Python 3, with
pip install fonttools
Defaults assume you're using macOS, but it's not necessary.
./convert.sh [/path/to/input/file] [/path/to/output/file]
The input file is expected to be an instance of Apple Color Emoji.ttc
, and will probably break in weird ways on other fonts.
The default args (if run simply with ./convert.sh
) will read from /System/Library/Fonts/Apple Color Emoji.ttc
and output to ./AppleColorEmoji.ttf
.
OpenType has a handful of sanctioned extensions:
- Apple's
sbix
(doc): Works on macOS/iOS. Embedded PNG/JPEG/TIFF. - Google's
CBLC
/CBDT
(CBLC
doc/CBDT
doc): Works on Android, but supported in Linux. Embedded uncompressed BMP/compressed PNG. - Microsoft's
COLR
/CPAL
(COLR
doc/CPAL
doc): (multi-)coloured glyphs SVG
/CPAL
(SVG
doc/CPAL
doc): Embedded SVG with (multi-)colour palette.
Our only real viable option here is to convert sbix
to CBLC
/CBDT
. Frustratingly similar, but also different. Hooray for standards!
Emojis make use of ligatures (i.e. person emoji + skin tone, or blank flag + colour), so we need to make sure we retain those mappings.
Apple uses mort
(deprecated) or morx
to define their ligatures (part of AAT, not OpenType), so we'll want to convert them to GDEF
and GSUB
definitions to make use of them.
- Extract ligature information (using
fontforge
andttx
) - Convert PNG tables (using
a2a.py
) - Convert & inject ligature information (using
xmlstarlet
anda2a.py
) - Write our result to a file!
The heavy lifting here is done via a2a.py
. I updated it to include dynamic/external ligature information, and to run on Python 3.