The two ways to install custom fonts

Edited: what a mess: all the dict, /dict string etc. lines between <> are void, so I removed the opening < for each entry in order to be able to guess what’s happening. Sorry.

Untill a few days ago I though the only way to install custom fonts was to use declares (below).
Then I saw that RL says, " On macOS, you can use ATSApplicationFontsPath key in Info.plist.
And so I implemented ATSApplicationFontsPath (below).

Now I’d like to know which of the two ways might be considered the recommended one.

  1. by Declares (I think suggested by Sam)
    Public Function loadIndicFonts(f as FolderItem) As Boolean
    //f is the full path of the font-location, ex:SpecialFolder.getresource(“myFont.ttf”)
    #if TargetMacOS
    if f <> nil then

    declare function CFURLCreateWithFileSystemPath lib “Cocoa” (allocator as Ptr, filePath as CFStringRef, pathStyle as integer, isDirectory as boolean) as Ptr
    dim CFURLRef as Ptr = CFURLCreateWithFileSystemPath( nil, f.NativePath, 0, false )

    dim fontRegistered as Boolean
    if CFUrlRef <> nil then

     declare function CTFontManagerRegisterFontsForURL lib "Cocoa" ( fontURL as Ptr, scope as Uint32, error as Ptr ) as boolean
     Dim CFErrorRef as Ptr
     
     fontRegistered = CTFontManagerRegisterFontsForURL( CFURLRef, 1, CFErrorRef )
     
     declare sub CFRelease lib "Cocoa" ( ref as ptr )
     CFRelease CFUrlRef
    

    end if
    Return fontRegistered
    end if
    #else
    #Pragma Unused f
    #endif
    End Function

  2. by ATSApplicationFontsPath
    At first I was a little confused because somewhere I read that the entry for the plist was supposed to be something like:
    dict>
    string>Fonts/myfont1 /string>
    /dict>
    In fact it worked. But I had 4 fonts to add, and the following code would load one font only. Even keeping only one dict> at the top and one /dict> at the bottom, or removing .ttf from the font name.
    dict>
    key>ATSApplicationFontsPath /key>
    string>Fonts/NotoSansSyriacEstrangela-Regular.ttf /string>
    /dict>
    dict>
    key>ATSApplicationFontsPath /key>
    string>Fonts/NotoSansSyriacWestern-Regular.ttf /string>
    /dict>
    dict>
    key>ATSApplicationFontsPath /key>
    string>Fonts/NotoSansHebrew-Regular.ttf /string>
    /dict>
    dict>
    key>ATSApplicationFontsPath /key>
    string>Fonts/NotoSansHebrew-Bold.ttf /string>
    /dict>

Same negative results with this snippet (with or without .ttf):
dict>
key>ATSApplicationFontsPath /key>
string>Fonts/NotoSansSyriacEstrangela-Regular.ttf /string>
string>Fonts/NotoSansSyriacWestern-Regular.ttf /string>
string>Fonts/NotoSansHebrew-Regular.ttf /string>
string>Fonts/NotoSansHebrew-Bold.ttf /string>
/dict>

At the end I saw that these few lines were enough (that is, the folder containing the fonts may have any name, and all fonts get loaded without naming them) :
dict>
key>ATSApplicationFontsPath /key>
string>FontsForMac/ /string>
/dict>

So, supposing the last “ATSApplicationFontsPath” procedure is correct, what would be considered the recommended way? Declares or ATSApplicationFontsPath?
Thanks,

Today, I use MBS plugins, but in the past, I have used ATSApplicationFontsPath.

It should be pretty stable, since the same method is used in iOS.

Thank you for sharing your experience.

I don’t quite like “Install” here…

The fonts are not being installed on the OS - they are only available while the application is running. This may even be necessary, depending on the license of your fonts.

On macOS, we have been using the Info.plist way with ATSApplicationFontsPath ever since.

If someone would like to see an example project (which covers macOS, Windows and Linux) - here you are: Custom App Fonts.

2 Likes

Note that FontActivateMBS can make fonts available to the whole system. It could not be called “install”, since the font does not appear in Font Book, but for all intents and purposes, all apps have access to the font.

2 Likes