*Goal
We are trying to implement an “Orphans” prevention system for unreal, since it is a big deal for our product.
Issue
The system has already been implemented in Unity, where we created a custom extension of the TMP component and had the needed data available in the TextInfo class.
However, for Unreal the component doesn’t seem to expose such data. We would have to compute it ourselves taking into account all the component and widget parameters.
References
We are trying to implement something similar to the “text-wrap: pretty” in CSS.
Questions
- Are we missing a way were we can get the “TextInfo” data similar to Unity?
- If not, what is the most advisable way to perform the computation to generate it ourselves?
Thanks.
I just found the variable I’m looking for (LineViews). Shoutouts to this great article
Unfortunatelly, is private on several levels, and since I don’t know how to work around that without modificating the source code, which is not an option, I’ll have to compute the value myself.
The path to get to the variable from the “TextBlock” is the following, for anywone willing to modify the engine:
For TextBlock:
TextBlock->MyTextBlock->TextLayoutCache->TextLayout->LineViews
For RichTextBlock:
RichTextBlock->MyRichTextBlock->TextLayoutCache->TextLayout->LineViews
Really, the need for the information about how the text component is rendering the text is only needed in the case of an “Orphan” being corrected producing an even worst effect of the last line of a paragraph being larger than the previous one:
Being kind of a corner case, it can be ignored and fix the Orphans by just processing the text and adding a NBSP character in the final space of each paragraph like so:
// UCMSTextBlock extends from UTextBlock
#define NBSP (TCHAR)160
void UCMSTextBlock::HandleOrphansFixing()
{
// Convert text to string
FString textString = Text.ToString();
// Replace all NBSPs with normal spaces
for (int i = 0; i < textString.Len(); i++)
if (textString[i] == NBSP)
textString[i] = ' ';
// Look for line breaks and insert NBSP in the previous space
int lastSpaceIndex = -1;
for (int i = 0; i < textString.Len(); i++)
{
// Space
if (textString[i] == ' ')
lastSpaceIndex = i;
// Line break or end of the text, replace last space with NBSP
if ((textString[i] == '\n' || i == textString.Len() - 1) &&
lastSpaceIndex > 0)
textString[lastSpaceIndex] = NBSP;
}
// Finally, replace component text
SetText(FText::FromString(textString));
}