Modern custom font guide?


#1

Every discussion here about how to use a custom font is dated from 2010 or so.

Can anyone point out how to embed and use a custom font for modern JUCE?

Thanks.


Which Fonts Are Available In JUCE?
#2

I’ve done it a few times, I will try to write up a guide. It’s sort of (but not super) convoluted to get working.


#3

That would be awesome. Something tells me I’m not the only one who would find it useful. Thanks.


#4

It’s super simple with the Projucer. Just:

  • Add the TTF (or OTF etc) files to the Projucer project. By default it will add them in the BinaryData.
  • Use Typeface::createSystemTypefaceFor() to create the typeface and construct a font.

I’ve never had a problem doing this with a Meyer’s singleton, especially now they’re threadsafe to initialise in C++11. Let’s say you had a font WackyFont.otf and it has been added to the Projucer project. You can have a method to create this font:

static const Font& getWackyFont()
{
    static Font wacky (Font (Typeface::createSystemTypefaceFor (BinaryData::WackyFont_otf,
                                                                BinaryData::WackyFont_otfSize)));
    return wacky;
}

I usually add a method like this to my custom look-and-feel class. They you can get different sizes by doing things like getWackyFont().withHeight (255.0f) etc…

I’m sure there are other patterns that you can use as Typeface::createSystemTypefaceFor() returns a shared Typeface::Ptr.

BTW Watch out for font licenses as many include an exclusion for embedding like this and require a separate (often more costly) license…Slightly different context but there was the My Little Pony case recently…


#5

Regarding the encoding of the font files to the binaryData file you can also use the BinaryBuilder (cf JUCE/extras/binarybuilder). I find it more practical than projucer for that, it makes it easy and fast to update the binaries, and name the binary file as you want

" Usage: BinaryBuilder  sourcedirectory targetdirectory targetclassname [optional wildcard pattern]\n\n"
                     " BinaryBuilder will find all files in the source directory, and encode them\n"
                     " into two files called (targetclassname).cpp and (targetclassname).h, which it\n"
                     " will write into the target directory supplied.\n\n"
                     " Any files in sub-directories of the source directory will be put into the\n"
                     " resultant class, but #ifdef'ed out using the name of the sub-directory (hard to\n"
                     " explain, but obvious when you try it...)\n";

#6

Full example of embedding.
Here’s my FontAwesome wrapper …



#7

Thanks, everyone. It was much easier than I expected. I simply added the .otf file in Projucer, and then added this to my LookAndFeel:

Typeface::Ptr getTypefaceForFont(const Font& f) override
    {
        static Typeface::Ptr myFont = Typeface::createSystemTypefaceFor(BinaryData::uglyFont_otf,
                                                                 BinaryData::uglyFont_otfSize);
        return myFont;
    }

Thanks again, gents.


#8

At some point in the past it was way more complicated :slight_smile:


#9

Yeah, when i said I’d post a guide to how I do it this was pretty much the meat of what I was going to show. When I do it however, I usually add an if/else inside the getTypeFaceForFont function that allows the method to pick the font I actually want (whether it’s an embedded font or existing system font) via Font::getTypefaceName() so I can use multiple fonts if needed instead of blindly returning my typeface (which may be what you want in your case).