Text Block's handle displaying static text that can be changed at runtime. Text block's allow for a simple text mode which is intended for optimized rendering of text blocks but only works with text containing numbers or basic ASCII.
Simple text mode does NOT allow for certain languages such as Arabic or Thai, that require complex text rendering support. It is useful for text that changes frequently and really shouldn't be used for localized user-facing text.
@TODO Add graph visuals for this hierarchy
UTextBlock
[Parent Class:UTextLayoutWidget
] UMG implementation of the Text Block.STextBlock
[Parent Class:SLeafWidget
]: Slate Widget implementation of the Text Block.FSlateTextBlockLayout
: Variable[TextLayoutCache
] The class to handle caching the layout of the STextBlock as a proxy of theFTextLayout
.FPlainTextLayoutMarshaller
[Compendium Explanation]: The marshaller that is used when creating the text block layout of this widget.
Within OnPaint
the text block goes through two paint routes on the CPU.
@TODO Add graph visuals for this section
Located in STextBlock::OnPaint
, this occurs in the paint pass in this execution order:
- Retrieves the local shadow color, opacity, and offset values and checks if a shadow should be drawn based on these values.
- Checks if the text should be rendered as enabled/disabled based on if the parent is enabled/disabled.
- Retrieves the local text and font values to be rendered.
- Checks if shadow rendering is enabled via
ShouldDropShadow
(local boolean
) which modifies the font settings to remove the outline from the shadow.- Calls
FSlateDrawElement::MakeText
to render the shadow text, with it being offset byLocalShadowOffset
(local FVector2D
) and styled according to the shadow font settings. - Restores the outline size to the font's and increments the
LayerID
(integer
) for the main text to be drawn at that layer ID in front of the shadow text.
- Calls
- Calls
FSlateDrawElement::MakeText
to render the main text at theLayerID
(integer
) and positions the text according toAllottedGeometry
(FGeometry
) and applies the style's and effects that are configured by the designer. - Returns the
LayerID
.
@TODO Add graph visuals for this section
Located in STextBlock::OnPaint
, this occurs in the paint pass in this execution order:
- Retrieves the last desired size of the text so we can check if the text size has changed after it was rendered.
- Tells the
TextLayoutCache
to paint the text via FSlateTextBlockLayout::OnPaint at theLayerID
(integer
). - Caches the new desired size of the text after its been painted(rendered) via the text layout cache.
- Checks if the desired size has changed and if wrapping is enabled, to then invalidate the layout of the widget since it requires the layout to be re-arranged.
- Returns the
LayerID
.
@TODO Add graph visuals for this section
This occurs for painting the block layout in this execution order:
- Caches size of the widget's geometry as
CachedSize
. - Computes the wrapping width to pass to the text layout for later use.
- Locally caches the visual justification of the text layout and computes the auto scroll value based on that justification(can be zero).
- Updates what part of the text layout is visible via
FTextLayout::SetVisibleRegion
&FTextLayout::UpdateIfNeeded
. - Lets the text layout handle the final aspects of OnPaint with its own
FTextLayout::OnPaint
functionality.
This occurs for painting the text layout in this execution order:
- Decides which drawing effects to show based on whether the parent widget is enabled/disabled. If disabled then uses the disabled effect.
- Calculates the text's scaling factor from the pre-scaled offset to the painted scaling(including things like the widget's render transform and such).
- Initializes the highest layer ID to keep track of front-most layer that's being used while painting.
- Sets up a visibility check to find out if a line of text is visible within the bounds of the widget as an optimization to not compute un-rendered text.
- Iterates over each line view, skipping lines that won't be rendered/visible.
- Renders background highlights for that line via
FSlateTextLayout::OnPaintHighlights
. - Sets up layer indices for rendering text and debugging visuals(incase there is a debug draw layer to draw over).
- Computes the overflow policy and direction of this line and how it should be handled such as adding ellipsis at the end.
- Render foreground highlights for that line via
FSlateTextLayout::OnPaintHighlights
. - Updates the highest layer ID to be based on the highest layer during this line's rendering.
- Renders background highlights for that line via
- Returns the highest layer ID.
This occurs when building the flow line layout in this execution order:
- Locally caches the current Line Model index as
LineModel
(FLineModel
) to prepare to lay out a single line of text. - Checks if
LineModel
's amount ofRunRenderer
(TArray<FTextRunRenderer>
)'s is greater than or equal to zero. - Locally caches if this line is wrapping by checking if
WrappingWidth
is greater than zero asIsWrapping
. - Checks if the line doesn't have any break candidates or if we're not wrapping the text:
- Iterates over all of the run's and creates a line view block via
FTextLayout::CreateLineViewBlocks
for this line model only.
- Iterates over all of the run's and creates a line view block via
- Otherwise it starts processing each word and character so see if we need to move it to the start of the next line to ensure the text fits. Each time it has to create a new line we call
FTextLayout::CreateLineViewBlocks
to run the new line.- Adjusts spacing between words and characters which would involve increasing/decreasing space to make sure the text looks balanced and easy to read.
- Aligns the positioning of the words and characters in the line to what the designer wanted via alignment & justification properties.
- Checks for special characters/elements of the text such as hyperlinks or embedded images to ensure they are correctly placed and rendered within the line.
- Caches line dimensions of width and height.
- Applies the line styling such as font size, color, bold/italic, etc.
- Caches word and character positioning of exact coordinates for the text to appear at.
- Accounts for special cases. This is a per text widget basis such as:
- Truncating text(cutting it off)
- Adding ellipsis("...")
- Wrapping it to the next line
- Applying different fonts
- Applying inline images
- Bidirectional text(such as Arabic or Hebrew)
- Text highlighting and selection
- Additional accessibility features such as high contract, larger text, etc.
- Notifying that this line of text is ready to be rendered(which will be sent to the rendering part of the engine later in the code execution).
This occurs for applying highlights to specific parts of text in this execution order:
- Ensure that this only occurs when updating a layout.
- Iterate through each line(
FLineView
).- Clear out any highlights in this line.
- Retrieve the text of this line as a line model(
FLineModel
). - Iterate through each model's highlights(
FTextLineHighlight
).- Check if the highlight is valid and relevant to the current line, otherwise skip it.
- Compute the text range(
FTextRange
) of the highlight for this line. - If the highlight doesn't affect this line then skip this highlight.
- Iterate through each text block in the line.
- Intersect the block's range with the highlight range.
- Check if the block is part of the highlight's range.
- Checks if this block is the start of the new highlight and adjusts positioning and width accordingly to fit the block.
- Computes the highlight width and offset depending on whether its the start of the highlight or a continuation from the previous block and the direction of the text(Left/Right).
- If a block is only partially highlighted then adjust the highlight's width and position to fit just the portion.
- Cache the highlight data that was computed.
- Apply the highlight to the line either as an foreground(overlay) or background(underlay) based on the z-order.