class
#include <Magnum/Text/AbstractFont.h>
AbstractFont Base for font plugins.
Provides interface for opening fonts, filling a glyph cache and layouting the glyphs.
Usage
Fonts are most commonly implemented as plugins, which means the concrete font implementation is loaded and instantiated through a PluginManager::
In the following example a font is loaded from the filesystem using the StbTrueTypeFont plugin, prerendering all needed glyphs, completely with all error handling:
PluginManager::Manager<Text::AbstractFont> manager; Containers::Pointer<Text::AbstractFont> font = manager.loadAndInstantiate("StbTrueTypeFont"); if(!font->openFile("font.ttf", 12.0f)) Fatal{} << "Can't open font.ttf with StbTrueTypeFont"; Text::GlyphCacheGL cache{PixelFormat::R8Unorm, Vector2i{128}}; font->fillGlyphCache(cache, "abcdefghijklmnopqrstuvwxyz" "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "0123456789?!:;,. ");
See Loading and using plugins for more information about general plugin usage and the list of derived classes for available font plugins. See GlyphCache for more information about glyph caches and Renderer for information about actual text rendering.
Font size
Font libraries specify font size in points, where 1 pt = ~1.333 px at 96 DPI, so in the above snippet a 12 pt font corresponds to 16 px on a 96 DPI display. The font size corresponds to the height of the EM quad which is defined as the distance between ascent and descent.
Upon opening the font, the size in points is exposed in size(). Derived properties are specified in pixels in lineHeight(), ascent() and descent().
The font size used when opening the font affects how large the glyphs will be when rendered into the GlyphCache. Actual text rendering with Renderer however uses its own font size, and the rendered size is then additionally depending on the actual projection used. This decoupling of font sizes is useful for example in case of DistanceFieldGlyphCache, where a single prerendered glyph size can be used to render arbitrarily large font sizes without becoming blurry or jaggy. When not using a distance field glyph cache, it's usually desirable to have the font size and the actual rendered size match. See the Renderer documentation for further information about picking font sizes.
Loading data from memory, using file callbacks
Besides loading data directly from the filesystem using openFile() like shown above, it's possible to use openData() to import data from memory. Note that the particular importer implementation must support FontFeature::
Utility::Resource rs{"data"}; Containers::ArrayView<const char> data = rs.getRaw("font.ttf"); if(!font->openData(data, 12.0f)) Fatal{} << "Can't open font data with StbTrueTypeFont";
Some font formats consist of more than one file and in that case you may want to intercept those references and load them in a custom way as well. For font plugins that advertise support for this with FontFeature::
struct Data { std::unordered_map<std::string, Containers::Optional< Containers::Array<const char, Utility::Path::MapDeleter>>> files; } data; font->setFileCallback([](const std::string& filename, InputFileCallbackPolicy policy, Data& data) -> Containers::Optional<Containers::ArrayView<const char>> { auto found = data.files.find(filename); /* Discard the memory mapping, if not needed anymore */ if(policy == InputFileCallbackPolicy::Close) { if(found != data.files.end()) data.files.erase(found); return {}; } /* Load if not there yet. If the mapping fails, remember that to not attempt to load the same file again next time. */ if(found == data.files.end()) found = data.files.emplace( filename, Utility::Path::mapRead(filename)).first; if(!found->second) return {}; return Containers::arrayView(*found->second); }, data); font->openFile("magnum-font.conf", 13.0f);
For importers that don't support FontFeature::
The input file callback signature is the same for Text::
Data dependency
The AbstractShaper instances returned from createShaper() have a code and data dependency on the dynamic plugin module — since their implementation is in the plugin module itself, the plugin can't be unloaded until the returned instance is destroyed.
Subclassing
The plugin needs to implement the doFeatures(), doClose(), doCreateShaper() functions, either doCreateGlyphCache() or doFillGlyphCache() and one or more of doOpen*()
functions. See also AbstractShaper for more information.
In order to support FontFeature::
You don't need to do most of the redundant sanity checks, these things are checked by the implementation:
- The doOpenData() and doOpenFile() functions are called after the previous file was closed, doClose() is called only if there is any file opened.
- The doOpenData() is called only if FontFeature::
OpenData is supported. - The doSetFileCallback() function is called only if FontFeature::
FileCallback is supported and there is no file opened. - All
do*()
implementations working on opened file are called only if there is any file opened.
Derived classes
- class FreeTypeFont
- FreeType font plugin.
- class MagnumFont
- Simple bitmap font plugin.
- class StbTrueTypeFont
- TrueType font plugin using stb_truetype.
Public types
- using Feature = FontFeature deprecated in 2020.06
- Features supported by a font implementation.
- using Features = FontFeatures deprecated in 2020.06
- Set of features supported by a font implementation.
Public static functions
-
static auto pluginInterface() -> Containers::
StringView - Plugin interface.
-
static auto pluginSearchPaths() -> Containers::
Array<Containers:: String> - Plugin search paths.
Constructors, destructors, conversion operators
- AbstractFont() explicit
- Default constructor.
-
AbstractFont(PluginManager::
AbstractManager& manager, const Containers:: StringView& plugin) explicit - Plugin manager constructor.
Public functions
- auto features() const -> FontFeatures
- Features supported by this font.
- auto fileCallback() -> auto new in 2019.10
- File opening callback function.
- auto fileCallbackUserData() const -> void* new in 2019.10
- File opening callback user data.
-
void setFileCallback(Containers::
Optional<Containers:: ArrayView<const char>>(*)(const std:: string&, InputFileCallbackPolicy, void*) callback, void* userData = nullptr) new in 2019.10 - Set file opening callback.
-
template<class T>void setFileCallback(Containers::
Optional<Containers:: ArrayView<const char>>(*)(const std:: string&, InputFileCallbackPolicy, T&) callback, T& userData) new in 2019.10 - Set file opening callback.
- auto isOpened() const -> bool
- Whether any file is opened.
-
auto openData(Containers::
ArrayView<const void> data, Float size) -> bool - Open raw data.
-
auto openFile(Containers::
StringView filename, Float size) -> bool - Open a file.
- void close()
- Close currently opened file.
- auto size() const -> Float
- Font size in points.
- auto ascent() const -> Float
- Font ascent in pixels.
- auto descent() const -> Float
- Font descent in pixels.
- auto lineHeight() const -> Float
- Line height in pixels.
- auto glyphCount() const -> UnsignedInt new in Git master
- Total count of glyphs in the font.
- auto glyphId(char32_t character) -> UnsignedInt
- Glyph ID for given character.
-
void glyphIdsInto(const Containers::
StridedArrayView1D<const char32_t>& characters, const Containers:: StridedArrayView1D<UnsignedInt>& glyphs) new in Git master - Glyph IDs for given characters.
-
auto glyphName(UnsignedInt glyph) -> Containers::
String new in Git master - Glyph name.
-
auto glyphForName(Containers::
StringView name) -> UnsignedInt new in Git master - Glyph for given name.
- auto glyphSize(UnsignedInt glyph) -> Vector2 new in Git master
- Glyph size in pixels.
- auto glyphAdvance(UnsignedInt glyph) -> Vector2
- Glyph advance in pixels.
-
auto fillGlyphCache(AbstractGlyphCache& cache,
const Containers::
StridedArrayView1D<const UnsignedInt>& glyphs) -> bool new in Git master - Fill glyph cache with given glyph IDs.
-
auto fillGlyphCache(AbstractGlyphCache& cache,
Containers::
StringView characters) -> bool - Fill glyph cache with given character set.
-
auto createGlyphCache() -> Containers::
Pointer<AbstractGlyphCache> - Create glyph cache.
-
auto createShaper() -> Containers::
Pointer<AbstractShaper> new in Git master - Create an instance of this font shaper implementation.
-
auto layout(const AbstractGlyphCache& cache,
Float size,
Containers::
StringView text) -> Containers:: Pointer<AbstractLayouter> deprecated in Git master - Layout the text using font's own layouter.
Protected types
- struct Properties
- Font properties.
Protected functions
-
auto doOpenFile(Containers::
StringView filename, Float size) -> Properties virtual - Implementation for openFile()
Private functions
- auto doFeatures() const -> FontFeatures pure virtual
- Implementation for features()
-
void doSetFileCallback(Containers::
Optional<Containers:: ArrayView<const char>>(*)(const std:: string&, InputFileCallbackPolicy, void*) callback, void* userData) virtual - Implementation for setFileCallback()
- auto doIsOpened() const -> bool pure virtual
- Implementation for isOpened()
-
auto doOpenData(Containers::
ArrayView<const char> data, Float size) -> Properties virtual - Implementation for openData()
- void doClose() pure virtual
- Implementation for close()
-
void doGlyphIdsInto(const Containers::
StridedArrayView1D<const char32_t>& characters, const Containers:: StridedArrayView1D<UnsignedInt>& glyphs) pure virtual new in Git master - Implementation for glyphIdsInto()
-
auto doGlyphName(UnsignedInt glyph) -> Containers::
String virtual new in Git master - Implementation for glyphName()
-
auto doGlyphForName(Containers::
StringView name) -> UnsignedInt virtual new in Git master - Implementation for glyphForName()
- auto doGlyphSize(UnsignedInt glyph) -> Vector2 pure virtual new in Git master
- Implementation for glyphSize()
- auto doGlyphAdvance(UnsignedInt glyph) -> Vector2 pure virtual
- Implementation for glyphAdvance()
-
auto doFillGlyphCache(AbstractGlyphCache& cache,
const Containers::
StridedArrayView1D<const UnsignedInt>& glyphs) -> bool virtual - Implementation for fillGlyphCache()
-
auto doCreateGlyphCache() -> Containers::
Pointer<AbstractGlyphCache> virtual - Implementation for createGlyphCache()
-
auto doCreateShaper() -> Containers::
Pointer<AbstractShaper> pure virtual new in Git master - Implementation for createShaper()
Typedef documentation
typedef FontFeature Magnum:: Text:: AbstractFont:: Feature
Features supported by a font implementation.
typedef FontFeatures Magnum:: Text:: AbstractFont:: Features
Set of features supported by a font implementation.
Function documentation
static Containers:: StringView Magnum:: Text:: AbstractFont:: pluginInterface()
Plugin interface.
"cz.mosra.magnum.Text.AbstractFont/0.3.7"
static Containers:: Array<Containers:: String> Magnum:: Text:: AbstractFont:: pluginSearchPaths()
Plugin search paths.
Looks into magnum/fonts/
or magnum-d/fonts/
next to the dynamic Trade library, next to the executable and elsewhere according to the rules documented in Corrade::MAGNUM_PLUGINS_DIR
CMake variables, see Downloading and building for more information.
Not defined on platforms without dynamic plugin support.
auto Magnum:: Text:: AbstractFont:: fileCallback() new in 2019.10
File opening callback function.
void* Magnum:: Text:: AbstractFont:: fileCallbackUserData() const new in 2019.10
File opening callback user data.
void Magnum:: Text:: AbstractFont:: setFileCallback(Containers:: Optional<Containers:: ArrayView<const char>>(*)(const std:: string&, InputFileCallbackPolicy, void*) callback,
void* userData = nullptr) new in 2019.10
Set file opening callback.
In case the font plugin supports FontFeature::userData
pointer as input and returns a non-owning view on the loaded data as output or a Corrade::nullptr
can't be used to indicate a failure.
In case the font plugin doesn't support FontFeature::
In case callback
is nullptr
, the current callback (if any) is reset. This function expects that the font plugin supports either FontFeature::
It's expected that this function is called before a file is opened. It's also expected that the loaded data are kept in scope for as long as the font plugin needs them, based on the value of InputFileCallbackPolicy. Documentation of particular importers provides more information about the expected callback behavior.
Following is an example of setting up a file loading callback for fetching compiled-in resources from Corrade::
font->setFileCallback([](const std::string& filename, InputFileCallbackPolicy, void*) { Utility::Resource rs{"data"}; return Containers::optional(rs.getRaw(filename)); });
template<class T>
void Magnum:: Text:: AbstractFont:: setFileCallback(Containers:: Optional<Containers:: ArrayView<const char>>(*)(const std:: string&, InputFileCallbackPolicy, T&) callback,
T& userData) new in 2019.10
Set file opening callback.
Equivalent to calling the above with a lambda wrapper that casts void*
back to T*
and dereferences it in order to pass it to callback
. Example usage — this reuses an existing Corrade::
const Utility::Resource rs{"data"}; font->setFileCallback([](const std::string& filename, InputFileCallbackPolicy, const Utility::Resource& rs) { return Containers::optional(rs.getRaw(filename)); }, rs);
bool Magnum:: Text:: AbstractFont:: openData(Containers:: ArrayView<const void> data,
Float size)
Open raw data.
Parameters | |
---|---|
data | File data |
size | Font size in points |
Closes previous file, if it was opened, and tries to open given raw data. Available only if FontFeature::false
.
bool Magnum:: Text:: AbstractFont:: openFile(Containers:: StringView filename,
Float size)
Open a file.
Parameters | |
---|---|
filename | Font file |
size | Size to open the font in, in points |
Closes previous file, if it was opened, and tries to open given file. On failure prints a message to Error and returns false
. If file loading callbacks are set via setFileCallback() and FontFeature::
void Magnum:: Text:: AbstractFont:: close()
Close currently opened file.
On certain implementations an explicit call to this function when the file is no longer needed but the font instance is going to be reused further may result in freed memory. This call is also done automatically when the font instance gets destructed or when another file is opened. If no file is opened, does nothing. After this function is called, isOpened() is guaranteed to return false
.
Float Magnum:: Text:: AbstractFont:: ascent() const
Font ascent in pixels.
Distance from baseline to top, positive value. Font size is defined as the distance between ascent() and descent(), thus the value of (ascent - descent)*0.75f
(i.e., converted to points) is equal to size(). Expects that a font is opened.
Float Magnum:: Text:: AbstractFont:: descent() const
Font descent in pixels.
Distance from baseline to bottom, negative value. Font size is defined as the distance between ascent() and descent(), thus the value of (ascent - descent)*0.75f
(i.e., converted to points) is equal to size(). Expects that a font is opened.
Float Magnum:: Text:: AbstractFont:: lineHeight() const
Line height in pixels.
Distance between baselines in consecutive text lines that corresponds to ascent() and descent(). Expects that a font is opened.
UnsignedInt Magnum:: Text:: AbstractFont:: glyphCount() const new in Git master
Total count of glyphs in the font.
Expects that a font is opened.
UnsignedInt Magnum:: Text:: AbstractFont:: glyphId(char32_t character)
Glyph ID for given character.
A convenience wrapper around glyphIdsInto() for querying a glyph ID for a single character. Expects that a font is opened.
void Magnum:: Text:: AbstractFont:: glyphIdsInto(const Containers:: StridedArrayView1D<const char32_t>& characters,
const Containers:: StridedArrayView1D<UnsignedInt>& glyphs) new in Git master
Glyph IDs for given characters.
Parameters | |
---|---|
characters in | Input characters |
glyphs out | Output glyph IDs |
Expects that a font is opened and that the characters
and glyphs
views have the same size. The glyph IDs are all guaranteed to be less than glyphCount().
Containers:: String Magnum:: Text:: AbstractFont:: glyphName(UnsignedInt glyph) new in Git master
Glyph name.
Returns a name of the glyph in the font file, if present and supported by the implementation, or an empty string. Expects that a font is opened and glyph
is less than glyphCount().
UnsignedInt Magnum:: Text:: AbstractFont:: glyphForName(Containers:: StringView name) new in Git master
Glyph for given name.
If the implementation supports querying glyphs by name and the name exists, returns a corresponding glyph ID, otherwise returns 0
for an invalid glyph. Note that certain named glyphs can also map to glyph 0
, in particular ".notdef"
in TTF and OTF fonts, the way to distinguish them is to ask for name of the zero glyph and compare. The returned index is guaranteed to be less than glyphCount().
Vector2 Magnum:: Text:: AbstractFont:: glyphSize(UnsignedInt glyph) new in Git master
Glyph size in pixels.
Parameters | |
---|---|
glyph | Glyph ID |
Size of the glyph image in pixels when rasterized. Some implementations may return fractional values, in which case Math::glyph
is less than glyphCount().
Vector2 Magnum:: Text:: AbstractFont:: glyphAdvance(UnsignedInt glyph)
Glyph advance in pixels.
Parameters | |
---|---|
glyph | Glyph ID |
Distance the cursor for the next glyph that follows glyph
. Doesn't consider kerning or any other advanced shaping features. Expects that a font is opened and glyph
is less than glyphCount().
bool Magnum:: Text:: AbstractFont:: fillGlyphCache(AbstractGlyphCache& cache,
const Containers:: StridedArrayView1D<const UnsignedInt>& glyphs) new in Git master
Fill glyph cache with given glyph IDs.
Parameters | |
---|---|
cache | Glyph cache instance |
glyphs | Glyph IDs to render |
Fills the cache with given glyph IDs. Fonts having FontFeature::glyphs
are all unique and less than glyphCount().
On success returns true
. On failure, for example if the cache
doesn't have expected format or the glyphs
can't fit, prints a message to Error and returns false
.
bool Magnum:: Text:: AbstractFont:: fillGlyphCache(AbstractGlyphCache& cache,
Containers:: StringView characters)
Fill glyph cache with given character set.
Parameters | |
---|---|
cache | Glyph cache instance |
characters | UTF-8 characters to render |
Converts characters
to a list of Unicode codepoints, gets glyph IDs for them using glyphIdsInto(), removes duplicates, adds the glyph 0
if the font is not in cache
already, and delegates to fillGlyphCache(AbstractGlyphCache&, const Containers::
Containers:: Pointer<AbstractGlyphCache> Magnum:: Text:: AbstractFont:: createGlyphCache()
Create glyph cache.
Configures and fills glyph cache with the contents of whole font. Available only if FontFeature::
On success returns an instance of a newly created glyph cache. On failure, for example if a file containing glyph cache data cannot be open, prints a message to Error and returns nullptr
.
Containers:: Pointer<AbstractShaper> Magnum:: Text:: AbstractFont:: createShaper() new in Git master
Create an instance of this font shaper implementation.
The returned class can be used to shape text using this font. See its documentation for more information. Note that the font has to stay in scope for as long as any AbstractShaper instances originating from the font exist. Expects that a font is opened. The returned instance is never nullptr
.
Containers:: Pointer<AbstractLayouter> Magnum:: Text:: AbstractFont:: layout(const AbstractGlyphCache& cache,
Float size,
Containers:: StringView text)
Layout the text using font's own layouter.
Parameters | |
---|---|
cache | Glyph cache |
size | Size to layout the text in, in pooints |
text | Text to layout |
Note that the layouters support rendering of single-line text only. See Renderer class for more advanced text layouting. Expects that a font is opened.
Properties Magnum:: Text:: AbstractFont:: doOpenFile(Containers:: StringView filename,
Float size) virtual protected
Implementation for openFile()
If doIsOpened() returns true
after calling this function, it's assumed that opening was successful and the Properties are expected to contain valid values. If doIsOpened() returns false
, the returned values are ignored. If FontFeature::
This function is not called when file callbacks are set through setFileCallback() and FontFeature::
void Magnum:: Text:: AbstractFont:: doSetFileCallback(Containers:: Optional<Containers:: ArrayView<const char>>(*)(const std:: string&, InputFileCallbackPolicy, void*) callback,
void* userData) virtual private
Implementation for setFileCallback()
Useful when the font plugin needs to modify some internal state on callback setup. Default implementation does nothing and this function doesn't need to be implemented — the callback function and user data pointer are available through fileCallback() and fileCallbackUserData().
Properties Magnum:: Text:: AbstractFont:: doOpenData(Containers:: ArrayView<const char> data,
Float size) virtual private
Implementation for openData()
If doIsOpened() returns true
after calling this function, it's assumed that opening was successful and the Properties are expected to contain valid values. If doIsOpened() returns false
, the returned values are ignored.
void Magnum:: Text:: AbstractFont:: doGlyphIdsInto(const Containers:: StridedArrayView1D<const char32_t>& characters,
const Containers:: StridedArrayView1D<UnsignedInt>& glyphs) pure virtual private new in Git master
Implementation for glyphIdsInto()
The implementation is expected to return all glyphs
smaller than glyphCount().
Containers:: String Magnum:: Text:: AbstractFont:: doGlyphName(UnsignedInt glyph) virtual private new in Git master
Implementation for glyphName()
Default implementation returns an empty string.
UnsignedInt Magnum:: Text:: AbstractFont:: doGlyphForName(Containers:: StringView name) virtual private new in Git master
Implementation for glyphForName()
The implementation is expected to return a value smaller than glyphCount(). Default implementation returns 0
.
bool Magnum:: Text:: AbstractFont:: doFillGlyphCache(AbstractGlyphCache& cache,
const Containers:: StridedArrayView1D<const UnsignedInt>& glyphs) virtual private
Implementation for fillGlyphCache()
The glyphs
are guaranteed to be unique and all less than glyphCount().
Containers:: Pointer<AbstractShaper> Magnum:: Text:: AbstractFont:: doCreateShaper() pure virtual private new in Git master
Implementation for createShaper()
This function is only called if the font is opened. The implementation is not allowed to return nullptr
.