Android Question MeasureMultilineTextHeight provides value which crops the text

epiCode

Active Member
Licensed User
I'm having certain issues with StringUtils function MeasureMultilineTextHeight

Non-english language strings are cut off (example attached)
I tried adding some constant to returned value from function but it does not work when lines exceed.
Is this a specific language/font issue ?
Is there an other method to measure height required or any autosize label which adapts its height if width is fixed or width if height is fixed, to fit the text (on the lines of label.autosize in vb)?

run view (2).png
 
Last edited:
Solution
After a lot of iterations I have arrived at a solution which I am going to share for others who might face the same challenge.

The value 1.16 has no technical or scientific basis. It is derived by trying a lot of iterations by varying text / width / font size and number of lines to check what value gives visually acceptable solution.

B4X:
'this line measures the height with little error for non-english fonts
lbl.Height = su.MeasureMultilineTextHeight(lbl, txt)

'this one corrects the error (almost always)
lbl.Height = lbl.Height * 1.16

epiCode

Active Member
Licensed User
here's a sample
 

Attachments

  • stringutilexample.zip
    9.4 KB · Views: 163
Upvote 0

TILogistic

Expert
Licensed User
Longtime User
see:

Update:
try this demo or modify it to measure your text in your language:

1626455735000.png
 

Attachments

  • B4XMeasureText.zip
    3.8 KB · Views: 207
Last edited:
Upvote 0

epiCode

Active Member
Licensed User
see:

Update:
try this demo or modify it to measure your text in your language:

View attachment 116516
Thanks !!
I've uploaded a sample code earlier but my messages are still waiting for approval.
I will try this code and revert
Thanks again
 
Upvote 0

epiCode

Active Member
Licensed User
see:

Update:
try this demo or modify it to measure your text in your language:

Hey Oparra,

Tried the nifty tool you made.

1. Its for B4j and not b4a but I'm presuming that since the core for both is same it wont matter much
2. The cropping continues - to confirm that its related to either the font or how java treats non-english fonts

I am attaching some images to show it varied with actually how many lines were there before the last line.
1626557793656.png
original text
1626557943897.png
single line rectangle
1626558058550.png
with just blank lines inserted before sample text (this looks perfect)
1626558404935.png
when number of lines is increased to 10 (gap is way too much)
1626558598410.png
finally single word -proverbial out of the box !!!

Sigh !!
 
Upvote 0

TILogistic

Expert
Licensed User
Longtime User
1. Its for B4j and not b4a but I'm presuming that since the core for both is same it wont matter much
tested on B4A and B4J

2. The cropping continues - to confirm that its related to either the font or how java treats non-english fonts
Yes

When I did this demonstration, it was to measure texts in Spanish or English.

But you can modify and test in your language.

Here is the logic of the text measurement, check it and adjust it to your language.

Note:
the routine measures the height and width of each row of the text.

B4X:
    For Each t As String In inTexts
        FontHeight = Max(FontHeight, cvs.MeasureText(t, xui.CreateDefaultFont(inFontSize)).Height) 'max. text row height
    Next

    For Each t As String In inTexts
        width = Max(width, cvs.MeasureText(t, xui.CreateDefaultFont(inFontSize)).Width) + 1 'maximal with
        height = height + FontHeight + 1
    Next
 
Last edited:
Upvote 0

epiCode

Active Member
Licensed User
After a lot of iterations I have arrived at a solution which I am going to share for others who might face the same challenge.

The value 1.16 has no technical or scientific basis. It is derived by trying a lot of iterations by varying text / width / font size and number of lines to check what value gives visually acceptable solution.

B4X:
'this line measures the height with little error for non-english fonts
lbl.Height = su.MeasureMultilineTextHeight(lbl, txt)

'this one corrects the error (almost always)
lbl.Height = lbl.Height * 1.16
 
Upvote 0
Solution
Top