# Candera 3.9

<div class="contents" id="bkmrk-animation-framework-"><div class="contents"><div class="textblock">- **Animation framework immediately applies the value of the first keyframe after the animation is started**:  
    CGI1-38759  
    First key frame value is not applied immediately anymore but at the time the keyframe is defined.
- **Truncation wrong left bearing has been considered**:  
    CGI1-41803  
    Text does not move anymore in x direction when it’s truncated.
- **Performance issue in Node2D::GetWorldTransform()**:  
    CGI1-40883  
    Performance Improvement for GetWorldTransform() function for 2D nodes.
- **ASTC Compression support for OpenGL ES 3.2**:  
    CGI1-42340  
    Support of ASTC compressed textures.

</div></div></div>#### Text Engine Changes

General improvements of the truncation algorithm have been added.

<div class="contents" id="bkmrk-the-default-texture-"><div class="contents"><div class="textblock">- The default texture size of GlyphAtlas textures has been reduced to 512x512. (CGI1-42474 - 10475)
- Information about the fill status of the glyph atlas and its textures can be retrieved now. (CGI1-42576 - 10477)
- Korean line break has changed to western style. (CGI1-42979 - 10500)
- The ignore list for special control character has been reworked. (CGI1-42963 - 10499)
- The CMake flag which enables the locl feature: CANDERA\_TEXTENGINE\_WORLDTYPE\_LOCL\_FEATURE\_ENABLED changed its default value to false. If this feature is required, an additional feature from Monotype is required to make it functional. (CGI1-41591 - 10408)
- The datatype PixelPosition has been changed from Int16 to Int32.
- The truncation algorithm has been stabilized regarding out of memory behavior. This has impact on the return type of the functions   
    PreprocessedGlyphData<span style="color: rgb(35, 111, 161);">\* [Candera::TextRendering::GlyphDataContainer::operator\[\](TextPosition const textPos)](http://dev.doc.cgistudio.at/APILINK/class_candera_1_1_text_rendering_1_1_glyph_data_container.html#a5627090e98ccee9e5ad3e52eea92a734)</span>;  
    bool <span style="color: rgb(35, 111, 161);">[Candera::TextRendering::GlyphDataContainer::AddNew()](http://dev.doc.cgistudio.at/APILINK/class_candera_1_1_text_rendering_1_1_glyph_data_container.html#afa8776dc18a26ecea20569f36f9a867a);</span>  
    bool [<span style="color: rgb(35, 111, 161);">Candera::TextRendering::GlyphDataContainer::AppendInvalidGlyphs(TextPosition const invalidCount)</span>](http://dev.doc.cgistudio.at/APILINK/class_candera_1_1_text_rendering_1_1_glyph_data_container.html#a9bdb37c14234b05dbf7297b83d6f4147); (CGI1-42726 - 10483)
- The Monotype WT-Shaper has been upgraded to version 4.4.0. (CGI1-45481)

</div></div></div>#### Asset loading improvements

Asset loading has been optimized. This includes changes in asset partitioning. (10430, 10443, 10442, 10417)

#### Detailed asset error information and asset initialization

It is possible to receive more detailed information about asset loading failurs now. (10338)

For this reason the [Candera::AssetConfig](http://dev.doc.cgistudio.at/APILINK/class_candera_1_1_asset_config.html "Asset configuration that encapsulates various asset repositories Custom AssetConfig classes can be de...") class has been extended by the interface

Candera::AssetConfig::AssetErrorsInfo \* Candera::AssetConfig::GetAssetErrorsInfoPtr();   
const Candera::AssetConfig::AssetErrorsInfo &amp; Candera::AssetConfig::GetAssetErrorsInfo() const;

This information contains all errors thrown while loading an asset. The different error types are defined in the enumeration Candera::AssetConfig::AssetErrorsInfo::ErrorInfo::Enum.

Additionally, the asset provider can be now tested on whether it is initialized to prevent corrupted access on [Candera::AssetProvider](http://dev.doc.cgistudio.at/APILINK/class_candera_1_1_asset_provider.html "Abstract class providing methods for retrieving objects.") (10468).

<span style="color: rgb(35, 111, 161);">[Candera::AssetProvider::IsInitialized()](http://dev.doc.cgistudio.at/APILINK/class_candera_1_1_asset_provider.html#afcfbcd69ccbb49ffb3e11fcf3d4f3bdc);</span>

#### RTTI support

Different classes have received [Candera](http://dev.doc.cgistudio.at/APILINK/namespace_candera.html "[DataBinding_RefTypeSample]") built-in RTTI system support:

<div class="contents" id="bkmrk-candera%3A%3Agraphicdevi"><div class="contents"><div class="textblock">- Candera::GraphicDeviceUnit and its derivates.
- [Candera::Layouter](http://dev.doc.cgistudio.at/APILINK/class_candera_1_1_layouter.html "A non-zero padding applies space inside the element layout's width and height. The values can be set ...") and its derivates.

</div></div></div>#### Asynchronous canvas text processing

The 3D text type canvas text supports asynchronous processing now.   
It is coupled to the feature of asynchronous text processing of 2D text type [TextNode2D](http://dev.doc.cgistudio.at/APILINK/class_candera_1_1_text_node2_d.html "TextNode2D is a RenderNode that renders text using the attached BitmapBrush effect."). Therefore, the approach is equal. A new property on canvas text enables the asynchronous text processing. This asynchronous text processing can be done asynchronously inside an own worker thread or single threaded but asynchronously scheduled over multiple frames.

The property can be changed in SceneComposer on the canvas text node itself or by code:

<span style="color: rgb(35, 111, 161);">[Candera::CanvasText::SetAsyncPreRenderEnabled(bool val)](http://dev.doc.cgistudio.at/APILINK/class_candera_1_1_canvas_text.html#a7d9c9468abef4330db30a4c1158289b0); </span>  
<span style="color: rgb(35, 111, 161);">[Candera::CanvasText::IsAsyncPreRenderEnabled()](http://dev.doc.cgistudio.at/APILINK/class_candera_1_1_canvas_text.html#a1ecba5ccb95ca7f26240edb8d01d9906); </span>

Asynchronous text rendering has been made more robust the API provides now a callback function which will be called in the render thread as soon as the text processing has finished:

void [Candera::TextRendering::ITextValidationUser::ResyncNodeRenderFinished()](http://dev.doc.cgistudio.at/APILINK/class_candera_1_1_text_rendering_1_1_i_text_validation_user.html#ac374acf0569a54465a225a60e82d92e4)

The TextRenderDispatcher will call this function accordingly.

To support asynchronous text processing in [CanvasText](http://dev.doc.cgistudio.at/APILINK/class_candera_1_1_canvas_text.html "CanvasText represents a text node within a 3D Canvas object."), some classes have been extended:

void [Candera::TextRendering::TextRenderArgs::SetAdditionalShaperOptions(Candera::Globalization::Culture::SharedPointer&amp; culture, Candera::TextRendering::PixelSize outlineWidth)](http://dev.doc.cgistudio.at/APILINK/class_candera_1_1_text_rendering_1_1_text_render_args.html#a82bcaa5e261d761f2e14bc3fdbb8d07b);  
Candera::Globalization::Culture::SharedPointer GetCulture() const;  
Candera::TextRendering::PixelSize [Candera::TextRendering::TextRenderArgs::GetOutlineWidth() const](http://dev.doc.cgistudio.at/APILINK/class_candera_1_1_text_rendering_1_1_text_render_args.html#a144007de43821d0c0ccfc213e7ea938c);  
[Candera::TextRendering::TextSize](http://dev.doc.cgistudio.at/APILINK/class_candera_1_1_text_rendering_1_1_text_size.html "Defines a 2D extent.") [Candera::TextRendering::TextRenderArgs::GetInnerSizeRestriction() const](http://dev.doc.cgistudio.at/APILINK/class_candera_1_1_text_rendering_1_1_text_render_args.html#a2056edc3f11b3ea375cb325d14b3208d);  
void [Candera::TextRendering::TextRenderArgs::SetInnerSizeRestriction(Candera::TextRendering::TextSize const&amp; val)](http://dev.doc.cgistudio.at/APILINK/class_candera_1_1_text_rendering_1_1_text_render_args.html#aa50a64eafc4a584414135a4ce2d563d8);  
void [Candera::TextRendering::TextRenderArgs::SetValidationUser(Candera::TextRendering::ITextValidationUser \* validationUser)](http://dev.doc.cgistudio.at/APILINK/class_candera_1_1_text_rendering_1_1_text_render_args.html#ad2999f5bc4b5069dae70919682bf309a);  
void [Candera::TextRendering::TextRenderArgs::SetAsyncEnabled(bool asyncEnabled)](http://dev.doc.cgistudio.at/APILINK/class_candera_1_1_text_rendering_1_1_text_render_args.html#a79fc8595254b0387f2c3560834a9af9e);

Additionally, it is possible to process the text during general asset scene loading upload time. With this, it is possible to load a 3D scene in background. When the scene has finished loading, the text is already prepared for rendering. This process run does not consider layout. Therefore, another process run during layout might be required. At least, the glyph caches should have its required glyph entries at this point. Rasterization can be skipped then.

The property to enable this feature can be set in SceneComposer on the canvas text node itself or by code:

[Candera::CanvasText::SetPreprocessOnUploadEnabled](http://dev.doc.cgistudio.at/APILINK/class_candera_1_1_canvas_text.html#a5e445950ff1a4416c0088d1bfc7b0109) (bool val);   
[Candera::CanvasText::IsPreprocessOnUploadEnabled](http://dev.doc.cgistudio.at/APILINK/class_candera_1_1_canvas_text.html#abad7507ca1bea0c473fbdcd7536ca42b) ();

#### Canvas text layout invalidation

[CanvasText](http://dev.doc.cgistudio.at/APILINK/class_candera_1_1_canvas_text.html "CanvasText represents a text node within a 3D Canvas object.") supports the possibility to disable and reenable its internal invalidation mechanism. It is possible to toggle the internal layout invalidation which happens inside, too. This is useful for custom layouter implementation as setting a property inside of the layouter code may not trigger layout in the next frame again.

[Candera::CanvasText](http://dev.doc.cgistudio.at/APILINK/class_candera_1_1_canvas_text.html "CanvasText represents a text node within a 3D Canvas object."):: SetLayoutInvalidationEnabled (bool val);   
[Candera::CanvasText](http://dev.doc.cgistudio.at/APILINK/class_candera_1_1_canvas_text.html "CanvasText represents a text node within a 3D Canvas object."):: IsLayoutInvalidationEnabled ();

#### TextNode2D invalidation

[Candera::TextNode2D](http://dev.doc.cgistudio.at/APILINK/class_candera_1_1_text_node2_d.html "TextNode2D is a RenderNode that renders text using the attached BitmapBrush effect.") supports disabling of the invalidation mechanism now.

[Candera::TextNode2D::IsInvalidationEnabled()](http://dev.doc.cgistudio.at/APILINK/class_candera_1_1_text_node2_d.html#ae5683123d7e9b86e004ae8a5c2c24129);   
[Candera::TextNode2D](http://dev.doc.cgistudio.at/APILINK/class_candera_1_1_text_node2_d.html "TextNode2D is a RenderNode that renders text using the attached BitmapBrush effect."):SetInvalidationEnabled(bool val);

#### Animation speedup

It is now possible to increase the speed of an animation for a defined set of milliseconds. bool

[Candera::Animation::AnimationPlayer::Speedup(Float speedFactor, SequenceTimeType durationMs)](http://dev.doc.cgistudio.at/APILINK/group___animation_base.html#gaa6aca74c7e809c27750c9007280189e5);

This speedup can be triggered by an AnimationReqMsg, too.

#### Glyph atlas statistics

It is possible to retrieve statistics of the glyph atlas now (10477). The statistics include how many glyphs are inside the glyph atlas and how much space is occupied inside the texture(s).

The information can be retrieved on a specific glyph atlas texture index or all used textures. The functions can be called on the specific instances of a glyph atlas:

SizeType GetGlyphCount() const;   
SizeType GetGlyphCount(SizeType atlasIndex) const;   
Float GetOccupiedSpace() const;   
Float GetOccupiedSpace(SizeType atlasIndex) const;

With the introduction of this feature, [BitmapAtlas](http://dev.doc.cgistudio.at/APILINK/class_candera_1_1_bitmap_atlas.html "The BitmapAtlas class packs several smaller images into the bitmap of the atlas. It supports padding ...") has been extended by a function to extract the occupied space inside:

UInt GetOccupiedSpaceInTexels() const;

#### Dedicated text properties for text flow direction

[CanvasText](http://dev.doc.cgistudio.at/APILINK/class_candera_1_1_canvas_text.html "CanvasText represents a text node within a 3D Canvas object.") and [TextNode2D](http://dev.doc.cgistudio.at/APILINK/class_candera_1_1_text_node2_d.html "TextNode2D is a RenderNode that renders text using the attached BitmapBrush effect.") support setting the text reading direction explicitly now. This feature can only be set by code for now.

API on [CanvasText](http://dev.doc.cgistudio.at/APILINK/class_candera_1_1_canvas_text.html "CanvasText represents a text node within a 3D Canvas object."):

Candera::TextRendering::BidiBaseLevel::Enum [Candera::CanvasText::GetBidiBaseLevel() const](http://dev.doc.cgistudio.at/APILINK/class_candera_1_1_canvas_text.html#a75ce9e9a4ba25734d0e9beb81e6e278a);   
void [Candera::CanvasText::SetBidiBaseLevel(Candera::TextRendering::BidiBaseLevel::Enum val)](http://dev.doc.cgistudio.at/APILINK/class_candera_1_1_canvas_text.html#a940b98103b2ffd29ed4897f5ffe05960);

API on intermediate text arguments:

Candera::TextRendering::BidiBaseLevel::Enum [Candera::TextRendering::TextRenderArgs::GetBidiBaseLevel() const](http://dev.doc.cgistudio.at/APILINK/class_candera_1_1_text_rendering_1_1_text_render_args.html#a982592caa6c1b19e035bc4163a0e9b9b);   
void [Candera::TextRendering::TextRenderArgs::SetBidiBaseLevel(Candera::TextRendering::BidiBaseLevel::Enum val)](http://dev.doc.cgistudio.at/APILINK/class_candera_1_1_text_rendering_1_1_text_render_args.html#abe860ed742e6f356369624debd290839);

API on [TextNode2D](http://dev.doc.cgistudio.at/APILINK/class_candera_1_1_text_node2_d.html "TextNode2D is a RenderNode that renders text using the attached BitmapBrush effect."):

static Candera::TextRendering::BidiBaseLevel::Enum Candera::TextNode2DLayouter::GetBidiBaseLevel(const TextNode2D&amp; node); static void Candera::TextNode2DLayouter::SetBidiBaseLevel(TextNode2D&amp; node, Candera::TextRendering::BidiBaseLevel::Enum val);

#### Customized font metrics

It is possible to set custom metrics on fonts and styles by code. These metrics replace the automatically calculated ones (CGI1-41735 - 10410). The font metrics used by default are aligned to the bounding boxes of the glyphs inside the font/style. With this feature it is possible to define a specific metric value and keep the exact position of text even if the font or style has changed inside or the position is imported from external tools. It is possible to switch back to automatically calculated metrics.

void [Candera::TextRendering::Style::SetMetrics(Metrics const&amp; newMetrics)](http://dev.doc.cgistudio.at/APILINK/class_candera_1_1_text_rendering_1_1_style.html#a4e50c2fd3c020e64bdcf79b415999c64); void [Candera::TextRendering::Style::SetDefaultMetrics()](http://dev.doc.cgistudio.at/APILINK/class_candera_1_1_text_rendering_1_1_style.html#a736c94b74a5318f09e8a5013b89f48ba);

void Candera::TextRendering::Font::SetMetrics(Metrics const&amp; newMetrics); void [Candera::TextRendering::Font::SetDefaultMetrics()](http://dev.doc.cgistudio.at/APILINK/class_candera_1_1_text_rendering_1_1_font.html#a1a4fbf4009b34d0361886e2771d3b72d);

<span style="color: rgb(34, 34, 34); font-size: 1.666em; font-weight: 400;">Text glyph iterator extension</span>

The glyph iterator interface supports the retrieval of horizontal X bearing now. The derivates have to implement this function to fully support it.

[Candera::TextRendering::PreprocessingContext::GlyphData::GetHorizontalBearingX()](http://dev.doc.cgistudio.at/APILINK/class_candera_1_1_text_rendering_1_1_preprocessing_context_1_1_glyph_data.html#a0649c6e01a8798dccadd606bca894347);

#### RenderTarget DestroyEvent

The typedef Candera::RenderTarget::DestroyEvent has been introduced for better readability and access to destroy events.

#### Usage of Monotype OT caching

In some cases Monotype opentype cache might have used cached data from previous fonts which then leads to wrong opentype table data in use. This has been fixed (CGI1-43094).

#### Specular highlights and spot lights

Reference shaders were calculating half vectors in point and spot light without normalizing them. As a result, the distance from the light to a vertex influenced the result, producing incorrect shading. Reference shaders were updated to correctly normalize half vectors in vertex shader for point and spot lights (CGI1-19781).

#### Layout monitor

The layout monitor communication protocol has been updated. The IDs referencing to nodes are 64-Bit now to fully support 64-Bit systems (CGI1-39844).

#### View invalidation on text invalidation

In case of a text gets invalidated, it will invalidate the courier view in addition to the layout now. This has been introduced into [Candera::TextNode2D](http://dev.doc.cgistudio.at/APILINK/class_candera_1_1_text_node2_d.html "TextNode2D is a RenderNode that renders text using the attached BitmapBrush effect.") and [Candera::CanvasText](http://dev.doc.cgistudio.at/APILINK/class_candera_1_1_canvas_text.html "CanvasText represents a text node within a 3D Canvas object.") (8719).

#### Screenshot tool

The snapshot tool did not fully support features like super sampling when OpenGLES2.0 was used. This has been fixed (CGI1-38463).

#### Text direction when using no shaper

The text direction when using NoShaper sometimes selected the wrong text flow direction for specific glyphs. This has been fixed (CGI1-26302).

#### Analyzer – Frame Debugger

The algorithm to compress a buffer inside of frame debugger monitor has been replaced with a different implementation (CGI1-45320).

#### CanvasSprite Upload strategy

CanvasSprite's default vertex buffer can potentially get uploaded more often than unloaded, causing a crash post-main. This has been fixed (CGI1-33876).

#### CanvasText line intersection

An issue that prevented intersecting lines with valid CanvasTexts was fixed (CGI1-26345).

#### Release method for SharedPointer and EventListener

Design refactoring: SharedPointer and [EventListener](http://dev.doc.cgistudio.at/APILINK/class_candera_1_1_event_listener.html) have both a Release method (CGI1-21916).

#### Redundant mipmap auto generation

Redundant mipmap auto generation in RenderDevice OpenGL ES 1.1 when texture with predefined mipmaps is uploaded. (CGI1-35758)

#### Endianess function template LittleToBigEndian is wrong

LittleToBigEndian conversion is wrong (CGI1-44380).

#### Dirty Area statistics is wrong for scissor operations

Dirty Area statistics broken for platform that support Scissor operations (CGI1-24992)

#### Uniform buffer objects without padding do not work

MaterialBlock and LightBlock shader parsing does not handle padding at struct end correctly in case that there is no padding. Std140 layout says that padding may or may not exist.

#### Data binding has dependency to view availability

Data Binding works only if the model updates when the view is already initialized. If the model updates data binding while the view is not initialized yet, after the view is initialized it cannot access the current data binding message. (CGI1-44499)

#### CanvasSprite is not unloaded when changed to 9-patch

CGI1-33876 Default shared static vertex buffer of [CanvasSprite](http://dev.doc.cgistudio.at/APILINK/class_candera_1_1_canvas_sprite.html) is not unloaded when being changed to 9-patch, thus triggering unloading post-main causing a crash.

#### CMake Build System Changes

New cmake variables were added:

<div class="contents" id="bkmrk-name-description-pos"><div class="contents"><div class="textblock"><table class="doxtable" style="width: 100%;"><tbody><tr><th style="width: 20.7664%;">**Name**</th><th style="width: 59.4599%;">**Description**</th><th style="width: 19.7737%;">**Possible values**</th></tr><tr><td style="width: 20.7664%;">CANDERA\_GLYPHATLAS\_PADDING\_SIZE</td><td style="width: 59.4599%;">Padding size around glyphs in the GlyphAtlas. Value depends on how the glyphs are being rendered. E.g. 4 if reference outline shader is used. 1 if bilinear texturing is used.</td><td style="width: 19.7737%;">4</td></tr><tr><td style="width: 20.7664%;">CANDERA\_TEXTENGINE\_WORLDTYPE\_CLIG\_FEATURE\_ENABLED</td><td style="width: 59.4599%;">Defines whether or not Contextual Ligatures (clig) are enabled. This flag is for wt-shaper only.</td><td style="width: 19.7737%;">ON/OFF (Default: ON)</td></tr><tr><td style="width: 20.7664%;">CANDERA\_TEXTENGINE\_WORLDTYPE\_DLIG\_FEATURE\_ENABLED</td><td style="width: 59.4599%;">Defines whether or not Discretionary Ligatures (dlig) are enabled. This flag is for wt-shaper only.</td><td style="width: 19.7737%;">ON/OFF (Default: ON)</td></tr><tr><td style="width: 20.7664%;">CANDERA\_TEXTENGINE\_WORLDTYPE\_LIGA\_FEATURE\_ENABLED</td><td style="width: 59.4599%;">Defines whether or not Standard Ligatures (liga) are enabled. This flag is for wt-shaper only.</td><td style="width: 19.7737%;">ON/OFF (Default: ON)</td></tr><tr><td style="width: 20.7664%;">CANDERA\_TEXTENGINE\_WORLDTYPE\_LOCL\_FEATURE\_ENABLED</td><td style="width: 59.4599%;">Defines Whether or not Localized Forms (locl) are enabled. The feature requires WT-Shaper 4.3.0 including 136475\_136476.</td><td style="width: 19.7737%;">ON/OFF (Default: ON)</td></tr></tbody></table>

---

</div></div></div>