Android Question Calculating the best font size for canvas

James Chamblin

Active Member
Licensed User
Longtime User
I am trying to figure out the best MONOSPACE font size that will allow exactly 60 characters to extend across the canvas. Since the canvas size can vary based on settings, I need to adjust the font size to match. I came up with this test program, but it doesn't seem to do the job. The string should fit in the canvas exactly.
B4X:
Sub Activity_Create(FirstTime As Boolean)
   'Do not forget to load the layout file created with the visual designer. For example:
   Activity.LoadLayout("Console")
   cvsConsole.Initialize(Panel1)
   

End Sub

Sub Activity_Resume
   Log(Label1.TextSize)
   Dim s As String = "01234567 9 123456 19 123456 29 123456 39 1234567890123456 49 123456 59"
   cvsConsole.DrawColor(Colors.White)
   Dim cw As Float = Panel1.Width
   Dim w As Float = cw / cvsConsole.MeasureStringWidth(s, Typeface.MONOSPACE,Label1.TextSize)
   Dim TS As Int = Label1.TextSize * w
   cvsConsole.DrawText(s,0,14dip,Typeface.MONOSPACE,TS,Colors.Black,"LEFT")
   Panel1.invalidate

End Sub
 

sorex

Expert
Licensed User
Longtime User
when TS would be xx.9 xx will be xx.0 since it's an int. maybe that's why it's smaller?
 
Upvote 0

James Chamblin

Active Member
Licensed User
Longtime User
Actually I need it smaller. With the default 14 point font, the width of 60 characters is 560 pixels, however, the canvas on the emulated device is only 320 pixels across. After doing the math, the size of the font should be ~ .57142 the default size, which would be just above 8 points. Seems that even at 8 points, the font is still too big because I only fit about 54 characters.

Testing with a 720 pixel wide canvas seems to return the same scaling factor, causing the string to not fill the entire line. I wonder if font point size is scaled to screen density. If so, then I need to figure out how to change the font size relative to density instead of by pixel.
 
Upvote 0

sorex

Expert
Licensed User
Longtime User
just had another look at the code and wondered...

what's the use of the messure string width?

ain't it just canvaswidth/60 since it's non proportional all chars are the same width anyway?
 
Upvote 0

James Chamblin

Active Member
Licensed User
Longtime User
just had another look at the code and wondered...

what's the use of the messure string width?

ain't it just canvaswidth/60 since it's non proportional all chars are the same width anyway?
No, that wouldn't work. The size of the font is in points and the size of the canvas is in pixels. Since the pixel size of the font will vary between devices, I would first need to find out how many pixels a default size would take, then determine the scale factor.

There seems to be a second problem as well. I tried entering font size explicitly into the drawtext function. Found that with a 320 pixel wide canvas, a 7 point font is too small and an 8 point font is too large. Trying to enter a float in drawtext has no effect as it seems to be rounded to the nearest int. So it looks like I am going to have to tackle the problem another way.
 
Upvote 0

James Chamblin

Active Member
Licensed User
Longtime User
TS is defined as an Int ! Why ?
TextSize must be a Float variable as sorex already posted in post #2
I used an int because I initially thought TextSize was an int, but if I changed TS to a float, I still get incorrect results. Testing with explicit values shows that DrawText rounds to int anyway.
B4X:
cvsConsole.DrawText(s,0,14dip,Typeface.MONOSPACE,8.0,Colors.Black,"LEFT") 'Font is too large
cvsConsole.DrawText(s,0,28dip,Typeface.MONOSPACE,7.0,Colors.Black,"LEFT") 'Font is too small
cvsConsole.DrawText(s,0,42dip,Typeface.MONOSPACE,7.75,Colors.Black,"LEFT") 'Font is same size as 8.0
cvsConsole.DrawText(s,0,56dip,Typeface.MONOSPACE,7.25,Colors.Black,"LEFT") 'Font is same size as 7.0
Screenshot.png
 
Upvote 0

klaus

Expert
Licensed User
Longtime User
I tested it and it seems that Typeface.MONOSPACE works only with integer textsize values.
It works OK with Typeface.DEFAULT.
The probelm remains the same within Labels and also using the AHExtDrawing library.
 
Last edited:
Upvote 0

James Chamblin

Active Member
Licensed User
Longtime User
That explains things. I wonder if that is true with all monospaced fonts, or just the android ones. Will have to test it later as I'm away from the computer now.
 
Upvote 0
Top