This is a story of a rabbit hole, a very deep rabbit hole, and what happens if you jump in head first.
This started as an attempt to reduce a memory leak with variable fonts and FreeType. It ended up with major changes to how variable fonts are handled. The most user forward change is that now the names for named face instances in a variable font are displayed. Matching of named instances is now handled correctly in the GUI. In the Font tab of the Text and Font dialog, only the face name is shown. The CSS string is still available, but in the tooltip. (With variable fonts, the CSS string can be very, very long. The CSS string is actually the result of the pango_font_description_to_string() function.)
This merge request does not change the toolbar style selector to use named faces. That is another rather large project.
Principle changes:
-
Switch the OpenType utilities to use exclusively HarfBuzz.
-
This removes a memory leak for font variations. The function FT_Get_MM_Var takes a ft_face as an argument but matching deletion function FT_Done_MM_Var requires ft_library which we don't have access to.
-
As a benefit of using Harfbuzz, we get the actual names of the variation axes. FreeType gives us the 'tags' in the name field except for the five predefined axes (weight, stretch, ...). This removes the need to rely on a list of tag to name pairs in font-variations.cpp, thus axis names have been removed from the data structure.
-
Font variation axes are now included in the 'font_spec' for a font instance. This allows us to track named instances of variable fonts and include them in the Face (style) list.
-
Switched from <map> to <vector> to track axes. Axes are kept in order as found in font.
-
Store the "tag" and "name" for each axis. The FreeType "name" value, formerly uses as the key in the map, was actually the "tag" value. Tags must be unique within a font. Names are arbitrary.
-
Parametric (hidden axes) now remain hidden in the GUI.
-
"CSS Style" in Text and Font dialog, Font tab, moved to tooltip. With variable fonts, the strings can be very long. (It's not true CSS. For example, CSS only defines the weight key words "normal" and "bold". The weights given in CSS Style are defined by Pango. They are commonly used by font designers but are not standardized.)
-
As CSS now allows for integer weight values from 1 through 1000, inclusive, we don't need to replace Pango's Book, Semi-Light, and Ultra-Heavy values anymore. Also removed switch statement for font weight in style-text.cpp as it's no longer useful.
-
The code was assuming that with a variation font, all style elements are set with variation axes. This is not the case. There is one font, for example, that has different files for the "Regular" and "Italic" versions.
-
Removed unused system_fontspec() from font-lister.h/cpp
-
Removed FontFactory::ConstructFontSpecification(), used only one place for debugging.
-
Moved canonize_fontspec from FontLister class to stand-alone function in font-utils.h/cpp. FontLister is tied to GTK and really should be in src/ui. This move is necessary to keep testing of libnrtype free from GTK dependencies.
-
Added tests for font-utils.h/cpp (canonize_fontspec(), parse_variations()).
Here is a sample of variable fonts that can be used for testing (as seen in the screenshots above). Note, that some of these also have non-variable versions.
- Adwaita Sans
- Amstelvar
- Cascadia Code
- Decover Alpha
- Foldit
- Nabla
- Noto Serif CJK JP (and many but not all Noto fonts)
- Roboto Flex
- Rocher Color
- Vazirmatn



























