[Guide] Juce Font Embedding (2019)

There are MANY threads about fonts and embedding.
But the information is pretty scattered around the forum.

Few notes regarding fonts and cross-platform:

  • Fonts by themselves aren’t assured to be available between OSes. also sometimes an OS would replace the default font or fallbacks. so a UI design with standard fonts might show up differently not only for different platforms but also for different OS versions.
  • TTF seems to be more cross platform at least from what’s written in the forum.
    (Ubuntu - JUCE Not Reading OTF Fonts, Embedding Custom Fonts OTF, TTF)

Embedded Fonts Cheat-Sheet:

Return a static Font (you can also return Typeface::Ptr) to be used each time you need the Typeface/Font object.

       static const Font getCustomFont()
        {
            static auto typeface = Typeface::createSystemTypefaceFor (BinaryData::CustomFont, BinaryData::CustomFont_size);
            return Font (typeface);
        }

Set a custom type to default (can be used from a LookAndFeel constructor)

setDefaultSansSerifTypeface (customTypeface);

If needed for DRY / LookAndFeel:

  1. override Typeface::Ptr getTypefaceForFont (const Font& f)

  2. IMPORTANT! apply your LookAndFeel using parent LookAndFeel:
    LookAndFeel::setDefaultLookAndFeel (&customLookAndFeel);

  • Note: you can call this from your LookAndFeel constructor (this) or from another component constructor as written above.

Here is a PIP (projucer) demo project:
CustomFontPIP.h (198.1 KB)

P.S. - This code was tested under Windows 10, macOS 10.7, macOS 10.14 and Linux (Debian).

Here is how to should look (this can be used to check if it ever got broken):
image


29 Likes

Thank you!! Very clear and concise.

1 Like

This was a handy cheat-sheet, indeed, thank you!

I’ll note that this seems to work just as well:

       static const Font getCustomFont()
       {
           return Font (Typeface::createSystemTypefaceFor (BinaryData::CustomFont, BinaryData::CustomFont_size));
       }

Was there some benefit to declaring typeface and making it static?

Pretty sure that your 2nd example is going to call Typeface::createSystemTypefaceFor every time you getCustomFont() (and that’s probably a costly operation), whereas the static version should only do it once.

4 Likes

Ah, right, that makes sense, if you repeatedly call getCustomFont() throughout your LookAndFeel class.

I was taking the approach of the LookAndFeel class having several Font class members, and was just calling a variant of getCustomFont() once for each typeface at construction, and assigning its returned value to those Font members. And so I was trying to think when I might need that static Typeface again later, and the answer seemed to be never…

hey
How can I change the font size using this method? How can I provide the typeface with a font size and a font family and return it in the getCustomFont () function?

I can’t enter g.setFont(juce::Font(20.f), getCustomFont());

How about:

g.setFont(getCustomFont().withHeight(20.0f));

Matt

2 Likes

oh jeah, thank you :slight_smile:

For anyone like me who could not figure out how to create the binary data for the font, this guy explains how to do it.

What is BinaryData::CustomFont ? Is it downloaded TIFF font in binary file representation?

and where is setDefaultSansSerifTypeface?

And so on… Can you provide exact info what is inherited, what overwritten, and where a font is loaded. Otherwise it is just list of methods and I don’t know how to apply your instructions.

If you use wither the Projcuer assets or the BinaryBuilder provided in the JUCE extras, then you can embed any assets into cpp files.

The cpp files look like that below

//BinaryFonts.hpp
namespace BinaryFonts {
	extern const char *Font_ttf; // this reflects the file name
	const int          Font_ttfSize = 804612;
}
_______________________________________________
//BinaryFonts.cpp
#include "BinaryFonts.hpp"

static const unsigned char temp2[] = {0,1,19,...};


const char *BinaryFonts::Font_ttf = (const char *)temp1;