So I discovered (thanks to Margret's CToast Class) that I can use a reflector on a view and use getWidth and getHeight to much, much more accurately figure out desired fontsize for views at run time over a canvas MeasureStringWidth or measurestringheight property.
(especially for other languages besides English, such as Thai)
However, the only way I can see to use those properties in a loop (to zero in on the correct size), is to call DoEvents after each run thru the loop, which involves resizing and drawing the View (I do it offscreen, so the user doesn't see it)
This results, (with my binary sort approach), in about a 250 millisecond time for each view that needs to be calculated. Whereas I could do 6 at once with the Canvas method in under 100 milliseconds
Anybody know a way to cut this down, and I think that really means to get rid of the DoEvents, but I don't know how to pull that off with b4a, and not sure if it could be done in a library call in java, but hopefully someone with a bit more savvy can point me down the right path.
Here's the code I'm using
(especially for other languages besides English, such as Thai)
However, the only way I can see to use those properties in a loop (to zero in on the correct size), is to call DoEvents after each run thru the loop, which involves resizing and drawing the View (I do it offscreen, so the user doesn't see it)
This results, (with my binary sort approach), in about a 250 millisecond time for each view that needs to be calculated. Whereas I could do 6 at once with the Canvas method in under 100 milliseconds
Anybody know a way to cut this down, and I think that really means to get rid of the DoEvents, but I don't know how to pull that off with b4a, and not sure if it could be done in a library call in java, but hopefully someone with a bit more savvy can point me down the right path.
Here's the code I'm using
B4X:
Sub newSetFontSizeLabel(theLabel As Label, someText As String, desiredFont As Typeface, someActivity As Activity, dummyLabel As Label) As Float
dummyLabel.Text = someText
dummyLabel.Typeface = desiredFont
Dim r As Reflector
r.Target = dummyLabel
Dim newWidth, newHeight As Float
newWidth = r.RunMethod("getWidth")
newHeight = r.RunMethod("getHeight")
'want to try a binary tree here
Dim LowNumber, HighNumber As Float
Dim middleSize As Float
LowNumber = 1
HighNumber = 200
middleSize = (HighNumber + LowNumber)/2
dummyLabel.Width = -2
dummyLabel.Height = -2
dummyLabel.TextSize = HighNumber
DoEvents
newWidth = r.RunMethod("getWidth")
newHeight = r.RunMethod("getHeight")
'First Find High Number
Do While newWidth/theLabel.Width < 1 AND newHeight/theLabel.Height < 1
LowNumber = (middleSize + LowNumber)/2
HighNumber = HighNumber * 2
middleSize = (LowNumber + HighNumber)/2
dummyLabel.Width = -2
dummyLabel.Height = -2
dummyLabel.TextSize = HighNumber
DoEvents
newWidth = r.RunMethod("getWidth")
newHeight = r.RunMethod("getHeight")
Loop
dummyLabel.Width = -2
dummyLabel.Height = -2
dummyLabel.TextSize = middleSize
DoEvents
newWidth = r.RunMethod("getWidth")
newHeight = r.RunMethod("getHeight")
'look at the size of the textbox against the height and width of the requirement
'if within and below some percentage, should be good enough
Do While newWidth/theLabel.Width >= 1 OR newHeight/theLabel.Height >= 1 OR (newWidth/theLabel.Width < .98 AND newHeight/theLabel.Height < .98)
If newWidth/theLabel.Width >= 1 OR newHeight/theLabel.Height >= 1 Then
'this means the middlesize is now the new highnumber
HighNumber = middleSize
Else
LowNumber = middleSize
End If
If LowNumber/HighNumber > .98 Then 'this catches case where it misses sometimes
Return LowNumber
End If
'Log("ratio: " & (LowNumber/HighNumber))
middleSize = (HighNumber + LowNumber)/2
dummyLabel.Width = -2
dummyLabel.Height = -2
dummyLabel.TextSize = middleSize
DoEvents
newWidth = r.RunMethod("getWidth")
newHeight = r.RunMethod("getHeight")
Loop
Return dummyLabel.TextSize
End Sub