OSXTypeface destructor improperly unregistering fonts

Here’s an interesting little bug. We have our own implementation of OSXTypeface::scanFolderForFonts() as we need to add a folder of fonts to our process. For those who want to do similar, below is the core of what it’s doing.

The problem is that code was added to the OSXTypeface destructor which calls CTFontManagerUnregisterGraphicsFont() on the font in all cases. However, this should only be called for the fonts created with the OSXTypeface() constructor that takes the block of data for in-memory fonts. Otherwise we have this:

  1. font created with OSXTypeface(const Font& font) where font reference is one added via scanFolderForFonts().

  2. OSXTypeface is destroyed (this happens more easily if TypefaceCache size is set to 1)

  3. future OSXTypeface instances can no longer use the font previously added via scanFolderForFonts.

Thanks for taking a look! And, any reason why Typeface::scanFolderForFonts() isn’t implemented by JUCE?

Rob

void Typeface::scanFolderForFonts (const File& folder)
{
    auto files = folder.findChildFiles(File::findFiles, false, "*.otf;*.ttf");

    for (auto file : files)
    {
        CFURLRef urlref = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, file.getFullPathName().toCFString(), kCFURLPOSIXPathStyle, true);
        if (urlref)
        {
            CTFontManagerRegisterFontsForURL(urlref, kCTFontManagerScopeProcess, NULL);
            CFRelease(urlref);
        }
    }
}

I think this could be fixed by guarding the call to CTFontManagerUnregisterGraphicsFont with

if (dataCopy.getSize() != 0)

which would mean it’s only activated for in-memory fonts. Could you give this a test in your app?

Hi Tom,

I just tried your suggested fix of guarding the call to CTFontManagerUnregisterGraphicsFont with if (dataCopy.getSize() != 0) and can confirm that does work. Please do add that in.

Thanks!

Rob

Thanks for the fix, and for adding in the scanFolderForFonts mac implementation. I also have similar for Windows but it’s a lot more involved. If someone has the bandwidth to integrate it I’d be happy to send it your way.

Rob