Overwriting getTypefaceForFont() not works when LF is set for component

We share some components like preset browsers and want to ensure they look the same in all plugins. Because of this, we set custom LookAndFeel classes for those components.

We overwrite the getTypefaceForFont as follows to return custom embedded fonts:

    Typeface::Ptr getTypefaceForFont(Font const& font) override
    {
        juce::String faceName (font.getTypefaceName());

        if (faceName == "myFont")
        {
          return Typeface::createSystemTypefaceFor(BinaryData::font_ttf, BinaryData::font_ttfSize);
...

We set the LookAndFeel on the parent component as follows:

setLookAndFeel(_talLookAndFeel.get());

This works as expected for colors and overwritten component drawing methods. But it does not work for the fonts when overriding getTypefaceForFont(). It only works when we set the DefaultLookAndFeel like this:

LookAndFeel::setDefaultLookAndFeel(_talLookAndFeel.get());

But here we set the typefaces globally. I also like to move away from static singletons in our plugin code and avoid dependencies between plug-in instances.

Is there something I can do? Any Ideas?

Looks like following code in the juce::LookAndFeel class is the source of that behavior:

static Typeface::Ptr getTypefaceForFontFromLookAndFeel (const Font& font)
{
    return LookAndFeel::getDefaultLookAndFeel().getTypefaceForFont (font);
}

using GetTypefaceForFont = Typeface::Ptr (*)(const Font&);
extern GetTypefaceForFont juce_getTypefaceForFont;

//==============================================================================
LookAndFeel::LookAndFeel()
{
    /* if this fails it means you're trying to create a LookAndFeel object before
       the static Colours have been initialised. That ain't gonna work. It probably
       means that you're using a static LookAndFeel object and that your compiler has
       decided to initialise it before the Colours class.
    */
    jassert (Colours::white == Colour (0xffffffff));

    juce_getTypefaceForFont = getTypefaceForFontFromLookAndFeel;
}

It’s not clear to me how I can replace juce_getTypefaceForFont in the constructor point to my nonstatic getTypefaceForFont() method at the moment. I will try a few things but at first sight, it looks like this needs to be static and that is exactly what I don’t want…

Please JUCE team, can you refactor this and remove the singleton behavior for this method?

I know that the typeface cache is static and this makes sense, but how getTypefaceForFont() is used is a design problem and misleading. I would expect that getTypefaceForFont() of the Component LookAndFeel is used and not the one from the DefaultLookAndFeel.

2 Likes

I also ran into this problem recently, and I agree it should work differently.

2 Likes