LookAndFeel, Custom Fonts, Linux Leaks

Hello,

Sorry for the long post, but I’m having a hard time trying to figure out some issues I have with LookAndFeel. It seems like I’m not the only one, so I guess we need some kind of updated info on how to properly use and set the look and feel for plugins.
I also upgraded to JUCE 7 and I’m on the development branch.

We started porting some of our plugins to Linux and noticed that they are leaking the GlyphInfo class, which I suppose is related to the custom fonts implementation I’m using. macOS and Windows are not leaking, just Linux.

This is what we are doing right now, in PluginProcessor.h I have the following code before the actual AudioProcessor class (which I believe was suggested by Jules a few years ago):

struct MainLookAndFeel
{
    MainLookAndFeel()  { LookAndFeel::setDefaultLookAndFeel (&lnf);    }
    ~MainLookAndFeel() { LookAndFeel::setDefaultLookAndFeel (nullptr); }
    
    MyLookAndFeel lnf;
};

Then as a member of AudioProcessor, I have:

SharedResourcePointer<MainLookAndFeel> mainLookAndFeel;

And this was enough for all my needs, using also custom fonts this way:

    static const juce::Typeface::Ptr getOpenSansRegular()
    {
        static auto typeface = juce::Typeface::createSystemTypefaceFor (BinaryData::OpenSansRegular_ttf,
                                                                        BinaryData::OpenSansRegular_ttfSize);
        return typeface;
    }
    static const juce::Typeface::Ptr getOpenSansBold()
    {
        static auto typeface = juce::Typeface::createSystemTypefaceFor (BinaryData::OpenSansBold_ttf,
                                                                        BinaryData::OpenSansBold_ttfSize);
        return typeface;
    }
    
    juce::Typeface::Ptr getTypefaceForFont (const juce::Font& font) override
    {
        if (font.getStyleFlags() == juce::Font::bold)
        {
            return getOpenSansBold();
        }
        
        return getOpenSansRegular();
    }

So, again, macOS and Windows are perfectly fine with this, but Linux is leaking GlyphInfo. If I remove the custom fonts, I see no leaks on Linux.
I also tried to replace the SharedResourcePointer with a std::unique_ptr but I get the same issues.

So I created a new plugin with nothing but a custom LookAndFeel to test a few implementations and discovered another issue related to this thread.
If I’m using setDefaultLookAndFeel my popups call getParentComponentForMenuOptions on my LookAndFeel class and they open as I want. Instead, if I’m just using setLookAndFeel on the popup object, getParentComponentForMenuOptions in my LookAndFeel is NOT called, and popups open with default behavior.

So, to recap:

  • what’s the proper way of implementing and using custom LookAndFeel with custom fonts in plugins?
  • how can I avoid the leaking of GlyphInfo on Linux if I want to use custom fonts?
  • is it safe to use setDefaultLookAndFeel for plugins? if not, there’s something wrong going on as getParentComponentForMenuOptions in my LookAndFeel is not called when using setLookAndFeel on popups.
1 Like

Bump.

This is the project I’ve used to test a few things, and it leaks GlyphInfo on Linux.

VanillaTest.zip (161.7 KB)

static auto getOpenSansRegular() {
  static auto result = juce::Typeface::createSystemTypefaceFor (...);
  return result;
}

Here, result will have static storage duration, so it won’t be cleaned up until after the leaked-object-checker runs. If you want to avoid the leaked object warning, you could either just get rid of the static at function scope altogether, or you could store your cached fonts in your own singleton (use JUCE_DECLARE_SINGLETON and inherit from DeletedAtShutdown).

Yes, I think so.

Thank you for your reply.

Ok but it doesn’t leak on macOS and Windows, and making it non-static means the font is loaded everytime is requested, which doesn’t seem to be a good idea? What’s the most efficient way of implementing custom embed fonts in a plugin then?

Ok, still, I think something’s wrong when we don’t use setDefaultLookAndFeel and just use setLookAndFeel on popups, the getParentComponentForMenuOptions in our look and feel is NOT called (and as far as i know, it was called in earlier versions of JUCE 6).

Those platforms have their own typeface implementations, and don’t create GlyphInfo instances.

I can’t say without profiling. If creating fonts on demand causes performance issues in your plugin, then you could try caching the fonts in a singleton, as I suggested above.

That looks like a regression, I’ll get that fixed.

Thank you for the explanation! I also have this problem and now I finally understand why!

That’s fixed here:

Thanks for reporting!

Thanks for the fix! Does this fix the popupmenu background bug related to this post BUG? Popup Menu Background and Logic Silicon - #29 by lcapozzi ?

No, the pink menu backgrounds visible in Logic are mandatory and cannot be disabled.