# General Concepts

This chapter provides a set of subchapters about the general concepts used in CGI Studio.

# 9-patch image

#### <a class="anchor" id="bkmrk--7"></a>Description

The 4-slice scaling technique has been around in desktop graphics software for some years already and is well known to users of Flash and Illustrator. It's a brilliant technique for scaling images by dividing them using 5 slices into sections that have a fixed size (the corners) and sections that are flexible (the edges and the center). There are many names in use for this technique: 9-slice-sprite, 9-slice-scaling, 9-patch-bitmap.

The following image shows the 9 patches areas of an image using different colors:

<div drawio-diagram="1362"><img src="https://doc316en.candera.eu/uploads/images/drawio/2023-02/drawing-4-1676531182.png" alt="drawing-4-1676531182.png"/></div>

<div class="contents" id="bkmrk--0"><div class="contents"><div class="textblock"><div class="image">  
</div></div></div></div>The basic rules are that the corners will not scale at all, the edges will only scale in their respective direction and the center will scale in all directions.

The green area usually is the content area and the other 8 areas are the border areas. It will be clear why the center area is named content area when we show a few example applications of 9-patch images.

#### <a class="anchor" id="bkmrk--9"></a>Examples

<div drawio-diagram="1363"><img src="https://doc316en.candera.eu/uploads/images/drawio/2023-02/drawing-4-1676531205.png" alt="drawing-4-1676531205.png"/></div>

<div class="contents" id="bkmrk--2"><div class="contents"><div class="textblock"><div class="image">  
</div></div></div></div>The images are very often used as background in controls like buttons for example. The big advantage is the low amount of memory needed. It is only necessary to store a small minimum version of the image and it can be reused in many different sizes without losing too much of its quality.

9-patch is mainly used for controls, if you have a text field or a button you can basically stretch it infinitely, but you want certain areas to not stretch like the borders so that in the visual sense it will look much better.

In a layouter (Overlay, Grid…), the 9-patch images will still have the same rules even if the Size properties of the layouter are changed. Using layouters to control the size of a node/control 9-patch images are very often the best way to adapt nodes/controls dynamically to the required space, which is then, adapted to the 9-patch-image as expected.

