Embedded Fonts

gui
projucer

#1

I’m having a bit of trouble embedding fonts in my app (totally forgot to put time into this before an app release, and now my app isn’t displaying my font on user systems - understandably so).

I’ve searched and followed all the posts available on the subject, but am still having issues. I’d like to be to add the embedded font to labels already present in my app that we’re created and layed out via a ProJucer GUI component.

What I’ve done so far:

  1. Added the font to my ProJucer session so that it gets added to BinaryData

  2. Created a class I called “EmbeddedFont:”

    #include “…/JuceLibraryCode/JuceHeader.h”

    class EmbeddedFonts
    {
    private:
    Font calistoMT;

    public:
    EmbeddedFonts();
    Font& getCalistoMT();
    };

and

EmbeddedFonts::EmbeddedFonts()
{
    calistoMT = Font(Typeface::createSystemTypefaceFor(BinaryData::Calisto_MT,
                                                       BinaryData::Calisto_MTSize));
}

Font& EmbeddedFonts::getCalistoMT()
{
    return calistoMT;
}
  1. Made an instance of this in the header of my GUI component class
  2. Tried passing this font to the label font:

genericLabelName->setFont(embeddedFont.getCalistoMT());

This is where I get an assertion:

jassert (typefaceName.isNotEmpty());

Not really sure what to do from here. Also, after I get the embedded font to work, is there anything specific I should be doing to the font field in the projucer GUI component? Should I just set it to the same font? I only ask because I will technically be setting the font twice in the constructor (once from the GUI Component option drop-down menu and once from hand coding the embedded font).

I’ve tried this for a few days and still am having trouble. Thanks for any help. This is the last thing I need to do before releasing my next app update, so any assistance is greatly appreciated.


#2

I hit a problem like this before. The reason for me was because the font file itself was malformed and the name of the font wasn’t stored in it.

From my experience, you are supposed to initialize your font like this:

Struct CalistoFont {
    CalistoFont() {
        Typeface::ptr ptr = Typeface::createSystemTypefaceFor(BinaryData::Calisto_MT, BinaryData::Calisto_MTSize);
        font = Font(ptr);
    }
    Font font;
};

You might experiment with using a SharedResourcePointer instead of a class instance, so it’s static throughout your app.


#3

Thank you for the code example. I’ll give this a try in a bit tonight and see if I can get it to work.


#4

Hmmm, I seem to be getting the exact same assertion with the example code you provided… will continue to work on it though.


#5

Still have not been able to successfully embed fonts in my apps. Anyone have a step-by-step guide for those of us who can’t figure this out? Thank you.


#6

Try this:

Add your font to the project in Projucer.
Create a custom LookAndFeel and override getTypefaceForFont():

class FooLAF    : public LookAndFeel_V3
{
public:
	FooLAF()
	{
		setColour(TextButton::textColourOnId, Colour(0xFFFF0000));
		setColour(TextButton::textColourOffId, Colour(0xFF00FFFF));
		setColour(TextButton::buttonColourId, Colour(0xFF444444));
		setColour(Label::textColourId, Colour(0xFFFFFF00));
	}
	~FooLAF(){}
	
	Typeface::Ptr getTypefaceForFont(const Font& f) override
	{
		static Typeface::Ptr myFont = Typeface::createSystemTypefaceFor(BinaryData::GGX88LtRegular_otf,BinaryData::GGX88LtRegular_otfSize);
		return myFont;
	}
};

Add your custom LookAndFeel to your main component:

class MainContentComponent   : public Component
{
public:
    MainContentComponent();
    ~MainContentComponent();

    void paint (Graphics&) override;
    void resized() override;

	TextButton button;
	Label label;
	FooLAF laf;
private:
    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MainContentComponent)
};

And finally, in your top level component, set the look and feel. I’m not sure why, but just calling setLookAndFeel(&laf); cascades correctly down to all child components, but does not change the font. But, calling FooLAF::setDefaultLookAndFeel(&laf); does work correctly and changes the font for everything.

MainContentComponent::MainContentComponent()
{
    setSize (600, 400);

	// this works correctly, setting the colors and font
	FooLAF::setDefaultLookAndFeel(&laf);
	
	// this only sets the colors, not the font
//	setLookAndFeel(&laf);
	
	label.setText("These should be using your font", dontSendNotification);
	label.setBounds(10, 20, 200, 30);
	addAndMakeVisible(label);

	button.setClickingTogglesState(true);
	button.setButtonText("Push me");
	button.setBounds(10, 55, 200, 30);
	addAndMakeVisible(button);
}

Hope that helps.


#7

Thank you very much for the detailed instructions, I will dig into this and reply back here when done.