Request: get system font (typeface name + size)

I’d like to get the system typeface (Segoe UI/Tahoma/San Francisco, or user defined) and metrics (size, etc). I poured through the SystemStats and Font docs and couldn’t find anything to do this - could this functionality please be added? For those of us trying to make our apps look at least somewhat native, it would be really handy.

I’m thinking the API would look something as simple as static Font Font::getSystemFont().

2 Likes

Bump since I’d like some JUCE team input on this, perhaps this functionality is tucked away somewhere unexpected?

1 Like

+1…

20 words

1 Like

Bumping this again…
With all the feature additions going on this feels like an opportune time!

1 Like

What’s a system font expected to be, exactly? Is this something provided by the operating system (some kind of default font?), or conjured up in JUCE?

If I understood correctly, isn’t this a matter of writing a simple static function that checks the OS and version as provided by SystemStats::getOperatingSystemType, and returns the Font most widely used in the OS?

When I say “system font” I mean the default font used by the OS for message boxes, menus, etc. Examples being the Sogoe UI typeface at 10pt on Windows Vista+, San Francisco typeface at 10pt on macOS 10.11+ (and Helvetica Neue typeface on earlier versions).

What you suggest works “well enough” in most cases, but since it’s possible to change the system font typeface and size it’s not really applicable if you’re trying to make your LookAndFeel fit in nicely with the rest of the system.

In the end I’ve written my own implementation of this for Windows and macOS via the SystemParametersInfo method in the Windows API and NSFont methods in Cocoa and plan on releasing them once I test them in OS versions other than the ones I use for development.

1 Like

Hm, that may be a bit tricky to get dynamically for Linux, and maybe less so Android. Curious to see what you have going on.

Yeah, I’m planning on skipping Android and Linux and just returning JUCE’s default Font() for those platforms since platform-wide appearance uniformity is already practically nonexistent (or at the very least can vary widely system to system, for better or worse) on those platforms.

There’s already some hairiness/hackiness going on with what I have so far in that the font pixel height is calculated based on the DPI of the main display - system fonts tend to use point sizes, so I’m doing conversions from that and they don’t always look right if the user is running multiple displays with different DPIs (but that may be viewed as a tradeoff on their part).

I did a bit of research and Android provides Typeface.DEFAULT (amongst other Java APIs). Is that along the lines of what you’re looking for? Mind you, based on your latest description, I don’t have a clear picture of the goal now.

Thanks for the info. Part of my reluctance with Android is Java/C++ bridging (which I have no experience with) so perhaps whenever I release what I have now for macOS/Windows/iOS someone can add that in.

Also, re: my goal being unclear, it’s simple: a static method which returns a JUCE Font object which contains the typeface name, size (in pixels, the height metric used by JUCE fonts), and style (usually plain, i.e. not bold/italic/whatever) for the “average” font used throughout the OS for standard native GUI elements like labels, button text, etc. Sorry if I wandered a bit in my last post.

1 Like

so perhaps whenever I release what I have now for macOS/Windows/iOS someone can add that in.

+1

When you post the code up, I’ll take this as an opportunity to learn JUCE’s Android bridging system. I’ve done this sort of thing with a game engine: it’s definitely a tedious pain in the arse!

I’ll try to clean it up and get it up ASAP then! :grinning:

1 Like

For you and anyone else here who’s interested: here’s the repo. The methods in question are NTLookAndFeel::getSystemFont() and NTLookAndFeel::getSmallSystemFont(). Currently, they work for Windows, macOS, and iOS. More platforms welcome, just add the platform specific .cpp files!

I currently have some other projects in my pipeline so anything past cleaning the code in this repo up just enough to be pushed into the public (with a focus on getting the system font calls working) has been pushed back, so treat everything in it as heavily WIP and experimental.

3 Likes

I recently wanted to load the system font from macOS and I achieved this with:

LookAndFeel::getDefaultLookAndFeel().setDefaultSansSerifTypefaceName ("System Font");

Before this, I was incorrectly loading my local user copy of Apple’s “SF Pro Text” (downloaded from Apple’s website) using the following:

LookAndFeel::getDefaultLookAndFeel().setDefaultSansSerifTypefaceName ("SF Pro Text");

The problem with the latter is that the font would not load on computers where the user had not downloaded it from Apple’s website. Additionally, from what I understand, Apple’s font licenses for these “San Francisco” system fonts do not permit developers to embed the font files in their apps.

But, the former solution of using “System Font” seems to work decently well.
When I compared this to loading my local user copy of “SF Pro Text”, I noticed the kerning was a bit tighter than expected and the Y alignment was down by 1 pixel. To fix this, for my Font declarations, I add a bit of kerning to match:

font.setExtraKerningFactor (0.0408f);

And whenever I draw text, I just translate it back up 1 pixel:

void paint (juce::Graphics & g) override
{
    // . . .
    g.drawText ("Some Text", textBounds.translated (0, -1), juce::Justification::centred);
}

After the kerning and Y-alignment fix, requesting the “System Font” works/looks proper for me on macOS Mojave, High Sierra, and Monterey.