For BitmapNode sample of the 9-patch click <span style="color:rgb(230,126,35);">[here](https://doc316en.candera.eu/books/candera/page/9-patch-image)</span>.

#### <a class="anchor" id="bkmrk--11"></a>Configuration and special properties

Because not all images are suitable for use as 9-patch-images SceneComposer allows the user to classify an imported bitmap as 9-patch-images using the bitmap properties. To configure the 9-patch, when a bitmap is selected from the Solution Explorer, in the Properties window, in Bitmap section, Bitmap Layout property must be set to NinePatch. If an image is a classified 9-patch-image, 4 additional properties are available. These properties define where the slices are going through the bitmap. For every slice the distance in pixel from the border has to be specified resulting in:

<div class="contents" id="bkmrk-top-border-left-bord"><div class="contents"><div class="textblock">- Top-Border
- Left-Border
- Right-Border
- Bottom-Border

</div></div></div><div drawio-diagram="1365"><img src="https://doc316en.candera.eu/uploads/images/drawio/2023-02/drawing-4-1676531224.png" alt="drawing-4-1676531224.png"/></div>

<div class="contents" id="bkmrk--4"><div class="contents"><div class="textblock"><div class="image">  
</div><dl class="note"><dt></dt><dd></dd></dl></div></div></div><p class="callout info">When using an image as a nine-patch image you should disable bilinear filtering (within the BitmapBrushBlend effect for example) by setting the bitmaps filter property to NearestFilter. This is necessary to have sharp borders between the 9 patches.</p>

<div drawio-diagram="1369"><img src="https://doc316en.candera.eu/uploads/images/drawio/2023-02/drawing-4-1676531320.png" alt="drawing-4-1676531320.png"/></div>

<p class="callout info">When using 9-patch-images on a BitmapNode or inside a control changing the size of the node or control will stretch the image as described above. The scale property of a node/control will be applied as an additional step AFTER adapting the image to the size of the node/control!</p>

<p class="callout info">Scale properties X and Y will scale the whole image and don’t have unscaled areas. 9-patch does not work with the Scale properties, but with the Size properties X and Y. To scale an image with the 9-patch rules, in the node Properties window, in Layout section, changing the values X and Y from Size property will stretch the image according to 9-patch.</p>

<p class="callout info">If the Size properties X or Y is smaller than the sum of the borders (9-patch Stretchable Area: Left, Top, Right and Bottom), then the borders themselves will also start scaling down.</p>

# Dynamic List

#### <a class="anchor" id="bkmrk--30"></a>Overview and characteristics

<div class="contents" id="bkmrk-the-size-of-the-list"><div class="contents"><div class="contents"><div class="textblock">- The size of the list exceeds the limit to process/render all items in the view or just not known at design time in SceneComposer.
- The view sees the list items only as a fragment/subset of the original list.
- The items in the model may be inhomogeneous. In this case special behavior have to switch the presentation of the item in the view corresponding to the provided item data.
- The items in the view have homogeneous size.
- The list model is bound via [Courier](http://dev.doc.cgistudio.at/APILINK/namespace_courier.html) databinding.
- The list model has to be implemented in the [Courier](http://dev.doc.cgistudio.at/APILINK/namespace_courier.html) Model Component.
- The list view is generic. This means the list does not require to implement a specific data structure for the item data. Only a generic base class is required which can be achieved by a simple flag in data description XML file.
- (also for static list) The list view allows horizontal/vertical lists
- (also for static list) The list view allows to swipe (scrolling/ moving the list while touching and moving the finger slowly) / flick (fast move of the finger and releasing the touch screen result is an automatic scrolling of the list for a specified duration and a velocity that epends on the speed of the flick) the list by touch.
- (also for static list) The list view positioning is decoupled from the list view itself. This enables a customizable list navigation (e.g. scrollbar/sidebar)
- The list view requests a list fragment from the model
- The list model provides this list fragment (subset of the list at the requested start index and a specified buffer size). It has to be filled with data from external data sources (e.g. CAN bus or blutooth).
- The list model can provide a default list fragment to the view component before any specific view is loaded (can be done asynchronously if the model is deployed in a separate thread). This enables the view scene to immediately show the list content without the need to request the fragment first.
- The list view items can again be bound by [Courier](http://dev.doc.cgistudio.at/APILINK/namespace_courier.html) data binding to specific data items in special binding sources for data items. Those binding sources have to be marked in XML (dataContextItem="true").

</div></div></div></div>#### <a class="anchor" id="bkmrk--31"></a>Create a list in a binding source (all samples are included in cgi\_studio\_player)

<div class="contents" id="bkmrk-first-of-all-create-"><div class="contents"><div class="contents"><div class="textblock">- First of all create a new binding source or reuse an existing. ```
    <bindingSource name="SampleBindingSource" access="asynchronous" uid="{5fb25ecc-8223-42b5-8f00-edce8fe042f3}">
    </bindingSource>
    ```
- This binding source does not yet provide a list. Hence, we have to add a list item to that binding source. ```
    <bindingSource name="SampleBindingSource" access="asynchronous" uid="{5fb25ecc-8223-42b5-8f00-edce8fe042f3}">
        <list name="SampleList" uid="{1241d345-07af-46ec-b0cd-90a687c56140}" />
    </bindingSource>
    ```
- By default this list will be able to support any fragment size that is requested. Hence, the fragment has not a fixed size capacity but a dynamically growing capacity. This implies the use of allocating memory with different block sizes. 
    - By providing the windowSize attribute for the list item you can easily define a list fragment with a fixed capacity. This implies that the fragment is not able to be larger than the capacity specified by windowSize (for the sample we did not use a fixed capacity). ```
            <list name="SampleList" windowSize="30"  uid="{1241d345-07af-46ec-b0cd-90a687c56140}" />
        ```
    - In addition you can also define a complete list of a fixed size by providing the attribute maxCount. If both attributes are provided the attribute maxCount will be ignored and a list fragment will be used. ```
        <list name="SampleList" maxCount="100" uid="{1241d345-07af-46ec-b0cd-90a687c56140}" />
        ```
- At this point we are already able to define the list binding itself in SceneComposer.

</div></div></div></div>#### <a class="anchor" id="bkmrk--32"></a>Create the List view binding to the list data model

<div class="contents" id="bkmrk-hence%2C-we-create-a-n"><div class="contents"><div class="contents"><div class="textblock">1. Drag the List control from the toolbox to the Scene Tree.  
    <div drawio-diagram="6584"><img src="https://doc316en.candera.eu/uploads/images/drawio/2024-08/drawing-4-1724408382.png" alt="drawing-4-1724408382.png"/></div>
2. Define the size of the List Control (e.g., 400x280). If the size is undefined, the list will be infinite in size and display as many items as you set.  
    
    - At this point, the List will not display any content because the items have not yet been set.  
        <div drawio-diagram="6583"><img src="https://doc316en.candera.eu/uploads/images/drawio/2024-08/drawing-4-1724408303.png" alt="drawing-4-1724408303.png"/></div>
3. Before defining Binding, the binding source for the application must be set. Each application must have a central XML file (like cgi\_studio\_player) that references all included XML files (it is also the starting point for the code generator). 
    - See <span style="color:rgb(230,126,35);">[here](https://doc316en.candera.eu/books/courier/page/courier-editor)</span> for Binding source configuration instructions .
    - In CGI Studio 3.6.0, you must close and reopen the solution to reload the Data Binding.
        
        <div drawio-diagram="6582"><img src="https://doc316en.candera.eu/uploads/images/drawio/2024-08/drawing-4-1724408255.png" alt="drawing-4-1724408255.png"/></div>
4. Next, set the List bindings. Press the white bind button on the right side of the List Control's properties “Control &gt; Items” to display the \[ Define Data Bindings \] dialog. 
    - From Data Items, select the target data and press the \[ OK \] button.  
        <div drawio-diagram="6581"><img src="https://doc316en.candera.eu/uploads/images/drawio/2024-08/drawing-4-1724408128.png" alt="drawing-4-1724408128.png"/></div>
5. When the Data Binding operation is completed, the Bind button in the Properties panel turns blue. Also, when you mouse over the bind button, the current binding item is displayed in a tooltip. 
    - For more information on displaying the bind button, click <span style="color:rgb(230,126,35);">[here](https://doc316en.candera.eu/books/scene-design/page/databinding-ui).</span>  
        <div drawio-diagram="6580"><img src="https://doc316en.candera.eu/uploads/images/drawio/2024-08/drawing-4-1724407985.png" alt="drawing-4-1724407985.png"/></div>

</div></div></div></div><div class="contents" id="bkmrk-hover-again-over-thi"><div class="contents"><div class="contents">  
</div></div></div><div class="contents" id="bkmrk--9"><div class="contents"><div class="textblock">  
</div></div></div>#### <a class="anchor" id="bkmrk--43"></a>Create the binding source for the list item

<div class="contents" id="bkmrk-since-we-have-not-ye"><div class="contents"><div class="textblock">- Since we have not yet defined how the data items will look like we have to go back to the data binding description in the XML file and add a new binding source for the list item itself. ```
    <bindingSource name="SampleListEntry" access="asynchronous" uid="{86f39d72-8d42-43eb-87e7-475cdf384734}">
    </bindingSource>
    ```
- To mark it as a binding source that can be used as a list item we have to enable the attribute dataContextItem. DataContext items are a more generic concept in CGI Studio that can be used to define scene node local data context containing one or more local binding sources. The list item is an example that uses this concept to enable the binding of view list item properties to list data items. ```
    <bindingSource name="SampleListEntry" access="asynchronous" dataContextItem="true" uid="{86f39d72-8d42-43eb-87e7-475cdf384734}">
    </bindingSource>
    ```
- Now we have to add some data items to that binding source. ```
    <bindingSource name="SampleListEntry" access="asynchronous" dataContextItem="true" uid="{86f39d72-8d42-43eb-87e7-475cdf384734}">
        <item name="UInt64Value" type="FeatStd::UInt64" uid="{5cb01d1b-9b9b-4982-99b2-4c82a4823d16}" />
        <item name="FloatValue" type="FeatStd::Float" uid="{7a55879f-0a01-41bf-9d96-d3048280b79f}" />
    ```

</div></div></div>#### <a class="anchor" id="bkmrk--44"></a>Create the List item view binding to the list item data model

After defining the List item structure, set up the Bindings in Scene Composer.

1. First, Nodes for the List item are required. Drag a Stack Layout node from the Node 2D section of the Toolbox to the Scene Tree and rename it "Item\_1".  
    <div drawio-diagram="6579"><img src="https://doc316en.candera.eu/uploads/images/drawio/2024-08/drawing-4-1724407887.png" alt="drawing-4-1724407887.png"/></div>
2. Next, drag a <span style="color:rgb(230,126,35);">[Text Value Control ](https://doc316en.candera.eu/link/1157#bkmrk-text-value)</span>and a <span style="color:rgb(230,126,35);">[Slider Control](https://doc316en.candera.eu/link/1156#bkmrk-slider)</span> onto that stack node. In addition, change the "Format Text" property of Text Value to “Item %05d”.

- In the Scene Editor, the text "Item" should be followed by the number that binds to the UInt64 data binding item you just added.  
    <div drawio-diagram="6637"><img src="https://doc316en.candera.eu/uploads/images/drawio/2024-08/drawing-4-1724668014.png" alt="drawing-4-1724668014.png"/></div>
- Add a little margin to the top, bottom, left and right of the Slider Control.  
    <div drawio-diagram="6577"><img src="https://doc316en.candera.eu/uploads/images/drawio/2024-08/drawing-4-1724407657.png" alt="drawing-4-1724407657.png"/></div>
- Bind the Value property of the Text Value Control to */SampleListEntry/UInt64Value*.  
    <div drawio-diagram="6576"><img src="https://doc316en.candera.eu/uploads/images/drawio/2024-08/drawing-4-1724407549.png" alt="drawing-4-1724407549.png"/></div>
- In addition, bind the Value property of the Slider control to */SampleListEntry/FloatValue*.  
    <div drawio-diagram="6575"><img src="https://doc316en.candera.eu/uploads/images/drawio/2024-08/drawing-4-1724407450.png" alt="drawing-4-1724407450.png"/></div>
- This completes the binding settings for this item.
- After selecting the List control in the Scene Tree, select \[ Clone \] from the context menu.
- When the \[ Clone Item \] dialog box appears, select the \[ Multiple Clone \] tab, enter “6” for the "Number of Copies", and perform the clone.

- A scroll bar will appear because the seventh item is outside the visible area due to the size setting set earlier.  
    <div drawio-diagram="6574"><img src="https://doc316en.candera.eu/uploads/images/drawio/2024-08/drawing-4-1724407350.png" alt="drawing-4-1724407350.png"/></div>
    
      
    This completes the scene configuration. You can now generate the assets.

<div class="contents" id="bkmrk-after-we-have-define"><div class="contents">  
</div></div>#### <a class="anchor" id="bkmrk--63"></a>Handling the List model code

<div class="contents" id="bkmrk-first-we-have-to-gen"><div class="contents"><div class="textblock">- First we have to generate the code for the binding sources. In cgi\_studio\_player this can be done by starting the command script: cgi\_studio\_player/src/generate.cmd
- You will find the list sample code of the model (DynamicListComponent.cpp and DynamicListComponent.h) located in this folder: cgi\_studio\_player/src/Player/SampleComponents
- So, what we do here is we provide a list fragment at the startup to enable the view as soon as possible to show the list content:

</div></div></div>```
bool DynamicListComponent::OnMessage(const <a class="code" href="http://dev.doc.cgistudio.at/APILINK/class_courier_1_1_message.html">Courier::Message</a> & msg)
    {
        bool rc = false;
        switch (msg.<a class="code" href="http://dev.doc.cgistudio.at/APILINK/class_courier_1_1_message.html#afe450f3cb1a124f0874ed4ede8c62b7e">GetId</a>()) {
        case Courier::StartupMsg::ID:
            (*mSampleBindingSource).mVariantValue = <a class="code" href="http://dev.doc.cgistudio.at/APILINK/class_feat_std_1_1_variant.html">FeatStd::Variant</a>(10.0F);
            LoadSampleListFragmentMissingItems(0, 30);
            (*mSampleBindingSource).mSampleList.UpdateListItemCount(SAMPLE_LIST_SIZE);
            mSampleBindingSource.MarkItemModified(ItemKey::SampleBindingSource::SampleListItem);
            mSampleBindingSource.SendUpdate(true);
            break;
```

<div class="contents" id="bkmrk-the-call-of-loadsamp"><div class="contents"><div class="textblock"><div class="fragment">  
</div>- The call of LoadSampleListFragmentMissingItems simply initializes the list content of the default fragment.
- With the call of UpdateListItemCount we define the virtual size of the complete list.
- The call of MarkItemModified will mark the list as modified. Hence, only the list is updated by the SendUpdate call (which will post a message to the view).
- The handling of the UpdateModelMsg will do two things. The first one handles requests of new fragments from the list view. The second one handles modification of data items with the list items that are requested by the view (e.g. by the slider)

</div></div></div>```
case UpdateModelMsg::ID: {
```

<div class="contents" id="bkmrk-when-we-handle-new-f"><div class="contents"><div class="textblock"><div class="fragment">  
</div>- When we handle new fragments we will receive the start index(request.NewIndex) the size (request.OldIndex) of the requested fragment. Hence, we will update the fragment with these values. We do not yet send the update message because other messages may require further modification of the model. Hence we will send the update in the OnExecute method where we can be sure that the modifications are complete.

</div></div></div>```
                case <a class="code" href="http://dev.doc.cgistudio.at/APILINK/group___c_o_u_r_i_e_r___d_a_t_a_b_i_n_d_i_n_g.html#gga7e8c2538a212673b9e59b6941a54cb57a55e2fd0a1f3b8d1c662423da7dbe7fd9">Courier::ListRequestType::NewFragment</a>:
                    switch (request.ItemKey()) {
                    case ItemKey::SampleBindingSource::SampleListItem:
                        LoadSampleListFragmentMissingItems(request.NewIndex(), request.OldIndex());
                        break;
                    }
                    break;
```

<div class="contents" id="bkmrk-when-we-handle-the-c"><div class="contents"><div class="textblock"><div class="fragment">  
</div>- When we handle the change of an data item we will get the exact information which list has been modified, which item, which data item in the item and the new value. The model still can reject this modification. In both cases the model should send an update of that data item to either reset the list that requested the change and/or update other views that are bound to the list but not yet visible (NOTE: for fragment lists only one bound list is allowed to be active because only one fragment per list is handled in the model).

</div></div></div>```
        case Courier::ListRequestType::ChangeDataItem:
            switch (request.ItemKey()) {
            case ItemKey::SampleBindingSource::SampleListItem:
                switch (request.InnerItemKey()) {
                case ItemKey::SampleListEntry::FloatValueItem: {
                    const FeatStd::Float* value = request.GetItem<FeatStd::Float>();
                    SetSampleListTestListValue(request.NewIndex(), *value);
                }
                break;
                }
                break;
            }
            break;
```

# Integration of Monotype

This section provides an overview of the Monotype integration.

The current integration is a hardwired solution. Therefore, the choice of which engine shall be used, has to be made at precompile-time (CMake decision).

The following features have been integrated:

<div class="contents" id="bkmrk-font-engine%3A-itype"><div class="contents"><div class="textblock">- Font engine: iType

</div></div></div>#### <a class="anchor" id="bkmrk-"></a>The font engine: iType

iType is a font engine which main purpose is fast and qualitative rasterization of fonts.

<p class="callout info">To see, which version of iType is currently supported, please have a look at the <span style="color:rgb(230,126,35);">[\[3rd Party Software section\]](https://doc316en.candera.eu/books/getting-started/page/cgi-studio-components#bkmrk-cgi-studio-3psw)</span>.</p>

There are two different approaches to integrate the third party code iType into CGIStudio:

<div class="contents" id="bkmrk-adding-prebuilt-libr"><div class="contents"><div class="textblock">- adding prebuilt libraries
- add the third party code into the build process

</div></div></div>CGIStudio supports both by CMake settings.

Monotype/iType has a special porting API with which target and OS specifics can be overridden.

CGIStudio provides a single solution for all targets. For this, the framework links the API to the device and operating system layers.

It is also possible to use an own customized port instead of the CGIStudio solution.

#### <a class="anchor" id="bkmrk--0"></a>Cache support

The iType integration concentrates on the most performant cache types: BitmapCache and GlyphAtlas. Therefore, only these two cache types are fully supported.

#### <a class="anchor" id="bkmrk--1"></a>Overview: CMake settings

Currently CMake supports general iType integration flags to include Monotype.

To switch to the font engine the following CMake flag has to be set:

<div class="contents" id="bkmrk-flag-value-candera_f"><div class="contents"><div class="textblock"><table class="doxtable" style="width:41.8519%;"><tbody><tr><th style="width:56.5298%;">**Flag**</th><th style="width:43.4702%;">**Value**</th></tr><tr><td style="width:56.5298%;">CANDERA\_FONTENGINE</td><td style="width:43.4702%;">Monotype</td></tr></tbody></table>

</div></div></div>If HarfBuzz is selected as the current TextShaper, the flag CANDERA\_TEXTSHAPER automatically will change to WorldType-Shaper. Shaping can also be disabled.

<div class="contents" id="bkmrk-harfbuzz-requires-fr"><div class="contents"><div class="textblock"><dl class="note"><dt></dt><dd><p class="callout info">HarfBuzz requires Freetype and is not available for iType.</p>

</dd></dl></div></div></div>This flag is called Monotype to switch to the available Monotype engines. The concrete font engine will be iType.

By enabling Monotype, several CMake flags become available.

The flag MONOTYPE\_USE\_BINARIES can be used to switch between the different building modes.

They have their own flags which will be described within the corresponding build process description.

#### <a class="anchor" id="bkmrk--2"></a>Build process: iType as source code

For this mode, MONOTYPE\_USE\_BINARIES has to be disabled.

<div class="contents" id="bkmrk-onotype_font_engine_"><div class="contents"><div class="textblock">- ONOTYPE\_FONT\_ENGINE\_SRC\_PATH - This path defines the location where to find the source code for iType. By default this will be cgi\_studio\_3psw/src/Monotype/iType and the folder structure may look like the following:  
    <div drawio-diagram="1423"><img src="https://doc316en.candera.eu/uploads/images/drawio/2023-02/drawing-4-1676532389.png" alt="drawing-4-1676532389.png"/></div>
    
      
      
    The FileList.txt which defines all the files should contain the following three Lists: 
    - - MONOTYPE\_PUBLIC\_HEADERS
        - MONOTYPE\_PRIVATE\_HEADERS
        - MONOTYPE\_SOURCES
    
    <dl class="note"><dt></dt><dd><p class="callout info">It does not matter how the source code is distributed on these lists. Only the names should be in use</p>
    
    </dd></dl>
- MONOTYPE\_FEATSTD\_PORT\_ENABLED - This flag toggles the port API implementation between a CGIStudio version and the default win32\_lib including the settings which are required for Candera. The win32\_lib represents a default implementation of the framework, separated from any Candera relations. This enables an easy possibility to build iType in a separated environment and link it to Candera.
- MONOTYPE\_FONT\_ENGINE\_PORT\_PATH - This path is directly links to the port API which shall be used for the build. By default it links to the default location of the default CGIStudio implementation: cgi\_studio\_3psw/src/Monotype/iType/source/port/CGIStudio However, this can be changed to different implementations, too. If MONOTYPE\_FEATSTD\_PORT\_ENABLED is false, this will link to the win32\_lib definition.

</div></div></div>#### <a class="anchor" id="bkmrk--4"></a>Build process iType as prebuilt library

For this mode, MONOTYPE\_USE\_BINARIES has to be enabled.

In general using the prebuilt library is similar to the source code version.

The flags MONOTYPE\_FEATSTD\_PORT\_ENABLED, MONOTYPE\_FONT\_ENGINE\_PORT\_PATH and MONOTYPE\_FONT\_ENGINE\_SRC\_PATH are equal in usage as in the source code version. The only difference is, that the prebuilt library only requires header files.

The port files and header have to match with the build settings of the prebuilt library.

MONOTYPE\_ITYPE\_LIBRARY\_FILEPATH is the path to the prebuilt library. And has to be defined by the user.

#### Monotype – Prepopulated font engine cache

This feature shall be used to load font bitmap data into the font engine cache.

##### CMAKE Configuration

1. Set CANDERA -&gt; CANDERA\_FONTENGINE to Monotype
2. Configure
3. Check MONOTYPE -&gt; MONOTYPE\_PREPOPULATED\_CACHE\_ENABLED

##### Usage

1. Include the previously created cache dump header file.
2. Include the “MtInclude” header  
      
    \#include &lt;Candera/TextEngine/Monotype/MtInclude.h&gt;
3. Create an instance of a font that is present in the asset. The name of the font must match the “Candera Name” property of the font resource in the scene composer. The font size parameter of the Setup call is irrelevant.  
      
     Candera::TextRendering::Font font;  
     font.Setup("ConstructionKit##ConstructionKit#Resources#Fonts#Open Sans Light", 20);
4. Call FontEngine::InitPrepopulatedCache with the font and a reference to the utilCache variable from the cache dump file.  
      
    Candera::TextRendering::FontEngine::Instance().InitPrepopulatedCache(font, &amp;utilCache);

##### Possible Pitfalls

- The cache should be prepopulated during startup of the application. Thus, the above methods shall be called when the Courier::StartupMsg is received.
- The “faceName” property of the Font::Setup call must match the “Candera Name” property of the font in the composer.
- The font size used when displaying the text, e.g. with a TextNode, must match the font size used when generating the cache dump file.
- While generating the cache dump file, the glyph maps must be retrieved as GRAYMAP’s by calling  
    map = FS\_get\_glyphmap(FS\_state\_ptr, glyphIDs\[i\], FS\_MAP\_GRAYMAP8);
- When generating the cache dump file, fs\_config.h should match the configuration in cgi\_studio\_3psw\\src\\Monotype\\iType\\source\\common\\fs\_config.h

# Text engine: Shaping

#### <a class="anchor" id="bkmrk-"></a>Shaping

Stored texts are ordered by the reading flow. This means that every text is placed from left to right within the memory. It does not matter which language it is. There is also no other information stored besides the text itself. Therefore, the memory representation of text has only logical information but no visual representation information.

The goal of shaping is to find the correct representation of the given text. For example Arabic letters differ in their visual representation depending on their position. Therefore, characters usually have four different forms: Isolated, Final, Medial and Initial. Additionally, there are many more tasks for a shaper to handle: Diacritics, ligatures, kerning...

All different languages have their own characteristics when it comes to shaping. Even Latin has some shaping cases.

For more detailed information about shaping:   
WT-Shaper, HarfBuzz as well as different sources, e.g. Unicode.org and w3.org provides abundant information.

##### <a class="anchor" id="bkmrk--0"></a>Supported shaper

Candera supports different shaper:

<div class="contents" id="bkmrk-no-shaping-complex-s"><div class="contents"><div class="contents"><div class="textblock">- No shaping
- Complex Script
- HarfBuzz (in combination with FreeType)
- WorldType Shaper WorldType-Shaper (in combination with iType)

</div></div></div></div><p class="callout info">To see, which versions of shapers are currently supported, please have a look at the <span style="color:rgb(230,126,35);">[\[3rd Party Software section\]](https://doc316en.candera.eu/books/getting-started/page/cgi-studio-components#bkmrk-cgi-studio-3psw)</span>.  
</p>

#### <a class="anchor" id="bkmrk--1"></a>WorldType Shaper

##### <a class="anchor" id="bkmrk--2"></a>Integration of WT-Shaper

The integration is based on the same approach iType uses. (Reference to iType)

##### <a class="anchor" id="bkmrk--3"></a>CMake Integration

In CMake WT-Shaper can only be selected when Monotype is set as CANDERA\_FONTENGINE.

To switch to the shaper the following CMake flag has to be set:

<div class="contents" id="bkmrk-flag-value-candera_f"><div class="contents"><div class="textblock"><table class="doxtable" style="width:53.7037%;"><tbody><tr><th style="width:50.704%;">**Flag**</th><th style="width:49.296%;">**Value**</th></tr><tr><td style="width:50.704%;">CANDERA\_FONTENGINE</td><td style="width:49.296%;">Monotype</td></tr><tr><td style="width:50.704%;">CANDERA\_TEXTSHAPER</td><td style="width:49.296%;">WorldType-Shaper</td></tr></tbody></table>

</div></div></div>If Freetype + HarfBuzz is slected, the flag CANDERA\_TEXTSHAPER will automatically change to WorldType-Shaper.

Using prebuilt binaries or not is bound to the same CMake flag as <span style="color:rgb(230,126,35);">[The font engine: iType](https://doc316en.candera.eu/link/294#bkmrk-the-font-engine%3A-ity)</span> iType.

The flag MONOTYPE\_USE\_BINARIES can be used to switch between the different building modes.

##### <a class="anchor" id="bkmrk--4"></a>Build process: WT-Shaper as source code

For this mode, MONOTYPE\_USE\_BINARIES has to be disabled.

<div class="contents" id="bkmrk-monotype_wtshaper_sr"><div class="contents"><div class="textblock">- MONOTYPE\_WTSHAPER\_SRC\_PATH - This path defines the location where to find the source code for WT-Shaper. By default this will be cgi\_studio\_3psw/src/Monotype/WTShaper and the folder structure may look like the following:  
    <div drawio-diagram="1424"><img src="https://doc316en.candera.eu/uploads/images/drawio/2023-02/drawing-4-1676532572.png" alt="drawing-4-1676532572.png"/></div>
    
      
      
    The FileList.txt which defines all the files should contain the following three Lists: 
    - - WTSHAPER\_ALL\_HEADERS
        - WTSHAPER\_ALL\_SOURCES
        - WTSHAPER\_INCLUDE\_PATHS
    
    <dl class="note"><dt></dt><dd><p class="callout info">It does not matter how the source code is distributed on the first two lists. Only the names should be in use. The third list shall include the directories of WT-Shaper to add them to the linking system.</p>
    
    </dd></dl>
- MONOTYPE\_FEATSTD\_PORT\_ENABLED - This flag toggles the port API implementation between a CGIStudio version and the default win32\_lib including the settings which are required for [Candera](http://dev.doc.cgistudio.at/APILINK/namespace_candera.html "[DataBinding_RefTypeSample]"). The win32\_lib represents a default implementation of the framework, separated from any [Candera](http://dev.doc.cgistudio.at/APILINK/namespace_candera.html "[DataBinding_RefTypeSample]") relations. This enables an easy possibility to build WT-Shaper in a separated environment and link it to [Candera](http://dev.doc.cgistudio.at/APILINK/namespace_candera.html "[DataBinding_RefTypeSample]"). This flag is shared between iType and WT-Shaper.
- MONOTYPE\_WTSHAPER\_PORT\_PATH - This path is directly links to the port API which shall be used for the build. By default it links to the default location of the default CGIStudio implementation: cgi\_studio\_3psw/src/Monotype/WTShaper/source/port/CGIStudio However, this can be changed to different implementations, too. If MONOTYPE\_FEATSTD\_PORT\_ENABLED is false, this will link to the win32\_lib definition.

</div></div></div>##### <a class="anchor" id="bkmrk--6"></a>Build process WT-Shaper as prebuilt library

For this mode, MONOTYPE\_USE\_BINARIES has to be enabled.

In general using the prebuilt library is similar to the source code version.

The flags MONOTYPE\_FEATSTD\_PORT\_ENABLED, MONOTYPE\_WTSHAPER\_PORT\_PATH and MONOTYPE\_WTSHAPER\_SRC\_PATH are equal in usage as in the source code version. The only difference is, that the prebuilt library only requires header files.

The port files and header have to match with the build settings of the prebuilt library.

MONOTYPE\_WTSHAPER\_LIBRARY\_FILEPATH is the path to the prebuilt library. And has to be defined by the user.

# Monotype's Spark Engine

#### <a class="anchor" id="bkmrk--0"></a>Introduction to Monotype’s Spark engine

The Spark engine is Monotype’s lightweight font engine, with a focus on devices with a limited feature set.

This is a powerful engine with many capabilities able to provide high quality font rasterization and shaping.

However, to support resource constrained devices, certain restrictions have been placed on the font forming.

For more details regarding the types of restrictions in place, please contact Monotype directly.

#### <a class="anchor" id="bkmrk--1"></a>Integrating the Spark engine

Copy the source package provided by Monotype for the Spark engine to the following location,

<div class="contents" id="bkmrk-cgi_studio_3psw%2Fsrc%2F"><div class="contents"><div class="textblock">- cgi\_studio\_3psw/src/Monotype/spark

</div></div></div>The final folder’s substructure should be as follows,

<div class="contents" id="bkmrk-cgi_studio_3psw%2Fsrc%2F-0"><div class="contents"><div class="textblock">- cgi\_studio\_3psw/src/Monotype/spark/itypespark
- cgi\_studio\_3psw/src/Monotype/spark/shaperspark

</div></div></div>Additional content may differ depending on the package received from Monotype.

By completing these steps, the Spark engine has now been integrated into CGI Studio.

#### <a class="anchor" id="bkmrk--2"></a>Configuring the Spark engine

Configure the following entries within CMake as listed below,

<div class="contents" id="bkmrk-go-to-the-candera-gr"><div class="contents"><div class="textblock">- Go to the **CANDERA** group, then change **CANDERA\_FONTENGINE** to **Monotype**. 
    - This setting is necessary as the Spark engine is comprised of the iType Shaper and WorldType Shaper software.
    - After changing this setting, perform a reconfigure to update the available text shaper options based on the newly selected font engine.
- If you are planning on using a shaper, change **CANDERA\_TEXTSHAPER** to **WorldType-Shaper**. 
    - Perform another reconfigure after updating this entry.
- To switch to the Spark engine, go to the **MONOTYPE** group, then enable the **MONOTYPE\_SPARK\_LIGHTENGINE\_ENABLED** flag. 
    - Perform a reconfigure to complete the configuration process.
- CMake also provides an optional configuration flag, **MONOTYPE\_SPARK\_ENGINE\_INSTANCE\_COUNT**, which can impact both overall performance and memory usage. 
    - For improved performance, this flag must be set to the number of fonts concurrently in use within your asset. For example, if your asset contains a total of 50 fonts, but at a maximum only 5 fonts are in simultaneous use, then this flag should be set to 5.
    - However, this flag also creates instances of the engine, including caches. This will in turn lead to more memory usage.
- After making the stipulated updates, click the **Generate** button to complete the process.

</div></div></div><div class="contents" id="bkmrk-the-version-of-the-s"><div class="contents"><div class="textblock"><dl class="note"><dt></dt><dd><p class="callout info">The version of the Spark engine provided by Monotype must contain the **MS\_STORE\_SOURCE\_INDEX** feature.</p>

<p class="callout info">If this feature is not present, some text features may not work as intended, such as truncation.</p>

<p class="callout info">Which versions of the Spark engine support this feature are listed in the “Versions” text file contained in the following file path: cgi\_studio\_3psw\\src\\Monotype\\Versions.txt</p>

</dd></dl></div></div></div>By integrating the Spark engine into CGI Studio,

<div class="contents" id="bkmrk-basic-support-for-te"><div class="contents"><div class="textblock">- Basic support for text shaping using the Spark engine will be available.
- FontMaps are currently supported at this time.
- Supported glyph caching methods are provided by the iType Shaper. 
    - Bitmap and GlyphAtlas are supported.
- **MI\_SYNC\_MODE** is currently not supported.

</div></div></div>#### <a class="anchor" id="bkmrk--3"></a>Updating the Spark engine configuration files

The following configuration flag must be present within the shaper’s configuration file (msconfig.h),

```
#define MS_STORE_SOURCE_INDEX
```

If this flag is not present, a warning message will be shown requesting that this flag be set.

#### <a class="anchor" id="bkmrk--4"></a>General limitations

As a result of the Spark engine containing a minimal set of features, many optional features are not available. Some of these features include,

<div class="contents" id="bkmrk-handling-different-t"><div class="textblock">- Handling different type faces.
- Retrieving font style names.
- Family name inside the font.
- Complex runtime hint flags.
- Complex shaping flags (for example, turning on or off different ligature features).
- OpenType is not supported. Please contact Monotype for support converting fonts into equivalent internal table structures.

</div></div><div class="contents" id="bkmrk-another-limitation-a"><div class="textblock"><dl class="note"><dt></dt><dd><p class="callout info">Another limitation arises when importing a Photoshop files using the Smart Importer or Import from Photoshop option. Due to a difference in how text positioning is calculated within the Spark engine and Photoshop, the positioning of the text within CGI Studio may differ from the original Photoshop file.</p>

</dd></dl></div></div>---

# Colored Glyph Support

With the integration of Monotype’s iType library, the CGI Studio text engine now supports colored bitmaps from the CBDT table of truetype/opentype fonts.

#### <a class="anchor" id="bkmrk-"></a>Scope of new functionality

<div class="contents" id="bkmrk-monotype-must-be-con"><div class="contents"><div class="textblock">- Monotype must be configured as a font engine (for further details, please reference the CMake configuration section below)
- TextNode2D must be used (this feature is not supported with CanvasText, or by the deprecated TextEffect)
- Two renders are available for TextNode2D when using Monotype: **Bitmap** and **GlyphAtlas**. The option **Bitmap** must be used.
- Colored glyph bitmaps are taken from the font file in their raw format. No scaling is applied. To match different font sizes, you will need to add different sized glyph bitmaps to the font file.
- Text color will always be applied as color multiplication. For this reason, the colored bitmaps are colorized with the text color. Only white text color will preserve the colors from the original image.

</div></div></div>#### <a class="anchor" id="bkmrk--0"></a>CMake configuration

<div class="contents" id="bkmrk-choose-monotype-for-"><div class="contents"><div class="textblock">- Choose **Monotype** for CANDERA\_FONTENGINE
- Activate the new flag CANDERA\_TEXTENGINE\_COLORBITMAP\_ENABLED

</div></div></div>A third party library ”lodepng” has been added to decode images in PNG format, and is licensed under the ”zlib License”. This library is available within the cgi\_studio\_3psw folder, with its path set to the CMake variable CGISTUDIO\_LODEPNG\_INCLUDE\_PATH.

Cache: You can change the cache size for the maximum number of cached colored bitmap elements. The macro is defined as: CANDERA\_TEXTENGINE\_COLORBITMAP\_CACHE\_ELEMENT\_COUNT - default value: 20 This macro can be changed using a compiler flag (-D... or cmake add\_definitions). Alternatively, you can directly add this macro to the generated config headers.

<div class="contents" id="bkmrk-the-colored-glyphs-w"><div class="textblock"><dl class="note"><dt></dt><dd><p class="callout info">The colored glyphs will use a 32 bit per pixel RGBA format, while regular glyphs use an 8 bit per pixel alpha format. If a text contains one or more colored glyphs, the bitmap generated by TextNode2D will be in RGBA format. As a result, bitmaps generated by TextNode2D instances containing colored glyphs will require 4 times the necessary memory required by TextNode2D instances without colored glyphs. Colored glyphs are cached internally by the text engine in RGBA format. This cache also contributes to increased memory consumption.</p>

</dd></dl></div></div>

# Integration of CGI Player

#### <a class="anchor" id="bkmrk-"></a>Integration of the Player into SceneComposer

The Player can be started directly from SceneComposer through the new functionality: Play button starts the Player. New configuration panel has been added to define if and how asset is generated and how the Player is started.

Player integration as screen content into SceneComposer is currently not possible. Therefore the Player will still be used as the external player.

SceneComposer is able to start and stop the Player and provides an updated asset during runtime. If the update of the asset is not possible the Player will be restarted. The Player will be preconfigured with the currently selected scene. If no scene is selected another preconfigured or the first scene will be used. The platform configuration of the Player will be done by SceneComposer. To speed up the asset export there will be the possibilty to just export the current selected scene and all dependent scenes.

#### <a class="anchor" id="bkmrk--0"></a>The Player execution into SceneComposer includes:

<div class="contents" id="bkmrk-play-button-in-toolb"><div class="textblock">- Play button in toolbar to start the Player (pause, stop)
- Automated generation of asset (e.g. in temporary folder)
- Automated loading and execution of asset
- Configuration of default scene to load (Current selected scene, specific scene)

</div></div><div class="contents" id="bkmrk-the-integration-of-p"><div class="textblock"><dl class="note"><dt></dt><dd><p class="callout info">The integration of Player into SceneComposer is an intermediate step towards full integration of Live Preview as a panel in SceneComposer. This Live Preview will then substitute current display preview.</p>

</dd></dl></div></div>

# Input Handling

# Touch Input Handling

#### <a class="anchor" id="bkmrk--6"></a>Description

This chapter gives a detailed, technical overview of how the user touch input is handled internally which is important to understand further concepts like the Control States. The base part therefore is the [CgiStudioControl::ControlTouchSession](http://dev.doc.cgistudio.at/APILINK/class_cgi_studio_control_1_1_control_touch_session.html) which handles the TouchEvent and emits several Events received by Controls with a Handle Control State Behavior (e.g. <span style="color: rgb(230, 126, 35);">[Control States](https://doc316en.candera.eu/books/controls-and-behaviors/page/control-states "Control States")</span>).

<div drawio-diagram="1484"><img src="https://doc316en.candera.eu/uploads/images/drawio/2023-02/drawing-4-1676536656.png" alt=""/></div>

<div class="contents" id="bkmrk--0"><div class="contents"><div class="textblock">  
</div></div></div>#### <a class="anchor" id="bkmrk--8"></a>Touch Event

The Touch Event is emitted by [Courier](http://dev.doc.cgistudio.at/APILINK/namespace_courier.html) and contains TouchInfo with following states:

<div class="contents" id="bkmrk-move-down-up-hover-t"><div class="contents"><div class="textblock">- Move
- Down
- Up
- Hover

</div><div class="textblock"><dl class="note"><dd><p class="callout info">Touch input can be tested with the Player which reacts to mouse input and emits Touch Events.</p>

</dd></dl></div></div></div>#### <a class="anchor" id="bkmrk--9"></a>ControlTouchSession

To simplify the process especially for Control developers, the states of a TouchInfo are mapped to several, more specific Events. Therefore the ControlTouchSession generates kind of virtual input events in the sense that a combination of touch events result in a new input event (e.g. Touch Down and Touch Up on the same Control leads to a Click Event). To be able to generate these events and to send them to the right Control the ControlTouchSession contains a list to register all Control State Behaviors. So be sure that each Control which should be handled by the Control Touch Session has to contain a Control State Behavior. For each of the following events it is important to know that the events are generated by the ControlTouchSession but they are dispatched from the Control which gets touched. To understand how Events get sent also check chapter <span style="color: rgb(230, 126, 35);">[Behaviors and Events](https://doc316en.candera.eu/books/controls-and-behaviors/page/behaviors-and-events "Behaviors and Events")</span> .

<div class="contents" id="bkmrk-controls-must-have-a"><div class="contents"><div class="textblock"><dl class="note"><dd><p class="callout info">Controls must have a Handle Control State Behavior to receive Events from the Control Touch Session even if the Event is not sent locally to this Behavior (e.g. the Click Event).</p>

</dd><dd></dd></dl></div></div></div>#### <a class="anchor" id="bkmrk--10"></a>Pressed Event

Basically the Pressed Event which has two different states is triggered by the users touch down (state: Pressed) or by the users touch up (state: Released).   
Furthermore the TouchSession reacts to the move of the touch. So if the touch moves and the primarily touched Control is not touched any longer, the ControlTouchSession emits a Pressed Event with the state Released.   
If the touch is still down and enters the primarily touched Control, the TouchSession again emits a Pressed Event with the state Pressed.

<div drawio-diagram="1488"><img src="https://doc316en.candera.eu/uploads/images/drawio/2023-02/drawing-4-1676536784.png" alt=""/></div>

<div class="contents" id="bkmrk--2"><div class="contents"><div class="textblock">  
</div></div></div>In many cases, especially concerning Controls, the Pressed Event gets received by the Handle Control State Behavior (see chapter <span style="color: rgb(230, 126, 35);">[Control States](https://doc316en.candera.eu/books/controls-and-behaviors/page/control-states "Control States")</span>).

The Handle Control State Behavior even receives the Event via Local Dispatch Strategy (see <span style="color: rgb(230, 126, 35);">[Behaviors and Events](https://doc316en.candera.eu/books/controls-and-behaviors/page/behaviors-and-events "Behaviors and Events")</span>). But the Event also gets dispatched via BubbleStrategy from the Control which enables other Behaviors of the Control to receive the event (e.g. PressedCondition).

#### <a class="anchor" id="bkmrk--12"></a>Hovered Event

Emitting the Hovered Event works similar to the Pressed Event. But in difference to the Pressed Event the Hovered Event has an additional state in case of keep hovering over the same object.

Additionally the Event is emitted when the Hover leaves the currently hovered object (**HoverLeave**) and when the Hover enters and object (**HoverEnter**).   
As for the Pressed Event also the Hover Event basically gets received by the Handle Control State Behavior (see chapter [Control States](http://dev.doc.cgistudio.at/APILINK/_p_i_d_control_states.html)). But the Event can also be received by another Behavior like the HoveredCondition.

#### <a class="anchor" id="bkmrk--13"></a>Click Event

As the previously described Events also the Click Event is generated by the ControlTouchSession but it is dispatched from the Control which gets clicked.   
But different to the PressedEvent and the HoveredEvent, the ClickEvent is not sent to the Handle Control State Behavior via Local Dispatch Strategy as it is not relevant for the states of a Control. But again the Event gets dispatched from the Handle Control State Behavior which enables the user to directly react on the Event via an EventHandler (also see <span style="color: rgb(230, 126, 35);">[EventHandler Tab](https://doc316en.candera.eu/books/controls-and-behaviors/page/eventhandler-tab "EventHandler Tab")</span>). Furthermore it is important to know that the Click Event is emitted only on release of the touch point. Moreover the the Control of the touch down must be the same as the Control of the touch up. So following example would not trigger a Click Event:

<div drawio-diagram="1490"><img src="https://doc316en.candera.eu/uploads/images/drawio/2023-02/drawing-4-1676536828.png" alt=""/></div>

<div class="contents" id="bkmrk--4"><div class="contents"><div class="textblock">  
</div></div></div>The Click Event is often used in combination with a [<span style="color: rgb(230, 126, 35);">EventHandler Tab</span>](https://doc316en.candera.eu/books/controls-and-behaviors/page/eventhandler-tab "EventHandler Tab") as shown below:

<div drawio-diagram="1492"><img src="https://doc316en.candera.eu/uploads/images/drawio/2023-02/drawing-4-1676536878.png" alt=""/></div>

<div class="contents" id="bkmrk-be-sure-to-read-chap"><div class="textblock"><dl class="note"><dt></dt><dd><p class="callout info">Be sure to read chapter <span style="color: rgb(230, 126, 35);">[Control States](https://doc316en.candera.eu/books/controls-and-behaviors/page/control-states "Control States")</span> and <span style="color: rgb(230, 126, 35);">[Control Examples](https://doc316en.candera.eu/books/controls-and-behaviors/page/control-examples "Control Examples")</span> to see how the described Events can be used.</p>

</dd></dl></div></div>

# Focus Management

#### <a class="anchor" id="bkmrk--7"></a>Focus Navigation on Computer

The user of the created HMI wants to move the focus from one control to another. When using the computer, usually a keyboard is used for focus navigation.

On a computer, the user can use the following keys to move the focus from one control to the other:

<div class="contents" id="bkmrk---tab-move-the-focus"><div class="contents"><div class="textblock"><table border="0"><tbody><tr><td>**- TAB** </td><td>move the focus to the next control</td></tr><tr><td>**- CTRL + TAB** </td><td>move the focus to the previous control</td></tr></tbody></table>

</div></div></div>On targets without a keyboard, different input methods can be used for changing the focused control. Automotive targets use the rotary for focus navigation. Therefore, focus navigation is only loosely coupled with a keyboard.

---

#### <a class="anchor" id="bkmrk--8"></a>Focus Navigation in CGI Studio

This section uses a phone keypad like the one below to demonstrate the focus changes.

<div drawio-diagram="1495"><img src="https://doc316en.candera.eu/uploads/images/drawio/2023-02/drawing-4-1676537028.png" alt=""/></div>

<div class="contents" id="bkmrk--1"><div class="contents"><div class="textblock"><div class="image">  
</div></div></div></div>The focused button in the example keypad above is the fifth button (Button 5), whose border is significantly wider.

Focus navigation can be performed in the Player. To start the Player click the play button next to "Generate and Play" in the toolbar below the menubar.

<div drawio-diagram="1496"><img src="https://doc316en.candera.eu/uploads/images/drawio/2023-02/drawing-4-1676537050.png" alt=""/></div>

<div class="contents" id="bkmrk--3"><div class="contents"><div class="textblock"><div class="image">  
</div><div class="image"></div></div></div></div>##### <a class="anchor" id="bkmrk--11"></a>Next/Previous Navigation in CGI Studio

**Next Navigation:** After selecting a focusable control the focus can be moved to the next focusable control by pressing the **TAB** key of the keyboard. If you repeat pressing the TAB key, the focus will move to the next until the last focusable node is reached. Pressing TAB on the last focusable node will bring the focus back to the first node again.  
Focus order when continuing pressing the TAB key: 5-6-7-8-9-0-1-2-3-4-5-6-7-...

**Previous:** To navigate the focus back to the previous focusable control, press the **CTRL + TAB** keys on the keyboard. If you repeat pressing the CTRL + TAB keys, the focus will move to the previous until the first focusable node is reached. Pressing CTRL + TAB on the first focusable node will bring the focus back to the last node.  
Focus order when continuing pressing the CTRL + TAB keys: 5-4-3-2-1-0-9-8-7-6-5-4-3-2-1-...

<div class="contents" id="bkmrk-if-no-focusable-cont"><div class="contents"><div class="textblock"><dl class="note"><dd><p class="callout info">If no focusable control has the focus and a key that navigates the focus (e.g. a key of the cursor control pad or the TAB key) is pressed, the focusable control that has the lowest TAB-order gets the focus.</p>

</dd><dd></dd></dl></div></div></div>##### <a class="anchor" id="bkmrk--12"></a>Geometrical Navigation in CGI Studio

Geometrical Navigation means a navigation in one of the following directions: Left, Right, Up, Down, Up Left, Up Right, Down Left, Down Right  
On the computer, navigations in those directions can be performed using the cursor control pad or the numeric pad (for diagonal navigation) of the keyboard.

The following describes the focus change that happens when repeatedly clicking the noted navigation key in the example keypad above. Initally, for every noted navigation key, the focus is on the fifth focusable control as in the image of the keypad above.

<div class="contents" id="bkmrk-navigate-left%3A-5-4-n"><div class="contents"><div class="contents"><div class="textblock"><table border="0" style="width: 42.963%;"><tbody><tr><td rowspan="2" style="width: 71.1816%;">- **Navigate Left:** 5-4
- **Navigate Right:** 5-6
- **Navigate Up:** 5-2
- **Navigate Down:** 5-8-0

</td><td style="width: 14.4092%;">[![focus_left.png](https://doc316en.candera.eu/uploads/images/gallery/2023-02/scaled-1680-/focus-left.png)](https://doc316en.candera.eu/uploads/images/gallery/2023-02/focus-left.png)

</td><td style="width: 14.4092%;">[![focus_right.png](https://doc316en.candera.eu/uploads/images/gallery/2023-02/scaled-1680-/focus-right.png)](https://doc316en.candera.eu/uploads/images/gallery/2023-02/focus-right.png)

</td></tr><tr><td style="width: 14.4092%;">[![focus_up.png](https://doc316en.candera.eu/uploads/images/gallery/2023-02/scaled-1680-/focus-up.png)](https://doc316en.candera.eu/uploads/images/gallery/2023-02/focus-up.png)

</td><td style="width: 14.4092%;">[![focus_down.png](https://doc316en.candera.eu/uploads/images/gallery/2023-02/scaled-1680-/focus-down.png)](https://doc316en.candera.eu/uploads/images/gallery/2023-02/focus-down.png)

</td></tr><tr><td rowspan="2" style="width: 71.1816%;">- **Navigate UpLeft:** 5-1
- **Navigate UpRight:** 5-3
- **Navigate DownLeft:** 5-7
- **Navigate DownRight:** 5-9

</td><td style="width: 14.4092%;">[![focus_upleft.png](https://doc316en.candera.eu/uploads/images/gallery/2023-02/scaled-1680-/focus-upleft.png)](https://doc316en.candera.eu/uploads/images/gallery/2023-02/focus-upleft.png)

</td><td style="width: 14.4092%;">[![focus_upright.png](https://doc316en.candera.eu/uploads/images/gallery/2023-02/scaled-1680-/focus-upright.png)](https://doc316en.candera.eu/uploads/images/gallery/2023-02/focus-upright.png)

</td></tr><tr><td style="width: 14.4092%;"></td><td style="width: 14.4092%;">[![focus_downright.png](https://doc316en.candera.eu/uploads/images/gallery/2023-02/scaled-1680-/focus-downright.png)](https://doc316en.candera.eu/uploads/images/gallery/2023-02/focus-downright.png)

</td></tr></tbody></table>

</div></div></div></div><div class="contents" id="bkmrk--4"><div class="contents"><div class="textblock">---

</div></div></div>#### <a class="anchor" id="bkmrk--13"></a>Managing the Focusable Nodes

Each keyboard focusable behavior notifies the KeyboardFocusManager about its view getting activated or deactivated.

<div class="contents" id="bkmrk-registernavigation-i"><div class="contents"><div class="contents"><div class="textblock">- *RegisterNavigation* is called when the view gets activated.
- *DeregisterNavigation* is called when the view gets deactivated.

</div></div></div></div><div class="contents" id="bkmrk--5"><div class="contents"><div class="textblock">---

</div></div></div>#### <a class="anchor" id="bkmrk--14"></a>Concept of the Next/Previous Navigation

The logical order of the focusable nodes is defined by the following criteria:

<div class="contents" id="bkmrk-the-tab-order-of-its"><div class="contents"><div class="textblock">1. The tab order of its scene: This order is stored as a dynamic property and can be set by a *KeyboardFocusTabOrderBehavior*.
2. The asset order of its scene: This order is defined by the order in which the scene is stored in the asset.
3. Its tab order: This order is stored as a dynamic property and can be set by a *KeyboardFocusTabOrderBehavior*.
4. Its tree order: The tree order in pre-order tree traversal.

</div></div></div>**KeyboardFocusTabOrderBehavior**  
The tab order of a node is defined as relative or absolute. The default order is *relative*.

<div class="contents" id="bkmrk-relative-considering"><div class="contents"><div class="textblock">- *relative* considering the parent inherited tab order
- *absolute* will stop the inherited tab order

</div></div></div>The next/previous navigation updates the logical order for each next/previous navigation event and sorts the focusable nodes, finds the currently focused node in that list and transfers the focus to the next/previous entry in the list.

<div class="contents" id="bkmrk--6"><div class="contents"><div class="textblock">---

</div></div></div>#### <a class="anchor" id="bkmrk--15"></a>Concept of the Geometrical Navigation (Left, Right, Up, Down, Up Left, Up Right, Down Left, Down Right)

For each geometrical navigation event the bounding box in the display of the node is calculated per camera in the scene. Each keyboard focusable node has one entry in the lookup list for each camera.

The keyboard focused node is extended by the camera that is responsible for the focus. A scene may have several cameras and the focus will be caused by one of them.

The following events may trigger a change of the keyboard focus:

<div class="contents" id="bkmrk-navigate-to-the-left"><div class="contents"><div class="textblock"><table border="0"><tbody><tr><td rowspan="2">- Navigate to the Left
- Navigate to the Right
- Navigate Up
- Navigate Down

</td><td>[![focus_left.png](https://doc316en.candera.eu/uploads/images/gallery/2023-02/scaled-1680-/focus-left.png)](https://doc316en.candera.eu/uploads/images/gallery/2023-02/focus-left.png)

</td><td>[![focus_right.png](https://doc316en.candera.eu/uploads/images/gallery/2023-02/scaled-1680-/focus-right.png)](https://doc316en.candera.eu/uploads/images/gallery/2023-02/focus-right.png)

</td></tr><tr><td>[![focus_up.png](https://doc316en.candera.eu/uploads/images/gallery/2023-02/scaled-1680-/focus-up.png)](https://doc316en.candera.eu/uploads/images/gallery/2023-02/focus-up.png)

</td><td>[![focus_down.png](https://doc316en.candera.eu/uploads/images/gallery/2023-02/scaled-1680-/focus-down.png)](https://doc316en.candera.eu/uploads/images/gallery/2023-02/focus-down.png)

</td></tr><tr><td rowspan="2">- Navigate to the UpLeft direction
- Navigate to the UpRight direction
- Navigate to the DownLeft direction
- Navigate to the DownRight direction

</td><td style="width: 14.4092%;">[![focus_upleft.png](https://doc316en.candera.eu/uploads/images/gallery/2023-02/scaled-1680-/focus-upleft.png)](https://doc316en.candera.eu/uploads/images/gallery/2023-02/focus-upleft.png)

</td><td style="width: 14.4092%;">[![focus_upright.png](https://doc316en.candera.eu/uploads/images/gallery/2023-02/scaled-1680-/focus-upright.png)](https://doc316en.candera.eu/uploads/images/gallery/2023-02/focus-upright.png)

</td></tr><tr><td style="width: 14.4092%;">[![focus_downleft.png](https://doc316en.candera.eu/uploads/images/gallery/2023-02/scaled-1680-/focus-downleft.png)](https://doc316en.candera.eu/uploads/images/gallery/2023-02/focus-downleft.png)

</td><td style="width: 14.4092%;">[![focus_downright.png](https://doc316en.candera.eu/uploads/images/gallery/2023-02/scaled-1680-/focus-downright.png)](https://doc316en.candera.eu/uploads/images/gallery/2023-02/focus-downright.png)

</td></tr></tbody></table>

<table border="0"><tbody><tr><td><div class="image"><div class="image">[![focus_left.png](https://doc316en.candera.eu/uploads/images/gallery/2023-02/scaled-1680-/RKnfocus-left.png)](https://doc316en.candera.eu/uploads/images/gallery/2023-02/RKnfocus-left.png)  
</div></div></td><td>**Navigate to the Left:**</td></tr></tbody></table>

</div></div></div>1\. Find the nearest node of the nodes that are at least partially within the top and the bottom boundary of the keyboard focused node. The distance of the right node boundary to the left boundary of the keyboard focused node is minimal. Limit the right node boundary to the left boundary of the keyboard focused node. For multiple matches use the same order criteria as for the previous/next navigation and take the first one.  
2\. If no node was found, find the nearest node (where the corner to corner distance is minimal) of the nodes that intersect the left sectors:

<div class="contents" id="bkmrk-corner-to-corner-dis"><div class="contents"><div class="textblock">- corner to corner distance for nodes in the top left sector: take the node's bottom right corner (limit that corner to the left boundary of the keyboard focused node) and the keyboard focused node top left corner and calculate the square distance.
- corner to corner distance for nodes in the bottom left sector: take the node's top right corner (limit that corner to the left boundary of the keyboard focused node) and the keyboard focused node bottom left corner and calculate the square distance.
- All other sectors are not on the left of the keyboard focused node.
- For multiple matches use the same order criteria as for the previous/next navigation and take the first one.

<table border="0"><tbody><tr><td>[![focus_right.png](https://doc316en.candera.eu/uploads/images/gallery/2023-02/scaled-1680-/Erufocus-right.png)](https://doc316en.candera.eu/uploads/images/gallery/2023-02/Erufocus-right.png)

</td><td>**Navigate to the Right:**</td></tr></tbody></table>

</div></div></div>The same as navigation to the left but in this case, left is right, right is left, top is top and bottom is bottom in the description. Imagine a mirrored image.

<div class="contents" id="bkmrk-navigate-up%3A"><div class="contents"><div class="textblock"><table border="0"><tbody><tr><td>[![focus_up.png](https://doc316en.candera.eu/uploads/images/gallery/2023-02/scaled-1680-/9sWfocus-up.png)](https://doc316en.candera.eu/uploads/images/gallery/2023-02/9sWfocus-up.png)

</td><td>**Navigate Up:**</td></tr></tbody></table>

</div></div></div>The same as Left navigation but left is bottom, right is top, top is left and bottom is right in the description. This is a rotation by 90° counter clock wise

<div class="contents" id="bkmrk-navigate-down%3A"><div class="contents"><div class="textblock"><table border="0"><tbody><tr><td>[![focus_down.png](https://doc316en.candera.eu/uploads/images/gallery/2023-02/scaled-1680-/XmAfocus-down.png)](https://doc316en.candera.eu/uploads/images/gallery/2023-02/XmAfocus-down.png)

</td><td>**Navigate Down:**</td></tr></tbody></table>

</div></div></div>**Navigate Down:** The same as Left navigation but left is top, right is bottom, top is right and bottom is left in the description. Which is a rotation by 90° clock wise.

<div class="contents" id="bkmrk-navigate-to-the-uple"><div class="contents"><div class="textblock"><table border="0"><tbody><tr><td>[![focus_upleft.png](https://doc316en.candera.eu/uploads/images/gallery/2023-02/scaled-1680-/UmJfocus-upleft.png)](https://doc316en.candera.eu/uploads/images/gallery/2023-02/UmJfocus-upleft.png)

</td><td>**Navigate to the UpLeft direction:**</td></tr></tbody></table>

</div></div></div>Find the nearest node (corner to corner distance is minimal) of the nodes the intersect the top left sector:

<div class="contents" id="bkmrk-corner-to-corner-dis-0"><div class="contents"><div class="textblock">- corner to corner distance: take the node's bottom right corner (limit that corner to the left and top boundary of the keyboard focused node) and the keyboard focused node top left corner and calculate the square distance.
- For multiple matches use the same order criteria as for the previous/next navigation and take the first one.

<table border="0"><tbody><tr><td>[![focus_upright.png](https://doc316en.candera.eu/uploads/images/gallery/2023-02/scaled-1680-/2sZfocus-upright.png)](https://doc316en.candera.eu/uploads/images/gallery/2023-02/2sZfocus-upright.png)

</td><td>**Navigate to the UpRight direction:**</td></tr></tbody></table>

</div></div></div>The same as UpLeft navigation but left is right, right is left, top is top and bottom is bottom in the description. Imagine a mirrored image.

<div class="contents" id="bkmrk-navigate-to-the-down"><div class="contents"><div class="textblock"><table border="0"><tbody><tr><td>[![focus_downleft.png](https://doc316en.candera.eu/uploads/images/gallery/2023-02/scaled-1680-/Ub1focus-downleft.png)](https://doc316en.candera.eu/uploads/images/gallery/2023-02/Ub1focus-downleft.png)

</td><td>**Navigate to the DownLeft direction:**</td></tr></tbody></table>

</div></div></div>The same as UpLeft navigation but left is bottom, right is top, top is left and bottom is right in the description. This is a rotation by 90° counter clock wise.

<div class="contents" id="bkmrk-navigate-to-the-down-0"><div class="contents"><div class="textblock"><table border="0"><tbody><tr><td>[![focus_downright.png](https://doc316en.candera.eu/uploads/images/gallery/2023-02/scaled-1680-/Seefocus-downright.png)](https://doc316en.candera.eu/uploads/images/gallery/2023-02/Seefocus-downright.png)

</td><td>**Navigate to the DownRight direction:**</td></tr></tbody></table>

</div></div></div>The same as UpLeft navigation but left is top, right is bottom, top is right and bottom is left in the description. This is a rotation by 90° clock wise.

# GestureDetector

#### <a class="anchor" id="bkmrk-"></a>How to implement a custom GestureDetector

The ControlTouchSession supports GestureDetectors. You simply register your own detector and register it at the ControlTouchSession.

<div class="contents" id="bkmrk-the-clickgesturedete"><div class="contents"><div class="textblock">- The ClickGestureDetector is one of the existing detectors. It detects click, drag and press related gestures.
- Since it only detects the gestures it is clear that the ControlTouchSession is the only place where it is referenced (and also only because it is registered by default).
- GestureDetector::OnEvent is the only interaction interface with the ControlTouchSession.

</div></div></div>The ControlTouchSession will send these events to the gesture detector:

#### <a class="anchor" id="bkmrk--0"></a>UpdateEvent

This event indicates an update iteration (one per frame)

#### <a class="anchor" id="bkmrk--1"></a>GestureDetector::TouchInput

This is a single/multi touch event extended by this information:

<div class="contents" id="bkmrk-the-state-of-the-ges"><div class="contents"><div class="textblock">1. The state of the gesture detector session (FirstDown, LastUp).
2. The behavior that has currently the touch focus (which is the touchable behavior that was hit by the first finger that touched the screen during a gesture detector session)
3. The behavior that is currently touched by the touch event (also updated by Drag).

</div></div></div>The following states of the gesture detector session are available:

<div class="contents" id="bkmrk-firstdown%3A-the-gestu"><div class="contents"><div class="textblock">- FirstDown: The gesture detector session begins when the first finger touches the screen.
- LastUp: The gesture detector session ends when the last finger is removed from the screen.

</div></div></div>In between you will get updates in the following cases:

<div class="contents" id="bkmrk-down%3A-another-finger"><div class="contents"><div class="textblock">- Down: another finger touched the screen
- Drag: a finger has been moved.
- Up: one finger has been removed from the screen. But at least one more is on the screen.

</div></div></div>#### <a class="anchor" id="bkmrk--2"></a>GestureDetector::AbortEvent

This event tells that another behavior has taken the exclusive touch control. Hence, no gesture detector will participate in the current gesture detector session and therefore has to reset all internal states and wait for the next session.

#### <a class="anchor" id="bkmrk--3"></a>GestureDetector::DeregisterEvent

The provided behavior is removed from the ControlTouchSession. Hence the gesture detector also has to remove all references to that behavior.

See also:

<div class="contents" id="bkmrk-check-click-check-dr"><div class="textblock">- <span style="color: rgb(230, 126, 35);">[Check Click](https://doc316en.candera.eu/link/597#bkmrk-check-click)</span>
- <span style="color: rgb(230, 126, 35);">[Check Drag Drop](https://doc316en.candera.eu/link/597#bkmrk-check-drag-drop)</span>
- <span style="color: rgb(230, 126, 35);">[Check Hover](https://doc316en.candera.eu/link/597#bkmrk-check-hover)</span>
- <span style="color: rgb(230, 126, 35);">[Check Pressed](https://doc316en.candera.eu/link/597#bkmrk-check-pressed)</span>
- <span style="color: rgb(230, 126, 35);">[Swipe Gesture Condition](https://doc316en.candera.eu/link/597#bkmrk-swipe-gesture-condit)</span>
- <span style="color: rgb(230, 126, 35);">[Transform Gesture](https://doc316en.candera.eu/link/597#bkmrk-transform-gesture)</span>
- <span style="color: rgb(230, 126, 35);">[Transform Gesture Action](https://doc316en.candera.eu/link/582#bkmrk--8)</span>

</div></div>

# Warping

# Introduction

Image warping is the process of digitally manipulating an image such that shapes portrayed in the image have been distorted. Warping may be used for correcting image distortion as well as for creative purposes (e.g., morphing). The same techniques are equally applicable to video. CGI Studio warping is intended to be used for correction image distortion only. The following two components are involved in the process:

<div class="contents" id="bkmrk-warping-library%3A-com"><div class="contents"><div class="textblock">- Warping Library: compute the warping matrix
- [Candera](http://dev.doc.cgistudio.at/APILINK/namespace_candera.html "[DataBinding_RefTypeSample]"): maps a displays image as texture to a mesh created from the warping matrix information and displays the correspondingly distorted result.

</div></div></div>Following is a diagram depicting the information flow for warping:

<div drawio-diagram="1523"><img src="https://doc316en.candera.eu/uploads/images/drawio/2023-02/drawing-4-1676537449.png" alt=""/></div>

<div class="contents" id="bkmrk--1"><div class="textblock">  
</div></div>

# Configuration

#### <a class="anchor" id="bkmrk--1"></a>Description

Configuration information passed to the warping library is used to check constraints and as basis for computations.   
Following is a description of the warping configuration parameters:

#### <a class="anchor" id="bkmrk--2"></a>Reference Points

The reference points are represented by a 2D array with coordinates inside the display area to be warped. There are **NumOfRefPointsX** in horizontal direction and **NumOfRefPointsY** in vertical direction, both having values in the range 0..255. These are equally distributed over Bitmap-pixel.   
*Example*:

<div class="contents" id="bkmrk-numofrefpointsx%3A-21-"><div class="contents"><div class="textblock">- NumOfRefPointsX: 21 (0x15)
- NumOfRefPointsY: 11 (0x0B)

</div></div></div>The number of reference points used influence to output of the distorted image with regard to Bitmap size. The output image will be less jagged the higher the number of reference points are used for warping computation

#### <a class="anchor" id="bkmrk--3"></a>PixResolution

The Resolution of warping parameters determinine the warping accuracy. The final displacement of the reference points is the product of warping parameter by parameter resolution. Therefore, a warping parameter is given by the desired displacement divided by resolution.

The warping library supports the following pixel:

<div class="contents" id="bkmrk-0%3A-1%2F16-px-1%3A-1%2F8-px"><div class="contents"><div class="textblock">- 0: <sup>1</sup>/<sub>16</sub> px
- 1: <sup>1</sup>/<sub>8</sub> px
- 2: ¼ px
- 3: ½ px
- 4: 1 px
- 5: 2 px
- 6: 4 px
- 7: 8 px

</div></div></div>*Example*:   
If a texture point at (0,0) should be mapped at (10,10) the corresponding X\[0\] and Y\[0\] coordinates can be calculated by dividing the desired displacement by pixel resolution.   
For a pixel resolution of <sup>1</sup>/<sub>16</sub> px (0.0625):

```
X[0] = Xnew[0] – Xold[0] / 0.0625 = 160 (0xA0)
Y[0] = Ynew[0] –Yold[0] / 0.0625 = 160 (0xA0)
```

  
For a pixel resolution of ¼ px (0.25):

```
X[0] = Xnew[0] – Xold[0] / 0.25 = 40 (0x28)
Y[0] = Ynew[0] –Yold[0] / 0.25 = 40 (0x28)
```

#### <a class="anchor" id="bkmrk--4"></a>NumOfBitsPerParam

Represents the number of bits used for each parameter (n-bit representation = bit length of each parameter).  
The value should be in the range is 1..16.  
*Example*:

<div class="contents" id="bkmrk-if-numofbitsperparam"><div class="contents"><div class="textblock">- If NumOfBitsPerParam is 8 the warping parameters corresponding to X\[0\]Y\[0\] are represented as 0xA0 0xA0.
- If NumOfBitsPerParam is 12 the warping parameters corresponding to X\[0\]Y\[0\] are represented as 0x0A 0x00 0xA0.

</div></div></div><div class="contents" id="bkmrk-the-numofbitsperpara"><div class="contents"><div class="textblock"><dl class="note"><dd><p class="callout info">The **NumOfBitsPerParam** and **PixResolution** are represented on 8 bits, upper three bits are used for NumOfBitsPerParam and lower bit for PixResolution.</p>

</dd><dd></dd></dl></div></div></div>*Example:*:

<div class="contents" id="bkmrk-0x96--%3E-numofbitsper"><div class="contents"><div class="textblock">- 0x96 -&gt; NumOfBitsPerParam: 12, PixResolution 0 (<sup>1</sup>/<sub>16</sub> px)
- 0x98 -&gt; NumOfBitsPerParam: 12, PixResolution 2 (¼ px)

</div></div></div>#### <a class="anchor" id="bkmrk--5"></a>DisplaySizeX and DisplaySizeY

Width and height data (in pixel) of the display hardware (range: 0..65535).

*Example*:

<div class="contents" id="bkmrk-0x01-0xe0-%E2%80%93-displays"><div class="contents"><div class="textblock">- 0x01 0xE0 – DisplaySizeX – 480px width
- 0X00 0XF0- DisplaySizeY – 240 px height

</div></div></div>#### <a class="anchor" id="bkmrk--6"></a>BitmapAreaX and BitmapAreaY

Width and height data (in pixels) of source surface used as input for warp. The reference points are equally distributed over this range in x and y direction with values in the range 0..65535.

*Example*:

<div class="contents" id="bkmrk-0x01-0x98-%E2%80%93-bitmapar"><div class="contents"><div class="textblock">- 0x01 0x98 – BitmapAreaX – 408px width
- 0X00 0XBE- BitmapAreaY– 190 px height

</div></div></div><div class="contents" id="bkmrk-condition%3A%C2%A0-%C2%A0bitmapa"><div class="contents"><div class="contents"><div class="textblock"><dl class="note"><dd><p class="callout info">Condition:  
 BitmapAreaX≤ DisplaySizeX  
 BitmapAreaY≤DisplaySizeY</p>

</dd></dl></div></div></div></div>#### <a class="anchor" id="bkmrk--7"></a>BitmapAreaCenter

The Bitmap Area Center Point describes the center point of the image area used by ABK.

#### <a class="anchor" id="bkmrk--8"></a>BitmapAreaShift

The Bitmap Area Shift describes the connection vector between the origin of the bitmap coordinate system (0,0) and the center point of the bitmap area - i.e. the Bitmap Area Center Point.

#### <a class="anchor" id="bkmrk--9"></a>BitmapAreaShiftX and BitmapAreaShiftY

Shift values of bitmap area center point in horizontal and vertical direction (range 0..65535).

<div class="contents" id="bkmrk-%E2%80%9D0%E2%80%9D-bitmapareashiftx"><div class="contents"><div class="textblock">- ”0” BitmapAreaShiftX means the application window starts at the left edge on the display.
- ”0” BitmapAreaShiftY means the application window starts at the upper edge on the display.

</div></div></div>*Example*:

<div class="contents" id="bkmrk-0x00-0xcc-%E2%80%93-bitmapsh"><div class="contents"><div class="textblock">- 0x00 0xCC – BitmapShiftAreaX – 204px
- 0X00 0X5F- BitmapShiftAreaY– 95 px

</div></div></div><div class="contents" id="bkmrk-condition%3A%C2%A0-%C2%A0%28bitmap"><div class="contents"><div class="contents"><div class="textblock"><dl class="note"><dd><p class="callout info">Condition:  
 (BitmapAreaY/2+BitmapAreaShiftY≤DisplaySizeY) AND (BitmapAreaY/2– BitmapAreaShiftY ≥0  
 (BitmapAreaX/2+BitmapAreaShiftX≤DisplaySizeX) AND (BitmapAreaX/2– BitmapAreaShiftX ≥0</p>

</dd></dl></div></div></div></div>#### <a class="anchor" id="bkmrk--10"></a>IlluminatedDisplayAreaX and IlluminatedDisplayAreaY

Width and height data (in pixel) for illuminated area. This represents the region in which the warped surface will be rendered. If the source surface size extends beyond the IlluminatedDisplayArea it will be scaled down with regards to display size.

*Example*:

<div class="contents" id="bkmrk-0x01-0xe0-%E2%80%93-illumina"><div class="contents"><div class="textblock">- 0x01 0xE0 – IlluminatedDisplayAreaX – 480px width
- 0X00 0XF0- IlluminatedDisplayAreaY– 240 px height

</div></div></div><div class="contents" id="bkmrk-condition%3A%C2%A0-%C2%A0illumin"><div class="contents"><div class="textblock"><dl class="note"><dd><p class="callout info">Condition:  
 IlluminatedDisplayAreaX ≤ DisplaySizeY   
 IlluminatedDisplayAreaY ≤ DisplaySizeY</p>

</dd></dl></div></div></div>#### <a class="anchor" id="bkmrk--11"></a>IlluminatedDisplayAreaShiftX and IlluminatedDisplayAreaShiftY

Shift values of illuminatedDisplay area center point in horizontal and vertical direction (range 0..65535).

*Example*:

<div class="contents" id="bkmrk-0x00-0xf0-%E2%80%93-bitmapsh"><div class="contents"><div class="textblock">- 0x00 0xF0 – BitmapShiftAreaX – 240px
- 0X00 0X78- BitmapShiftAreaY– 120 px

</div></div></div><div class="contents" id="bkmrk-condition%3A%C2%A0-%C2%A0%28illdis"><div class="contents"><div class="textblock"><dl class="note"><dd><p class="callout info">Condition:  
 (IllDisplayAreaX/2+IllDisplayAreaShiftX≤DisplaySizeX) AND (IllDisplayAreaX/2– IllDisplayAreaShiftX ≥0)  
 (IllDisplayAreaY/2+IllDisplayAreaShiftY≤DisplaySizeY) AND (IllDisplayAreaY/2– IllDisplayAreaShiftY ≥0)</p>

</dd></dl></div></div></div>#### <a class="anchor" id="bkmrk--12"></a>RotationValue

The rotation value is represented in grad \*100 with values in the range -18000 .. +18000. This is the default rotation value which will be applied to the warp image.

The rotation takes place around the warped center point of the bitmap area used. With an uneven number of reference points in x- and y-direction, this point coincides with the middle reference grid point, and the coordinates of the rotation axis are present. If an even number of reference grid points is used, the coordinates of the warped center point of the image are be calculated.

*Example*:

<div class="contents" id="bkmrk-0x01-0xf4-%E2%80%93-rotation"><div class="contents"><div class="textblock">- 0x01 0xF4 – RotationValue: 500/100 = 50

</div></div></div>#### <a class="anchor" id="bkmrk--13"></a>ParamSet

Set of reference point shift vectors column-ordered.

The warping parameter correspond to the shift vectors (in pixels) of warping interpolation points in warped images in comparison to reference points in non-warped images (divided by the specified resolution). To save memory space and computing time, the absolute coordinates are not saved as warping parameters, but rather only the distance from the reference points (without rotation and shifting).

#### <a class="anchor" id="bkmrk--14"></a>ParamSetLength

Length of ParamSet in bytes. This is calculated by:

```
ParamSetLength = NumRefPointsX * NumRefPointsY * 2 * NumBitsPerParam
```

#### <a class="anchor" id="bkmrk--15"></a>RotationLimit

This value represents the maximal rotation angle in grad – both positive and negative values are accepted. If the RotationLimit value is chosen such that at maxim rotation point, the image will extend beyond display size, it will be scaled down to the size that fits inside the display area when a rotation equal to RotationLimit is applied.

The *display area* comprises the whole image including the grey border.  
The *bitmap image* area is the area within the grey border. This is the area we are interested in and which should be warped.  
The reference points are evenly distributed over the bitmap image area.

<div class="contents" id="bkmrk-the-illuminated-disp"><div class="contents"><div class="textblock"><dl class="note"><dt></dt><dd><p class="callout info">The illuminated display area is the part of the display, which is backlit and projected to the windshield.</p>

</dd></dl><div drawio-diagram="1543"><img src="https://doc316en.candera.eu/uploads/images/drawio/2023-02/drawing-4-1676538201.png" alt=""/></div>

  
</div></div></div>#### <a class="anchor" id="bkmrk--17"></a>Reference Point Shift Vectors

The warping parameters are based on reference point. These points are mapped by a 2D array containing coordinates inside the display area to be warped. For ++-each reference point, a shift vector is stored by the application. Every shift vector determines the amount of distortion to be applied to the corresponding point in x- and y-direction. Figure 2 shows a reference point grid with corresponding shift vectors.

To preserve memory, the shift vectors are stored in a compressed format. The format is determined by configuration information passed to warping library (number of bits used, value resolution) and is used by warping library to de- and encode shift vectors. The decoded shift vectors are cached in the warping library.

<div drawio-diagram="1544"><img src="https://doc316en.candera.eu/uploads/images/drawio/2023-02/drawing-4-1676538319.png" alt=""/></div>

<div class="contents" id="bkmrk--0"><div class="contents"><div class="textblock">  
</div></div></div>#### <a class="anchor" id="bkmrk--19"></a>Warp Matrix

The warp matrix is computed by the warping library. It is a 2-dimensional matrix. Each point corresponds to a reference point. The value of each point is the vector-addition of the reference point and corresponding shift vector. All values of the warp matrix are normalized to the range \[0..1\].

#### <a class="anchor" id="bkmrk--20"></a>Warp Image Bounds

Warp image bounds can be computed by the warping library. Warp image bounds comprise upper left corner point of the bitmap image area, its width, and height (normalized to the range \[0..1\]). They are used to specify to [Candera](http://dev.doc.cgistudio.at/APILINK/namespace_candera.html "[DataBinding_RefTypeSample]") which part of the rendered image shall be mapped to the warping mesh.

# Default Adjustments

An adjustment is specified by a mode and a delta. Mode defines the way of the distortion, delta defines the amount. The following modes are available:

<div class="contents" id="bkmrk-parallelogram-trapez"><div class="contents"><div class="textblock">- Parallelogram
- Trapezoid
- Pin balance
- Pincushion
- Shift
- Width
- Height
- Rotation (around bitmap image center point)

</div></div></div>For each reference point and corresponding shift vector, the adjustment is computed and applied. The resulting shift vector is again cached in the warping library. This way of implementation allows incremental adjustments.

Following are tables detailing supported adjustments:

<div class="contents" id="bkmrk-modedirection-trapez"><div class="textblock"><table border="1" cellpadding="5" cellspacing="0" style="height: 450.266px;" width="600"><tbody><tr bgcolor="#d4d4d4" style="height: 46.5938px;"><th style="height: 46.5938px;">**Mode**  
**Direction**</th><th style="height: 46.5938px;">**Trapezoid**</th><th style="height: 46.5938px;">**Parallelogram**</th><th style="height: 46.5938px;">**Pincushion**</th><th style="height: 46.5938px;">**Pin balance**</th></tr><tr style="height: 124.812px;"><td align="center" style="height: 124.812px;" valign="middle">Up</td><td style="height: 124.812px;"><div class="image"><div class="image">[![warping_trapezoid_up.png](https://doc316en.candera.eu/uploads/images/gallery/2023-02/scaled-1680-/warping-trapezoid-up.png)](https://doc316en.candera.eu/uploads/images/gallery/2023-02/warping-trapezoid-up.png)</div></div><div class="image">  
</div></td><td style="height: 124.812px;"><div class="image">[![warping_parallelogram_up.png](https://doc316en.candera.eu/uploads/images/gallery/2023-02/scaled-1680-/warping-parallelogram-up.png)](https://doc316en.candera.eu/uploads/images/gallery/2023-02/warping-parallelogram-up.png)</div></td><td style="height: 124.812px;">[![warping_pincushion_up.png](https://doc316en.candera.eu/uploads/images/gallery/2023-02/scaled-1680-/warping-pincushion-up.png)](https://doc316en.candera.eu/uploads/images/gallery/2023-02/warping-pincushion-up.png)

</td><td style="height: 124.812px;">[![warping_pinbalance_up.png](https://doc316en.candera.eu/uploads/images/gallery/2023-02/scaled-1680-/warping-pinbalance-up.png)](https://doc316en.candera.eu/uploads/images/gallery/2023-02/warping-pinbalance-up.png)

</td></tr><tr style="height: 76.5938px;"><td align="center" style="height: 76.5938px;" valign="middle">Down</td><td style="height: 76.5938px;">[![warping_trapezoid_down.png](https://doc316en.candera.eu/uploads/images/gallery/2023-02/scaled-1680-/warping-trapezoid-down.png)](https://doc316en.candera.eu/uploads/images/gallery/2023-02/warping-trapezoid-down.png)</td><td style="height: 76.5938px;">[![warping_pinbalance_down.png](https://doc316en.candera.eu/uploads/images/gallery/2023-02/scaled-1680-/warping-pinbalance-down.png)](https://doc316en.candera.eu/uploads/images/gallery/2023-02/warping-pinbalance-down.png)

</td><td style="height: 76.5938px;">[![warping_pincushion_down.png](https://doc316en.candera.eu/uploads/images/gallery/2023-02/scaled-1680-/warping-pincushion-down.png)](https://doc316en.candera.eu/uploads/images/gallery/2023-02/warping-pincushion-down.png)

</td><td style="height: 76.5938px;">[![warping_pinbalance_down.png](https://doc316en.candera.eu/uploads/images/gallery/2023-02/scaled-1680-/wkcwarping-pinbalance-down.png)](https://doc316en.candera.eu/uploads/images/gallery/2023-02/wkcwarping-pinbalance-down.png)

</td></tr><tr style="height: 100.641px;"><td align="center" style="height: 100.641px;" valign="middle">Left</td><td style="height: 100.641px;">[![warping_shift_left.png](https://doc316en.candera.eu/uploads/images/gallery/2023-02/scaled-1680-/warping-shift-left.png)](https://doc316en.candera.eu/uploads/images/gallery/2023-02/warping-shift-left.png)

</td><td style="height: 100.641px;">[![warping_pinbalance_left.png](https://doc316en.candera.eu/uploads/images/gallery/2023-02/scaled-1680-/warping-pinbalance-left.png)](https://doc316en.candera.eu/uploads/images/gallery/2023-02/warping-pinbalance-left.png)

</td><td style="height: 100.641px;">[![warping_pincushion_left.png](https://doc316en.candera.eu/uploads/images/gallery/2023-02/scaled-1680-/warping-pincushion-left.png)](https://doc316en.candera.eu/uploads/images/gallery/2023-02/warping-pincushion-left.png)

</td><td style="height: 100.641px;">[![warping_pinbalance_left.png](https://doc316en.candera.eu/uploads/images/gallery/2023-02/scaled-1680-/tYSwarping-pinbalance-left.png)](https://doc316en.candera.eu/uploads/images/gallery/2023-02/tYSwarping-pinbalance-left.png)

</td></tr><tr style="height: 101.625px;"><td align="center" style="height: 101.625px;" valign="middle">Right</td><td style="height: 101.625px;">[![warping_shift_right.png](https://doc316en.candera.eu/uploads/images/gallery/2023-02/scaled-1680-/warping-shift-right.png)](https://doc316en.candera.eu/uploads/images/gallery/2023-02/warping-shift-right.png)

</td><td style="height: 101.625px;">[![warping_pinbalance_right.png](https://doc316en.candera.eu/uploads/images/gallery/2023-02/scaled-1680-/warping-pinbalance-right.png)](https://doc316en.candera.eu/uploads/images/gallery/2023-02/warping-pinbalance-right.png)

</td><td style="height: 101.625px;">[![warping_pincushion_right.png](https://doc316en.candera.eu/uploads/images/gallery/2023-02/scaled-1680-/warping-pincushion-right.png)](https://doc316en.candera.eu/uploads/images/gallery/2023-02/warping-pincushion-right.png)

</td><td style="height: 101.625px;">[![warping_pinbalance_right.png](https://doc316en.candera.eu/uploads/images/gallery/2023-02/scaled-1680-/Mafwarping-pinbalance-right.png)](https://doc316en.candera.eu/uploads/images/gallery/2023-02/Mafwarping-pinbalance-right.png)

</td></tr></tbody></table>

<table border="1" cellpadding="5" cellspacing="0" style="height: 450.782px;" width="600"><tbody><tr bgcolor="#d4d4d4" style="height: 46.5938px;"><th style="height: 46.5938px;">**Mode**  
**Direction**</th><th style="height: 46.5938px;">**Height**</th><th style="height: 46.5938px;">**Width**</th><th style="height: 46.5938px;">**Rotation**</th><th style="height: 46.5938px;">**Shift**</th></tr><tr style="height: 100.016px;"><td align="center" style="height: 100.016px;" valign="middle">Up</td><td style="height: 100.016px;">[![warping_height_up.png](https://doc316en.candera.eu/uploads/images/gallery/2023-02/scaled-1680-/YInwarping-height-up.png)](https://doc316en.candera.eu/uploads/images/gallery/2023-02/YInwarping-height-up.png)

</td><td style="height: 100.016px;">[![warping_width_up.png](https://doc316en.candera.eu/uploads/images/gallery/2023-02/scaled-1680-/warping-width-up.png)](https://doc316en.candera.eu/uploads/images/gallery/2023-02/warping-width-up.png)

</td><td style="height: 100.016px;">  
</td><td style="height: 100.016px;">[![warping_shift_up.png](https://doc316en.candera.eu/uploads/images/gallery/2023-02/scaled-1680-/warping-shift-up.png)](https://doc316en.candera.eu/uploads/images/gallery/2023-02/warping-shift-up.png)

</td></tr><tr style="height: 94.2188px;"><td align="center" style="height: 94.2188px;" valign="middle">Down</td><td style="height: 94.2188px;">[![warping_height_down.png](https://doc316en.candera.eu/uploads/images/gallery/2023-02/scaled-1680-/SyGwarping-height-down.png)](https://doc316en.candera.eu/uploads/images/gallery/2023-02/SyGwarping-height-down.png)

</td><td style="height: 94.2188px;">  
</td><td style="height: 94.2188px;">  
</td><td style="height: 94.2188px;">[![warping_shift_down.png](https://doc316en.candera.eu/uploads/images/gallery/2023-02/scaled-1680-/warping-shift-down.png)](https://doc316en.candera.eu/uploads/images/gallery/2023-02/warping-shift-down.png)

</td></tr><tr style="height: 107.547px;"><td align="center" style="height: 107.547px;" valign="middle">Left</td><td style="height: 107.547px;">[![warping_height_left.png](https://doc316en.candera.eu/uploads/images/gallery/2023-02/scaled-1680-/warping-height-left.png)](https://doc316en.candera.eu/uploads/images/gallery/2023-02/warping-height-left.png)

</td><td style="height: 107.547px;">  
</td><td style="height: 107.547px;">[![warping_rotation_left.png](https://doc316en.candera.eu/uploads/images/gallery/2023-02/scaled-1680-/warping-rotation-left.png)](https://doc316en.candera.eu/uploads/images/gallery/2023-02/warping-rotation-left.png)

</td><td style="height: 107.547px;">[![warping_shift_left.png](https://doc316en.candera.eu/uploads/images/gallery/2023-02/scaled-1680-/Ztwwarping-shift-left.png)](https://doc316en.candera.eu/uploads/images/gallery/2023-02/Ztwwarping-shift-left.png)

</td></tr><tr style="height: 102.406px;"><td align="center" style="height: 102.406px;" valign="middle">Right</td><td style="height: 102.406px;">[![warping_height_right.png](https://doc316en.candera.eu/uploads/images/gallery/2023-02/scaled-1680-/warping-height-right.png)](https://doc316en.candera.eu/uploads/images/gallery/2023-02/warping-height-right.png)

</td><td style="height: 102.406px;">  
</td><td style="height: 102.406px;"><div class="image">[![warping_rotation_right.png](https://doc316en.candera.eu/uploads/images/gallery/2023-02/scaled-1680-/warping-rotation-right.png)](https://doc316en.candera.eu/uploads/images/gallery/2023-02/warping-rotation-right.png)</div></td><td style="height: 102.406px;">[![warping_shift_right.png](https://doc316en.candera.eu/uploads/images/gallery/2023-02/scaled-1680-/U8Lwarping-shift-right.png)](https://doc316en.candera.eu/uploads/images/gallery/2023-02/U8Lwarping-shift-right.png)

</td></tr></tbody></table>

</div></div>

# Enabling Warping

Following are the display settings required to enable warping in [Candera](http://dev.doc.cgistudio.at/APILINK/namespace_candera.html "[DataBinding_RefTypeSample]"):

<div class="contents" id="bkmrk-enable-warping-set-w"><div class="contents"><div class="textblock">1. Enable warping
2. Set warp matrix
3. Set warp image bounds
4. Apply display settings

</div></div></div>Candera’s Display class uses a transaction based execution model for setting properties. Several changes can be queued. Changes have to be applied explicitly via a call to [Display::ApplyChanges()](http://dev.doc.cgistudio.at/APILINK/group___behaviors_animation.html#ggac925ef0f693402018942162bb4843ca1ac689a0da569384cac91c50abcbfef8d3). Warping matrix data from the warping library can be used directly in [Candera](http://dev.doc.cgistudio.at/APILINK/namespace_candera.html "[DataBinding_RefTypeSample]").

# Warping Sequence

<div class="contents" id="bkmrk-distribute-reference"><div class="textblock">1. Distribute reference points over the bitmap according to the specifications in the parameter list. Parameterized through: Bitmap Area and the associated Bitmap Area Shift
2. Bitmap predistortion (warping) Parameterized through: the active Parameter Set
3. Rotate predistorted image data according to the parameter list. The rotation of the warped reference points must take place around the center point of the warped bitmap. Parameterized through: rotation of the warping area and warped bitmap area center point.
4. Shift rotated and warped image data according to the parameter list. Parameterized through: shift of warped bitmap area center point.
5. Display warped, rotated and shifted image data on the display

</div></div>

# Warping Library API

The public interface of the Warping Library is presented below:

<div class="contents" id="bkmrk-method-parameters-en"><div class="textblock"><table border="1" cellpadding="5" cellspacing="0" width="800"><tbody><tr bgcolor="#d4d4d4"><th width="40%">**Method**</th><th width="60%">**Parameters**</th></tr><tr><td valign="top">en\_warp\_result\_t   
**CalculateWarpMatrix()**- calculates the WarpMatrix from configuration parameters and reference points passed.

</td><td valign="top">- stc\_warp\_configuration\_pamameter\_t\* \[IN\] **pstcWarpConfigParams**: pointer to structure holding the configuration parameters and limits that need to be checked.
- stc\_warp\_parameter\_set\_t\* \[IN\] **pstcWarpRefPoints**: pointer to structure holding the packed reference points. These values are internally copied, so that the caller may change the values in the structure without any side effect to the reference points held by the library.
- stc\_warp\_matrix\_t\* \[OUT\] **pstcWarpMatrix**: pointer to data structure in which the WarpMatrix is written to. Memory must be allocated and managed by the caller. <dl class="note"><dt></dt><dd><p class="callout info">The values written into this data structure are valid only if success code is returned, otherwise data might be inconsistent or incomplete.</p>
    
    </dd></dl>

</td></tr><tr><td valign="top">en\_warp\_result\_t   
**AdjustWarpMatrix()**- adjust WarpMatrix from configuration parameters and adjust passed parameters based on internally stored reference points.

</td><td valign="top">- stc\_warp\_configuration\_pamameter\_t\* \[IN\] **pstcWarpConfigParams**: pointer to structure holding the configuration parameters and limits that need to be checked.
- stc\_warp\_adjust\_parameter\_t\* \[IN\] **pstcWarpAdjustParams**: pointer to structure holding the adjustment parameters.
- stc\_warp\_bool\_t\* \[OUT\] **pbRefPointsChanged**: pointer to Boolean where the function returns a flag indicating if the internally stored reference points have been changed during the adjustments. Memory must be allocated and managed by the caller.
- stc\_warp\_matrix\_t\* \[OUT\] **pstcWarpMatrix**: pointer to data structure in which the WarpMatrix is written to. Memory must be allocated and managed by the caller. <dl class="note"><dt></dt><dd><p class="callout info">The values written into this data structure are valid only if success code is returned, otherwise data might be inconsistent or incomplete.</p>
    
    </dd></dl>

</td></tr><tr><td valign="top">en\_warp\_result\_t   
**GetRefPoints()**- copy the values of internal current and valid reference point to the data structure. <dl class="note"><dt>**Note:**</dt><dd>If any range check fails, appropriate error code is returned.</dd></dl>

</td><td valign="top">- stc\_warp\_parameter\_set\_t\* \[OUT\] **pstWarpRefPoints**: pointer to data structure where the packed reference points will be copied to. Memory must be allocated and managed by the caller.

</td></tr><tr><td valign="top">en\_warp\_result\_t   
**ComputeWarpImageBoundsFromConfig()**- computes the bounds of the warping image within the full render target contents in normalized coordindates \[0..1\] from the warping configuration. <dl class="note"><dt>**Note:**</dt><dd>The bounds can be used as input for SetWarpImageBounds() function of Candera::Display.</dd></dl>

</td><td valign="top">- stc\_warp\_configuration\_parameter\_t\* \[IN\] **config**: configuration used for warping.
- WRP\_SFLOAT\* \[OUT\] **x**: coordinate of upper-most left bitmap area point.
- WRP\_SFLOAT\* \[OUT\] **y**: coordinate of upper-most left bitmap area point
- WRP\_SFLOAT\* \[OUT\] **width**: width of the bitmap area
- WRP\_SFLOAT\* \[OUT\] **height**: height of the bitmap area

</td></tr></tbody></table>

</div></div>

# Warping Candera API

The warping related public interface of the Candera::Display class is presented below:

<div class="contents" id="bkmrk-methods-void-setwarp"><div class="textblock"><table border="1" cellpadding="5" cellspacing="0" style="width: 69.3827%;"><tbody><tr bgcolor="#d4d4d4"><th style="width: 100%;">**Methods**</th></tr><tr><td style="width: 100%;">void SetWarpMatrix(WarpMatrix &amp;warpMatrix, UInt index=0)</td></tr><tr><td style="width: 100%;">const WarpMatrix &amp; GetWarpMatrix(UInt index=0) const</td></tr><tr><td style="width: 100%;">void ResetWarpMatrix(UInt index)</td></tr><tr><td style="width: 100%;">void SetWarpMatrixWeight(UInt index, Float weight)</td></tr><tr><td style="width: 100%;">Float GetWarpMatrixWeight(UInt index) const</td></tr><tr><td style="width: 100%;">void SetWarpImageBounds(Rectangle &amp;warpImageBounds)</td></tr><tr><td style="width: 100%;">const Rectangle &amp; GetWarpImageBounds() const</td></tr><tr><td style="width: 100%;">void SetWarpOrientation(DisplayOrientation::Enum orientation)</td></tr><tr><td style="width: 100%;">DisplayOrientation::Enum GetWarpOrientation() const</td></tr><tr><td style="width: 100%;">bool SetWarpingEnabled(bool isEnabled)</td></tr><tr><td style="width: 100%;">bool IsWarpingEnabled() const</td></tr></tbody></table>

</div></div>

# RenderTarget Alpha Blending

Using the icons in the toolbar the user can switch between "Normal Scene Editor Rendering" and "Alpha Blending Scene Editor Rendering".

<div drawio-diagram="1360"><img src="https://doc316en.candera.eu/uploads/images/drawio/2023-02/drawing-4-1676531143.png" alt="drawing-4-1676531143.png"/></div>

<div class="contents" id="bkmrk--0"><div class="contents"><div class="textblock">  
</div></div></div>The alpha blending render mode shows the check pattern in the background. The actual scene is rendered to an offscreen buffer and then blended against the background, that displays the check pattern.

<div drawio-diagram="1358"><img src="https://doc316en.candera.eu/uploads/images/drawio/2023-02/drawing-4-1676531134.png" alt="drawing-4-1676531134.png"/></div>

<div class="contents" id="bkmrk--2"><div class="contents"><div class="textblock">  
</div></div></div>This approach enables the user to immediately test certain blend settings.