RAMSES Documentation  27.0.130
Information for RAMSES users and developers
Public Member Functions | Static Public Member Functions | Public Attributes | List of all members
ramses::TextCache Class Reference

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. More...

#include <TextCache.h>

Public Member Functions

 TextCache (Scene &scene, IFontAccessor &fontAccessor, uint32_t atlasTextureWidth, uint32_t atlasTextureHeight)
 Constructor for text cache. More...
 
 ~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. More...
 
GlyphMetricsVector getPositionedGlyphs (const std::u32string &str, FontInstanceId font)
 Create and get glyph metrics for a string using a font instance. More...
 
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. More...
 
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. More...
 
TextLine const * getTextLine (TextLineId textId) const
 Get a const pointer to a (previously created) text line object. More...
 
TextLinegetTextLine (TextLineId textId)
 Get a (non-const) pointer to a (previously created) text line object. More...
 
bool deleteTextLine (TextLineId textId)
 Delete an existing text line object. More...
 
 TextCache (const TextCache &other)=delete
 Deleted copy constructor. More...
 
TextCacheoperator= (const TextCache &other)=delete
 Deleted copy assignment. More...
 

Static Public Member 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. More...
 
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. More...
 

Public Attributes

class TextCacheImpl * impl
 

Detailed Description

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 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:

The scene objects created for each text line are:

It's important to note that the Appearance of each TextLine has a reference to the texture page holding its glyph data, and the GeometryBinding 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.

Examples
ramses-example-text-basic/src/main.cpp, and ramses-example-text-languages/src/main.cpp.

Constructor & Destructor Documentation

◆ TextCache() [1/2]

ramses::TextCache::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
[in]sceneScene to use when creating meshes from string glyphs.
[in]fontAccessorFont accessor to be used for getting font instance objects
[in]atlasTextureWidthWidth for the texture atlas that gets created to store glyphs
[in]atlasTextureHeightHeight for the texture atlas that gets created to store glyphs

◆ ~TextCache()

ramses::TextCache::~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.

◆ TextCache() [2/2]

ramses::TextCache::TextCache ( const TextCache other)
delete

Deleted copy constructor.

Parameters
otherunused

Member Function Documentation

◆ ApplyTrackingToGlyphs()

static void ramses::TextCache::ApplyTrackingToGlyphs ( GlyphMetricsVector glyphMetrics,
int32_t  trackingFactor,
int32_t  fontSize 
)
static

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
[in]glyphMetricsGlyphMetrics that get tracking applied on
[in]trackingFactorfactor of tracking intensity (higher --> bigger tracking effect)
[in]fontSizesize of the font that contains the glyphs to be tracked
Examples
ramses-example-text-basic/src/main.cpp.

◆ ContainsRenderableGlyphs()

static bool ramses::TextCache::ContainsRenderableGlyphs ( const GlyphMetricsVector glyphMetrics)
static

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
[in]glyphMetricsGlyphMetrics to be checked @ return True if the provided vector contains at least one renderable glyph

◆ createTextLine()

TextLineId ramses::TextCache::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:

Parameters
[in]glyphsThe glyph metrics for which to create a text line
[in]effectThe effect used for creating the appearance of the text line and rendering the meshes
Returns
Id of the text line created
Examples
ramses-example-text-basic/src/main.cpp, and ramses-example-text-languages/src/main.cpp.

◆ deleteTextLine()

bool ramses::TextCache::deleteTextLine ( TextLineId  textId)

Delete an existing text line object.

Parameters
[in]textIdId of the text line object to delete
Returns
True on success, false otherwise

◆ getPositionedGlyphs() [1/2]

GlyphMetricsVector ramses::TextCache::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
[in]strThe string for which to create glyph metrics
[in]fontOffsetsThe 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

◆ getPositionedGlyphs() [2/2]

GlyphMetricsVector ramses::TextCache::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
[in]strThe string for which to create glyph metrics
[in]fontId 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
Examples
ramses-example-text-basic/src/main.cpp, and ramses-example-text-languages/src/main.cpp.

◆ getTextLine() [1/2]

TextLine* ramses::TextCache::getTextLine ( TextLineId  textId)

Get a (non-const) pointer to a (previously created) text line object.

Parameters
[in]textIdId of the text line object to get
Returns
A pointer to the text line object, or nullptr on failure

◆ getTextLine() [2/2]

TextLine const* ramses::TextCache::getTextLine ( TextLineId  textId) const

Get a const pointer to a (previously created) text line object.

Parameters
[in]textIdId of the text line object to get
Returns
A pointer to the text line object, or nullptr on failure
Examples
ramses-example-text-basic/src/main.cpp, and ramses-example-text-languages/src/main.cpp.

◆ operator=()

TextCache& ramses::TextCache::operator= ( const TextCache other)
delete

Deleted copy assignment.

Parameters
otherunused
Returns
unused

Member Data Documentation

◆ impl

class TextCacheImpl* ramses::TextCache::impl

Stores internal data for implementation specifics of TextCache.


The documentation for this class was generated from the following file: