/var/log/journal

Thoughts, stories and ideas.

09th July 2018 · 8 minutes · ios macos
Gilbert, NTBixa and Abelone fonts
Gilbert, NTBixa and Abelone fonts

Fonts, as we know them, only contain a single color information, using either vector or bitmaps. We call them monochromatic fonts. They do not contain any other color information. That’s why a glyph (usually a character) can only have one color, by default black.

The main font format nowadays is the Open Font Format (OFF), on which OpenType (OT) is based. Thanks to its flexibility, OpenType fonts are used commonly today on the major computer platforms.

OpenType SVG (OTS) is a new font format in which an OpenType font has all or just some of its glyphs represented as SVG artwork.

This allows the display of multiple colors, gradients, shades and even transparency in a single glyph.

We also refer to OTS fonts as “color fonts”, and you’ve been using them for years already.

Emoji

The Unicode Standard began to add emoji in its sixth version, in late 2011. A lot of actors integrated them in their products and platforms, but this was just a start. Unicode emoji are handled as text, and color is an essential aspect of the emoji experience. This led to a need to create mechanisms for displaying multicolor glyphs. Each actor then created its own format to display it own emojis. So emojis are color fonts.

Emoji are SVG fonts
Emoji are SVG fonts

Color font formats

All of major players have previously developed and implemented their own proprietary color formats to display emojis, for the gaming, or printing purpose.

There are two types of color fonts: the one using vectors or the ones using bitmaps. The major difference is that bitmaps’ color fonts are not scalable and thus, they get bigger really quick.

There is a ton of color font formats, but today the three major are SBIX, CBDT and COLR.

Name Actor Type
SBIX Apple Bitmap
CBDT Google Bitmap
COLR Microsoft Vector

As you see, no real consensus existed on that topic.

To address this fragmentation, Mozilla and Adobe decided to work on a new format, taking the best of all. Google and Microsoft also joined the battle, and in 2016, the OTS standard was born.

OpenType logo
OpenType logo

OTS is both SVG and bitmap compatible.

As you see, the OTS standard is relatively new, and therefore as of 2017, no operating system supports OTS fonts. But it’s changing!

OTS in Apple ecosystem

While browsing the headers of the new Xcode 10 beta 2, I noticed a completely new framework in CoreText, OTSVG.framework.

Again some headers exploring, a quick search on the Internet and I stumble upon this tweet1, confirming my suspicion: OTS support is coming to Apple ecosystem!

You can also find the related new data types and functions online.

CoreText datatypes
GCoreText datatypes
CoreText functions
CoreText functions

This new framework is available on iOS 12.0+, macOS 10.14+, watchOS 5.0+, tvOS 12.0+ starting Xcode 10 beta 2.

How to use it?

Well, this is the easy part, you don’t need to do anything else to use them. Either select the font in the Interface Builder or set it in the code. For example to use the Playbox font with a UILabel:

label.text = "An OpenType SVG font on iOS!"
label.font = UIFont(name: "PlayboxRegular", size: 30)
Playbox font on iOS 12
Playbox font on iOS 12

What about retrocompatibility?

iOS 11 and previous will not crash, they’ll just display a plain black version of the glyphs. That’s neat, right?

Playbox font on iOS 11
Playbox font on iOS 11

Font features

A ma­jor goal of Open­Type was to pro­vide bet­ter sup­port for in­ter­na­tional lan­guages than its pre­de­ces­sors. In order to do this, Open­Type introduced lay­out fea­tures, com­monly known as font features, that al­low fonts to spec­ify what and how these features should be in­serted into the text. And of course, color fonts have font features.

But not all color fonts have all font features. So first we need to check what are the features available in the font. I choose the font Trajan Color as example. We use CTFontCopyFeatures(_:) to extract the font features.

let font = UIFont(name: "TrajanColor-Concept", size: 30)
let features = CTFontCopyFeatures(font)

Let’s see the content of it. Don’t forget to bring your Font Feature Registry.

(
    {
        CTFeatureTypeIdentifier = 0;
        CTFeatureTypeName = "All Typographic Features";
        CTFeatureTypeNameID = "-100";
        CTFeatureTypeSelectors =         (
            {
                CTFeatureSelectorDefault = 1;
                CTFeatureSelectorIdentifier = 0;
                CTFeatureSelectorName = On;
                CTFeatureSelectorNameID = "-101";
            }
        );
    },
     
    [...]

    {
        CTFeatureTypeIdentifier = 35;
        CTFeatureTypeName = "Alternative Stylistic Sets";
        CTFeatureTypeNameID = "-3600";
        CTFeatureTypeSelectors =         (
            {
                CTFeatureSelectorIdentifier = 2;
                CTFeatureSelectorName = Silver;
                CTFeatureSelectorNameID = 256;
            },
            {
                CTFeatureSelectorIdentifier = 4;
                CTFeatureSelectorName = Copper;
                CTFeatureSelectorNameID = 257;
            },
            
            [...]

            {
                CTFeatureSelectorIdentifier = 26;
                CTFeatureSelectorName = Salmon;
                CTFeatureSelectorNameID = 268;
            },
                
            [...]
            
            {
                CTFeatureSelectorIdentifier = 40;
                CTFeatureSelectorName = Solid;
                CTFeatureSelectorNameID = 275;
            }
        );
    }
)    

Let’s take the one named “Alternative Stylistic Sets”. It’s identifier is 35.

In your registry, find the one with the Feature Value equals to that value. This one. The feature constant is kStylisticAlternativesType.

The CTFeatureTypeSelectors array below describe the values available for that feature.

Let’s says I want the one named “Salmon”, with the identifier 26. We need to find the selector value in the registry matching the identifier. Then retrieve the Selector Constant value, in the previous column, to activate it. In our case, the value is kStylisticAltThirteenOnSelector.

We now have the feature we want, need to add it to our font, using a UIFontDescriptor.

let alternativesType = [
	UIFontDescriptor.FeatureKey.featureIdentifier: kStylisticAlternativesType,
	UIFontDescriptor.FeatureKey.typeIdentifier: kStylisticAltThirteenOnSelector
]

let descriptor = font
            	.fontDescriptor
	            .addingAttributes(
    	            [UIFontDescriptor.AttributeName.featureSettings: [alternativesType]]
        	    )

Finally we create a new font with this new feature.

let salmonFont = UIFont(descriptor: descriptor, size: 0.0)
Trajan font
Trajan font

Where can I get these gorgeous color fonts?

Color fonts are still new and so hard to find. You can go to colorfonts.wtf, which references most of them. And if you are inspired you can even create your own with a dedicated software, Fontself.

What’s next?

At the moment, the OTSVG.framework is only available in Objective-C, so I encourage you to browse the header of the framework if you want to go further. Watch closely the new betas and the documentation.

OTSVG.framework
OTSVG.framework

There is still a lot to talk about and explore about color fonts and I hope these colorful fonts will appear on some iOS app in next fall!

Last updated on 02nd September 2019