Slow TextLayout on OSX with memory-based fonts

Just tried this on 10.12 with some fairly text heavy sections of my application and the time spent rendering reduced significantly
It’d be cool to get the opinion of the JUCE guys to see whether this could be added

Thanks for the tip

Yep, thanks for the heads-up, George, I’ll take a look asap!

1 Like

I saw the fix in the commit 2e0f6b5, but does that mean that memory-based fonts will now render incorrectly below 10.11? george-spitfire stated that OSX versions 10.10 and earlier show garbled text for memory-based fonts. Doesn’t that mean all that removed code would still be needed to support 10.7-10.10.

No, I didn’t remove any code relating to this. I did take the opportunity to rip out a pile of old legacy stuff for 10.5. But the fallback for pre-10.11 memory fonts is still there and older systems should still use it.

1 Like

Hmm unfortunately the fix destroys my tooltips which are using TextLayout and fonts stored in memory. This is using the OSX 10.11 SDK with 10.11 deployment target on a 10.11 machine.
Before the commit:
before

After the commit:
after

I have my font in BinaryData and use LookAndFeel::getTypefaceForFont(…) to override the default fonts. Obviously it is using characters from the font, but the wrong ones.

Everything else in my GUIs seems unaffected, but as far as I know the tooltip window is the only spot a textlayout is used.

Edit:: weirdly enough it looks like all the char codes are just offset by 2 for rendering.

Setting canAllTypefacesBeUsedInLayout (…) to return false fixes my issue, but I can’t do that without patching JUCE.
My font does work correctly on OSX outside Juce and the same code/font does work on windows.
My conclusion is that at least with my configuration the old workaround is still needed even on pure 10.11 and I would very much like to have a way to override the new behaviour with the old one as I have no issues with speed.

Update: I tried running the same thing on 10.13 and there it is displaying correctly. I have no access to 10.12. Anything below 10.11 will use the old workaround and probably work in my case.

1 Like

Anyone else seeing this issue? Maybe it’s just my font that’s somehow weird.

I really wonder what that bug looked like that caused the workaround to be added… was it similar to what I’m seeing?

I just updated to the latest JUCE and have garbled tooltips as well… :frowning:

This is already fixed on develop. See here:

Hot fix will appear on master soon.

2 Likes

Thanks, good to hear! BTW, the bug also affected MacOS 10.13.2 which I´m running. I´ll check out the latest develop.

I have been doing some tests in an attempt to track down where the behavioural discrepancies are arising from by building with various versions of the SDK, running on various versions of OSX and isolating different parts the changes I made. It seems to me that the reason we are observing different behaviour is because I also added some code in my LookAndFeel class which registers the font with the CoreText font manager:

#if JUCE_MAC
bool myLookAndFeel::registerCFTypeface (const char *data, size_t length)
{
    CFDataRef fontData = CFDataCreate (kCFAllocatorDefault, (uint8_t *) data, (CFIndex) length);
    
    if (fontData == nullptr)
        return false;
    
    bool result = false;
    CGDataProviderRef provider = CGDataProviderCreateWithCFData ((CFDataRef) fontData);
    if (CGFontRef font = CGFontCreateWithDataProvider (provider))
    {
        CFErrorRef error;
        result = CTFontManagerRegisterGraphicsFont (font, &error);
        CFRelease (font);
    }
    
    CFRelease (provider);
    CFRelease (fontData);
    
    return result;
}
#endif

If I don’t include this I also see garbled text on OSX 10.11 and 10.12 with both versions of the SDK. With this included the results are as mentioned in my original post (even with the 10.11 version of the SDK) – on OSX 10.11 and above, big layouts will render much faster and will not show garbled text, versions lower than 10.10 are excluded and will go via the old route (slower but still no garbled text).

2 Likes

Thanks George! So we could achieve the same thing just by adding a call to CTFontManagerRegisterGraphicsFont in the OSXTypeface constructor at line 505:

    if (fontRef != nullptr)
    {
        CTFontManagerRegisterGraphicsFont (fontRef, nullptr);

        ctFontRef = CTFontCreateWithGraphicsFont (fontRef, referenceFontSize, nullptr, nullptr);

?

FYI I think this function was the missing piece of the puzzle - rather than checking the OS version number, we can just check the return value of CTFontManagerRegisterGraphicsFont. Will push something to develop shortly and would appreciate feedback on whether it finally fixes this one!

I am pretty sure using that function fixes fallback for unknown characters too.

That would be most excellent

Great, that’ll be a double-whammy!

Jules, I tried the fix you just committed on 10.11.6 and for me it fixes the issue with the font I’m using and textlayouts inside tooltips.

1 Like

We’re still seeing garbled tooltips on the latest develop tip (on at least macOS 10.12) with memory-based fonts, though it seems to occur very infrequently — maybe 10% of the time the plugin is instantiated.

38%20PM

A workaround that worked well for me was using the GlyphArrangement class to create a Path object that draws the text with a custom font. No issues with just drawing the path as opposed to the text.

void paint (Graphics& g) override {
    GlyphArrangement textGlyph;
    Path textPath;

    // The text will be centered within the component
    textGlyph.addLineOfText (someFontToUse, someStringToDisplay,
                             proportionOfWidth(0.5f) - (someStringWidth / 2.0f),
                             proportionOfHeight(0.5f) + (someStringHeight / 2.0f));
    textGlyph.createPath (textPath);
    g.setColour (whateverColourToUse);
    g.fillPath (textPath);
}

This saved about ~20% CPU during animations as well as got rid of any weirdness with rendering memory-based fonts, especially when I took actually creating the Glyph out of paint(). This was only on necessary on Mac for me.

2 Likes

Thanks! This is essentially what we’re doing as a workaround too.