Ramses Text API
-
using FontId = StronglyTypedValue<uint32_t, std::numeric_limits<uint32_t>::max(), FontIdTag>
A strongly typed integer to distinguish between different fonts.
-
using FontInstanceId = StronglyTypedValue<uint32_t, std::numeric_limits<uint32_t>::max(), FontInstanceIdTag>
A strongly typed integer to distinguish between different font instances.
-
StringBoundingBox GetBoundingBoxForString(GlyphMetricsVector::const_iterator first, GlyphMetricsVector::const_iterator last)
Compute a bounding box for a string represented by a range of GlyphMetrics.
- Parameters:
first – [in] Beginning of range of GlyphMetrics to compute bounding box
last – [in] End of range of GlyphMetrics to compute bounding box, glyph pointed to by last is not included
- Returns:
The bounding box of the provided string, or bounding box of Zero values on failure
-
StringBoundingBox GetBoundingBoxForString(const GlyphMetricsVector::const_reverse_iterator &first, const GlyphMetricsVector::const_reverse_iterator &last)
Compute a bounding box for a string represented by a range of GlyphMetrics.
- Parameters:
first – [in] Beginning of range of GlyphMetrics to compute bounding box
last – [in] End of range of GlyphMetrics to compute bounding box, glyph pointed to by last is not included
- Returns:
The bounding box of the provided string, or bounding box of Zero values on failure
-
struct FontCascade
- #include <FontCascade.h>
struct to define a font cascade
Allows to define a list of fonts that are tried sequentially for character availability. The first font that supports a given character is returned. Also supports generic fallback characters and blacklisted characters.
Public Members
-
const IFontAccessor &fontAccessor
interface to use to resolve FontInstanceId to a FontInstance
-
std::u32string charsToRemove
String of characters that will be removed from a processed string.
-
OrderedFontList fontPriorityList
Ordered list of font instance ids to try for each character.
-
FontInstanceId fallbackFont
Fallback font used for fallbackChar when none in fontPriorityList matched.
-
char32_t fallbackChar
Fallback character when no match was found in fontPriorityList.
Public Static Functions
-
static std::u32string FilterAndFindFontInstancesForString(const FontCascade &fontCascade, const std::u32string &str, FontInstanceOffsets &fontOffsets)
Process a character string according to given FontCascade.
Creates a string with characters removed or replaced according to given FontInstance. Additionally creates FontInstanceOffsets specifying the font instance to use for all returned characters. Intended to be used in conjunction with TextCache::getPositionedGlyphs.
- Parameters:
fontCascade – [in] the font cascade used to process str
str – [in] the character string to process
fontOffsets – [out] vector of FontOffset describing the font to use
- Returns:
The processed string
-
const IFontAccessor &fontAccessor
-
struct FontInstanceIdTag
- #include <FontInstanceId.h>
An empty struct to make FontInstanceId a strong type.
-
struct FontInstanceOffset
- #include <FontInstanceOffsets.h>
A list of tuples from font instances and offsets into a string.
Used to tell the text API which font should be used for which substring when creating glyphs for a string. The list is used as this: take entry N of the list, start at string offset ‘N:beginOffset’ and use font ‘N:fontInstance’ until offset ‘N+1:beginOffset’.
Public Members
-
FontInstanceId fontInstance
Font instance to use starting at this offset.
-
std::size_t beginOffset
Offset into string where to start.
-
FontInstanceId fontInstance
-
class FontRegistry : public ramses::IFontAccessor
- #include <FontRegistry.h>
Font registry can be used to load Freetype2 fonts and create font instances (optionally with Harfbuzz). These are owned and managed by FontRegistry.
Public Functions
-
FontRegistry()
Constructor for FontRegistry.
-
~FontRegistry() override
Destructor for FontRegistry. Destroys all created fonts.
-
virtual IFontInstance *getFontInstance(FontInstanceId fontInstanceId) const override
Get font instance object corresponding to given id.
- Parameters:
fontInstanceId – [in] The id of font instance
- Returns:
The font instance object, nullptr if not found
-
FontId createFreetype2Font(std::string_view fontPath)
Load Freetype2 font from file.
- Parameters:
fontPath – [in] The file path to the font
- Returns:
The font id, FontId::Invalid() on error
-
FontId createFreetype2FontFromFileDescriptor(int fd, size_t offset, size_t length)
Load Freetype2 font from an open file descriptor.
The font file must be in the already opened filedescriptor at absolute position offset within the file. The filedescriptor must be opened for read access and may not be modified anymore after this call. The filedescriptor must support seeking. Ramses takes ownership of the filedescriptor and will close it when not needed anymore.
The behavior is undefined if the filedescriptor does not contain a complete and valid font at offset.
- Parameters:
fd – [in] Open and readable filedescriptor.
offset – [in] Absolute starting position of the font data within fd.
length – [in] Size of the font data within fd.
- Returns:
The font id, FontId::Invalid() on error
-
FontInstanceId createFreetype2FontInstance(FontId fontId, uint32_t size, bool forceAutohinting = false)
Create Freetype2 font instance.
- Parameters:
fontId – [in] The id of the font from which to create a font instance
size – [in] Size (height in rasterized texels of glyphs) of the font
forceAutohinting – [in] Force autohinting (a flag for FT2 library)
- Returns:
The font instance id, FontInstanceId::Invalid() on error
-
FontInstanceId createFreetype2FontInstanceWithHarfBuzz(FontId fontId, uint32_t size, bool forceAutohinting = false)
Create Freetype2 font instance with Harfbuzz shaping.
- Parameters:
fontId – [in] The id of the font from which to create a font instance
size – [in] Size (in rasterized texels of glyphs) of the font
forceAutohinting – [in] Force autohinting (a flag for FT2 library)
- Returns:
The font instance id, FontInstanceId::Invalid() on error
-
bool deleteFont(FontId fontId)
Delete an existing font.
- Parameters:
fontId – [in] The id of the font to be deleted
- Returns:
True on success, false otherwise
-
bool deleteFontInstance(FontInstanceId fontInstance)
Delete an existing font instance.
- Parameters:
fontInstance – [in] The id of the font instance to be deleted
- Returns:
True on success, false otherwise
-
FontRegistry(const FontRegistry &other) = delete
Deleted copy constructor.
- Parameters:
other – unused
-
FontRegistry &operator=(const FontRegistry &other) = delete
Deleted copy assignment.
- Parameters:
other – unused
- Returns:
unused
Public Members
-
class internal::FontRegistryImpl &impl
Stores internal data for implementation specifics of FontRegistry.
-
FontRegistry()
-
struct GlyphKey
- #include <Glyph.h>
GlyphKey identifies a glyph with a specific font instance.
Public Functions
-
inline GlyphKey(GlyphId _identifier, FontInstanceId _fontInstanceId)
Constructor for GlyphKey that initializes members to passed values.
- Parameters:
_identifier – [in] The glyph id
_fontInstanceId – [in] The font instance id
-
inline GlyphKey(GlyphId _identifier, FontInstanceId _fontInstanceId)
-
struct GlyphMetrics
- #include <GlyphMetrics.h>
GlyphMetrics describes a glyph’s position and dimensions in the rasterized glyph bitmap space.
Width and height are the pixel dimensions of the glyph - must match the pixel data of the glyph provided by its corresponding font instance. GlyphKey uniquely identifies the glyph by referencing its origin character and font instance. The posX/posY values are local pixel values in the coordinate system of the text line. The advance value is the local advance (see Freetype2 docs) for each glyph.
-
class IFontAccessor
- #include <IFontAccessor.h>
Interface for getting font instances using font instance ids.
This interface allows overriding the standard Freetype/Harfbuzz logic to create and access fonts and e.g. replace with other implementations, or just override behavior/settings. Can be also used to pre-load font instances and a predefined set of glyphs statically (or load from file).
Subclassed by ramses::FontRegistry
Public Functions
-
virtual ~IFontAccessor() = default
Empty destructor.
-
virtual IFontInstance *getFontInstance(FontInstanceId fontInstanceId) const = 0
Gets a font instance object using font instance id.
- Parameters:
fontInstanceId – [in] The id of font instance
- Returns:
The font instance object
-
virtual ~IFontAccessor() = default
-
class IFontInstance
- #include <IFontInstance.h>
Interface for font instance that can be used to query glyph metadata and bitmaps.
Public Functions
-
virtual ~IFontInstance() = default
Empty destructor.
-
virtual bool supportsCharacter(char32_t character) const = 0
Check if font instance supports a char using it’s UTF32 char code and cache the result.
- Parameters:
character – [in] The UTF32 char code of the character
- Returns:
True if the character is supported, false otherwise
-
virtual std::unordered_set<char32_t> getAllSupportedCharacters() = 0
Get all characters that are supported (mapped to a glyph) by IFontInstance.
- Returns:
set with all supported UTF32 char codes
-
virtual int getHeight() const = 0
Get the line height of the font instance.
- Returns:
Line height (in rasterized texels of glyphs)
-
virtual int getAscender() const = 0
Get the line ascender of the font instance (see Freetype2 docs)
- Returns:
Line ascender (in rasterized texels of glyphs)
-
virtual int getDescender() const = 0
Get the line descender of the font instance (see Freetype2 docs)
- Returns:
Line descender (in rasterized texels of glyphs)
-
virtual void loadAndAppendGlyphMetrics(std::u32string::const_iterator charsBegin, std::u32string::const_iterator charsEnd, GlyphMetricsVector &positionedGlyphs) = 0
Load the glyphs metrics for all characters in a string and appends them to the provided vector of GLYPHS.
- Parameters:
charsBegin – [in] Iterator for the beginning of characters from UTF32 string that should be loaded
charsEnd – [in] Iterator for the end of characters from UTF32 string that should be loaded
positionedGlyphs – [out] Vector of glyphs to which newly loaded glyph metrics are appended
-
virtual GlyphData loadGlyphBitmapData(GlyphId glyphId, uint32_t &sizeX, uint32_t &sizeY) = 0
Load the glyph data for a specific glyph id.
- Parameters:
glyphId – [in] Id of glyph for which to load data
sizeX – [out] Width of glyph data
sizeY – [out] Height of glyph data
- Returns:
The glyph data if glyphId is found, or empty glyph data otherwise
-
virtual ~IFontInstance() = default
-
struct StringBoundingBox
- #include <LayoutUtils.h>
Helper data structure describing multiple glyphs metrics.
StringBoundingBox is essentially a union of a set of GlyphMetrics. It describes a bounding box of renderable glyphs (glyphs with non-empty bitmap data). Width and height are dimensions of the bounding box. The bounding box can be offset from origin using offsetX/Y. Combined advance is X axis offset from origin where next StringBoundingBox would be if put on same line. Similarly to GlyphMetrics, even when StringBoundingBox have zero width/height (which means there is no renderable data) it can still have non-zero advance which should be taken into account by other StringBoundingBox if combined.
-
class TextCache
- #include <TextCache.h>
Stores text data - texture atlas, meshes, glyph bitmap data. It is a cache because the content can be re-generated when necessary, e.g. when cached glyphs take up too much memory.
The TextCache class keeps hold of following data:
The texture atlas pages (array of textures) which holds the glyph bitmaps for different glyphs
The scene objects which represent a “text line” - an array of sized and positioned characters
The TextCache uses IFontAccessor (provided in constructor) to obtain glyph data for various fonts but has otherwise no dependencies to fonts - it treats glyphs as a simple bitmap image placed in one of the texture atlas pages.
The scene objects created for each texture atlas page with glyphs is:
A 2D texture with a single channel (intensity of text pixel)
A texture sampler with bilinear filtering (to blur out edges)
The scene objects created for each text line are:
a Geometry with Vertex/Index arrays (holding a list of quads for each glyph in the text line)
an Appearance (based off the effect provided in createTextLine()). The appearance will have it’s semantic texture sampler pointing to the texture atlas page where the text line’s glyphs are located
a MeshNode which holds above objects together for rendering
It’s important to note that the Appearance of each TextLine has a reference to the texture page holding its glyph data, and the Geometry has links to the texture quad data generated by TextCache. We highly recommend not to tamper with these objects, unless you have in-depth understanding of how text rendering works and know what you are doing. However, setting custom uniforms in the Appearance is valid, as long as you are not touching the semantic texture sampler which was provided when creating the text line.
The TextCache has a limitation that all characters of a TextLine must fit in one (empty) texture atlas page. This means that if a TextCache was created with size 16x16 and a TextLine with single glyph of size 32 is created, the call to createTextLine() will fail because it can’t fit a single glyph in a texture atlas page - it’s too small. Therefore, pay special attention to the size of TextCache and the size of text rendered. If you want to optimize memory usage across different and wildly heterogeneous text sizes, it’s suggested to use multiple TextCache instances with different sizes if in order to avoid inefficient memory partitioning.
To understand better how TextCache internally works, consider following case. You create a TextCache with size 20x20. You use a latin font with uniform character size 10x10 for all letters. You can thus only create TextLine’s with a maximum of 4 letters. If you create two lines with size 4 which use the same 4 characters, the TextCache will create a single texture page and use the glyphs for both lines. If you create two lines with different, but partially overlapping characters, like this: line1 = ‘ABC’ line2 = ‘AXY’
the TextCache will not be able to create a page with all 5 characters (A, B, C, X and Y) and will need to create two pages. The first page will put the letters ‘ABC’ in one page which will have one empty slot. The second line will not fit in the first page, so the TextCache will create a second page and put the characters ‘AXY’ there. Note that the character ‘A’ will be in in both pages, so that each line can be rendered with a single draw call using exactly one mesh and one texture. One may argue that copying glyphs across different pages is bad, but trying to implement a TextCache which creates multiple MeshNodes and partitions them in the worst case across all texture pages quickly leads to the awareness that it’s much better to just forbid it and sacriface a bit of memory in favor of much simpler implementation.
The above limitation ensures that each TextLine receives exactly one MeshNode which makes the rendering setup much easier. However, it requires that multi-language texts with large amount of glyphs may result in suboptimal texture atlas layout. This memory overhead can be overcome by either using a texture atlas size large enough to hold any text line or implementing a more sophisticated partitioning of TextLine’s to ensure atlas pages are filled proportionally.
Finally, the TextLine object holds pointers to the original vector of glyphs which were used to create it. Be careful to not tamper with it, as it is used when destroying the text line to obtain information which glyphs can be freed.
Public Functions
-
TextCache(Scene &scene, IFontAccessor &fontAccessor, uint32_t atlasTextureWidth, uint32_t atlasTextureHeight)
Constructor for text cache.
Choose carefully the size of the atlas textures. Too small will prevent creation of larger strings, because not all of the glyphs will fit on a single page. Too large pages take up more memory than actually needed.
- Parameters:
scene – [in] Scene to use when creating meshes from string glyphs.
fontAccessor – [in] Font accessor to be used for getting font instance objects
atlasTextureWidth – [in] Width for the texture atlas that gets created to store glyphs
atlasTextureHeight – [in] Height for the texture atlas that gets created to store glyphs
-
~TextCache()
Destructor for text cache that cleans up any objects created using the text cache. The scene object passed to the text cache constructor must be still valid at the time of the text cache destruction.
-
GlyphMetricsVector getPositionedGlyphs(const std::u32string &str, FontInstanceId font)
Create and get glyph metrics for a string using a font instance.
Use this call to obtain glyph metadata - positions, sizes, language and font origin (contained in GlyphKey). You can change the positions if you need to, e.g. if you need to do funky things like re-aligning glyphs coming from different fonts with incompatible baselines. But in the regular case, you just pass the glyphs to createTextLine() as-is.
- Parameters:
str – [in] The string for which to create glyph metrics
font – [in] Id of the font instance to be used for creating the glyph metrics vector. The font instance must be available at the font accessor passed in the constructor of the text cache.
- Returns:
The glyph metrics vector created
-
GlyphMetricsVector getPositionedGlyphs(const std::u32string &str, const FontInstanceOffsets &fontOffsets)
Create and get glyph metrics for a string using a list of font instances and offsets.
Use this version of getPositionedGlyphs if you need more fine-grained control over how glyphs are resolved from multiple fonts. See also documentation of FontInstanceOffset.
- Parameters:
str – [in] The string for which to create glyph metrics
fontOffsets – [in] The font offsets created from font cascade to be used for creating the glyph metrics vector. The font instances within the font cascade must all be available at the font accessor passed in the constructor of the text cache. Also see docs of FontInstanceOffsets
- Returns:
The glyph metrics created
-
TextLineId createTextLine(const GlyphMetricsVector &glyphs, const Effect &effect)
Create the scene objects, e.g., mesh and appearance…etc, needed for rendering a text line (represented by glyph metrics). If the provided string of glyphs contains no render-able characters (e.g. it has only white spaces), the method will fail with an error. If you want to avoid having such errors, filter out the
glyphs
with no visual representation (e.g. control characters) and use the helper method ContainsRenderableGlyphs on top to check if the remaining glyphs contain at least one renderable (size not zero) glyph so they can be used as input for createTextLine.This method will always produce exactly one MeshNode. We do this by enforcing that all glyphs are rendered in the same texture atlas page, thus making it possible to create one mesh instead of several. The effect argument has special requirements - it needs to have three semantic uniforms:
EEffectAttributeSemantic::TextTexture - this is where TextCache will link the texture atlas page with glyph data
EEffectAttributeSemantic::TextPositions - this is where the text quad vertices are linked
EEffectAttributeSemantic::TextTextureCoordinates - this is where texture coordinates are linked
- Parameters:
glyphs – [in] The glyph metrics for which to create a text line
effect – [in] The effect used for creating the appearance of the text line and rendering the meshes
- Returns:
Id of the text line created
-
TextLine const *getTextLine(TextLineId textId) const
Get a const pointer to a (previously created) text line object.
- Parameters:
textId – [in] Id of the text line object to get
- Returns:
A pointer to the text line object, or nullptr on failure
-
TextLine *getTextLine(TextLineId textId)
Get a (non-const) pointer to a (previously created) text line object.
- Parameters:
textId – [in] Id of the text line object to get
- Returns:
A pointer to the text line object, or nullptr on failure
-
bool deleteTextLine(TextLineId textId)
Delete an existing text line object.
- Parameters:
textId – [in] Id of the text line object to delete
- Returns:
True on success, false otherwise
Public Members
Public Static Functions
-
static bool ContainsRenderableGlyphs(const GlyphMetricsVector &glyphMetrics)
Check if provided GlyphMetricsVector contains at least one renderable glyph If this functions returns false, the provided input cannot be used as input for the function createTextLine. The function call will simply fail.
- Parameters:
glyphMetrics – [in] GlyphMetrics to be checked @ return True if the provided vector contains at least one renderable glyph
-
static void ApplyTrackingToGlyphs(GlyphMetricsVector &glyphMetrics, int32_t trackingFactor, int32_t fontSize)
Apply character tracking (positive or negative) to each glyph in provided GlyphMetricsVector. This means that that the space between the individual glyphs can be increased (positive tracking) or decreased (negative tracking). The tracking factor is calculated in em, so it’s relative to the font size (1/1000 of font size in pixels). So having a tracking factor of 1000 and a font size of 10 would result in an extra of 10 pixels space between every glyph (1000/1000 * 10 = 10px). Overdoing the negative tracking is not advised, as the glyphs will then potentially be printed on top of each other. This helper function should only be used on Latin fonts as for all other font types this kind of tracking may lead to unexpected visual output.
- Parameters:
glyphMetrics – [in] GlyphMetrics that get tracking applied on
trackingFactor – [in] factor of tracking intensity (higher –> bigger tracking effect)
fontSize – [in] size of the font that contains the glyphs to be tracked
-
struct TextLine
- #include <TextLine.h>
Groups the scene objects needed to render a text line.
Public Members
-
std::size_t atlasPage = std::numeric_limits<std::size_t>::max()
Index to the atlas page containing the glyphs.
-
GlyphMetricsVector glyphs
Glyph metrics of the original string characters.
-
ArrayBuffer *positions = nullptr
Stores vertex data for the text line quads.
-
ArrayBuffer *textureCoordinates = nullptr
Stores texture coordinate data for the text line quads.
-
ArrayBuffer *indices = nullptr
Stores index data for the text line quads.
-
std::size_t atlasPage = std::numeric_limits<std::size_t>::max()
-
struct ExtractedUnicodePoint
- #include <UtfUtils.h>
Stores an extracted Unicode/UTF32 code-point and corresponding meta-data resulting from the conversion to Unicode (see also UtfUtils)
Public Members
-
bool extractionSuccessful
true if the extraction was successful. Otherwise: false and codePoint is undefined
-
uint32_t codePoint
The unicode-point storing the unique id of a character (UTF32)
-
size_t inputCharsConsumed
Stores how many input characters were read to resolve the unicode point (bytes in UTF8 case and words in UTF16 case)
-
bool extractionSuccessful