gfx/system_font.h
Finding a typeface on the machine the plugin is running on.
#include <sonore/gfx/system_font.h>- 6other declarations
- Guides: The native editor
On this page
Design notes
Why the SDK ships no font
Embedding one would guarantee identical text everywhere, which is the same argument that produced the software rasteriser, and it is a genuinely good argument. It loses to two others.
A font is 150 KB to 400 KB in every plugin binary, and this SDK's whole case against the webview is weight. And every font worth embedding carries a licence -- SIL OFL, Apache -- whose terms have to be honoured by a commercial product that generates thousands of plugins. That is a decision for whoever owns the business, not a default the SDK should make quietly.
So: look for one that is already there. A plugin that needs guaranteed text -- a specific face, a specific language -- supplies its own bytes to Typeface::load and never calls this.
What happens when nothing is found
The controls still work. Font handles an invalid typeface by drawing nothing, so a knob is still a knob and a slider still drags; only the labels are missing. That is a degraded interface rather than a broken one, and it says so through Font::isValid() rather than pretending.
Functions 6
- fn
inline std::vector<uint8_t> readFileBytes(const char* path)Reads a whole file, or an empty vector.gfx::readFileBytes · system_font.h:59 - fn
inline std::shared_ptr<Typeface> loadTypefaceFile(const char* path)A typeface read from a font file, mapped rather than copied into memory where the system allows; null when the file cannot be read or is not a font this can read.gfx::loadTypefaceFile · system_font.h:142More
The file must stay as it is while the typeface lives: one truncated by another program, or on a disk that goes away, faults when the typeface next reads it (SIGBUS, or an in-page error on Windows) -- the system's fonts do not change under a running program, and a plugin's own font sits in its bundle. A file that may change, or that lives on removable media, is better read into memory and given to Typeface::load.
- fn
inline std::shared_ptr<Typeface> systemTypeface()The first readable typeface from the usual places, or null.gfx::systemTypeface · system_font.h:172More
Ordered by how much a UI-shaped face is wanted rather than by what is most likely present: Segoe UI before Arial on Windows, DejaVu before FreeSans on Linux. A plugin's labels look better in the face the desktop uses for its own.
Cached, because a host opens and closes an editor repeatedly and parsing a 4000-glyph font each time would be visible.
- fn
inline size_t fallbackFacesRead()How many fallback face files have been read so far, whether or not they parsed -- what a character has cost in file reads and memory. For a test, or for a plugin that wants to know.gfx::fallbackFacesRead · system_font.h:301 - fn
inline std::shared_ptr<Typeface> fallbackTypeface(uint32_t codepoint)A typeface on this machine with a glyph forcodepoint, or null.gfx::fallbackTypeface · system_font.h:334More
The face a plugin draws with covers the scripts its designer had in mind; a preset a user named in Japanese, a sample folder in Korean, a file browser listing anything at all, does not ask. Without a fallback each of those characters drew as the empty .notdef box. These are the faces the desktop itself falls back to.
Each is asked only about the scripts it is there for -- Hangul goes to the Korean face, kana and Han to the Japanese and then the Chinese ones, Thai to Leelawadee -- and read the first time a character in those scripts needs it. The first version asked every face in turn and kept each one it read: one Thai letter or one newer emoji in a preset name loaded every CJK face on the way past, 47 to 87 MB held for the life of the process, in every plugin. A face listed for no script in particular may be asked about any character, and only small ones are: a character nothing covers costs those few MB once, and is then remembered as a miss. A face that does not parse is passed over.
[main-thread], though locked: a host may run two editors on two threads.
- fn
inline std::shared_ptr<Typeface> emojiTypeface()The system's colour emoji face, or null: Segoe UI Emoji on Windows, Apple Color Emoji on macOS, Noto Color Emoji on Linux -- what Font draws an emoji from, in colour, wherever its text asks for an emoji's look. Read the first time one does, mapped, and kept; a face whose colour this cannot draw -- COLR version 1 alone -- is passed over.gfx::emojiTypeface · system_font.h:426More
[main-thread], though locked, as fallbackTypeface.