How FSlateFontMeasure::Measure() and ShapedTextCacheUtil::MeasureShapedText() calculate heights of strings differently

(This is a translation of a [Japanese [Content removed] by FumitoKimura.)

Thank you for your continued support.

I am trying to create a widget class that directly renders strings using FSlateDrawElement::MakeShapedText() or FSlateDrawElement::MakeText(), without using TextBlock. In the process, I need to create an operation for measuring the size of strings. I found that STextBlock::ComputeDesiredSize() and FSlateTextRun::Measure() are responsible for this. So I am trying to implement the operation based on them.

The trouble is, however, that when I tried to measure the rendering size of a Shaped Text sequence where its outline has been enlarged, using ShapedTextCacheUtil::MeasureShapedText(), I found that the height that it calculated was less than the actual height of the text. In constrast, I confirmed that the size measured using FSlateFontMeasure::Measure() was the same as that of the text.

So I’d appreciate it if you could let me know how this can happen (i.e. how the height that ShapedTextCacheUtil::MeasureShapedText() calculates is less than the actual height of the text.)

(FYI, it can calculate the width correctly, including the outline size and shadow offset.)

Additionally, is my understanding correct that the text size measurement with FSlateFontMeasure::Measure() can only be valid for simplified text that is rendered with SimpleTextMode?

Thank you.

Hi,

I wouldn’t expect ShapedTextCacheUtil::MeasureShapedText to account for outlines or shadows at all, since it’s measuring the x advance (glyph width plus kerning) used to position each glyph within the text area. In FSlateTextRun::Measure, we take this as a starting point (the width from the beginning of the first letter to the end of the final letter) and add on the shadow and outline offsets to account for the portion of outline/shadow that extends past the ends of the unoutlined text:

return ShapedTextCacheUtil::MeasureShapedText(TextContext.ShapedTextCache, FCachedShapedTextKey(FTextRange(0, Text->Len()), Scale, TextContext, Style.Font), FTextRange(BeginIndex, EndIndex), **Text) + ShadowOffsetToApply + OutlineSizeToApply;Since outlines/shadows don’t affect the spacing between characters, this calculation of shaped text width plus the extra space for outlines/shadows should represent the full visual size of the text that we used to report the text block’s desired size. If that’s not the result you’re seeing, would you be able to provide a test project to demonstrate what you’re seeing?

FSlateFontMeasure::Measure should give accurate results for fully shaped text, and potentially slightly less accurate results for text using Simple Text Mode. There are a number of edge cases where Simple Text Mode may result in inaccuracies (specifically when using it with text which really does require full shaping), but you could test that quickly by adding the text to a text widget in a canvas panel and enabling “Size To Content” to see how well the bounding box matches the visuals of the text.

Best,

Cody

[mention removed]​

Would it be possible for you to answer the licensee’s question above?

Thanks

[mention removed]

(This is a translation of a Japanese post by FumitoKimura.)

Thank you very much for your reply.

> I wouldn’t expect ShapedTextCacheUtil::MeasureShapedText to account for outlines or shadows at all

I know that the calculation in ShapedTextCacheUtil::MeasureShapedText does not account for outlines and shadows, and I had implemented the calculation in the same way as the code you provided here. So what I would like to ask is why the heights of the return values from ShapedTextCacheUtil::MeasureShapedText and FSlateFontMeasure::Measure are different even for the same string.

> FSlateFontMeasure::Measure should give accurate results for fully shaped text, and potentially slightly less accurate results for text using Simple Text Mode.

I understand that FSlateFontMeasure::Measure() can be used for text rendered with FSlateDrawElement::MakeShapedText(), as well.

If the difference in size between ShapedTextCacheUtil::MeasureShapedText() and FSlateFontMeasure::Measure() is by design, I’ll use the measurement of FSlateFontMeasure::Measure().

Hi,

Sorry for the misunderstanding, I see what you mean. The biggest difference I see here is that ShapedTextCacheUtil will use the max text height as reported by the font (the tallest glyph in the font) while FSlateFontMeasure will use the tallest glyph in the block of being measured (as well as accounting for multiple lines). Both could be useful for different situations- the FSlateFontMeasure version will tell you the actual size of the text you are displaying, while the ShapedTextCacheUtil approach is better for sizing a text widget (since you wouldn’t want it to resize as new characters are entered). If you’re measuring a static piece of text that won’t change, FSlateFontMeasure will get you the most accurate information.

Best,

Cody

(This is a translation of a Japanese post by FumitoKimura.)

I understand that FSlateFontMeasure is useful for measuring static text, while ShapedTextCacheUtil is better for text that is not static.

Thank you very much for your support.

Please close this thread.