High, Higher, Highest text

boten

Active Member
Licensed User
Longtime User
I searched this ad nauseam and maybe I'll get a solution once and for all:

A label of a known and fixed height needs to have a "maximum" textsize - that is the text should fill the entire height of the label, well almost entirely.

I use a loop to determine the maximum textsize:
B4X:
canvs.Initialize(lbl)
f=lbl.TextSize
h=canvs.MeasureStringHeight(lbl.Text,lbl.Typeface,f)
Do While h<lbl.Height
  f=f+1
  h=canvs.MeasureStringHeight(lbl.Text,lbl.Typeface,f)
Loop
f=f-1
lbl.TextSize=f

The problem is that the top lead space takes "a lot of" space. GRAVITY.TOP does not help.
I even tried "reducing" the padding with:
B4X:
Dim r As Reflector
r.Target = lbl
r.RunMethod4("setPadding", Array As Object(0, 1dip, 0, 0), Array As String("java.lang.int", "java.lang.int", "java.lang.int", "java.lang.int"))
but it didn't help.

I usually solve this by drawing the text on the label with canvs.Drawtext, thus eliminating the top-lead problem
but I would like to know if there's any way to do that without drawing the text.
 

boten

Active Member
Licensed User
Longtime User
No difference, still big top-lead
The entire code:

B4X:
Sub Process_Globals
End Sub
Sub Globals
Dim lbl As Label
Dim cvs As Canvas
End Sub
Sub Activity_Create(FirstTime As Boolean)
lbl.Initialize("xxx")
Activity.AddView(lbl,10%x,2%y,80%x,20%y)
lbl.Color=Colors.White
lbl.TextColor=Colors.Black
lbl.Text="tyHgf"
lbl.Gravity=Gravity.TOP
Activity.Title=lbl.TextSize

Dim r As Reflector
r.Target = lbl
r.RunMethod4("setPadding", Array As Object(0, 0, 0, 0), Array As String("java.lang.int", "java.lang.int", "java.lang.int", "java.lang.int"))
End Sub
Sub Activity_Resume
End Sub
Sub Activity_Pause (UserClosed As Boolean)
End Sub
Sub xxx_Click
Dim h,f As Int
cvs.Initialize(lbl)
f=lbl.TextSize
h=cvs.MeasureStringHeight(lbl.Text,lbl.Typeface,f)
Do While h<lbl.Height
  f=f+1
  h=cvs.MeasureStringHeight(lbl.Text,lbl.Typeface,f)
Loop
f=f-1
lbl.TextSize=f
Activity.Title=lbl.TextSize  

Dim r As Reflector
r.Target = lbl
r.RunMethod4("setPadding", Array As Object(0, 0, 0, 0), Array As String("java.lang.int", "java.lang.int", "java.lang.int", "java.lang.int"))
End Sub

attached screenshot of before and after click on label
 

Attachments

  • x12.jpg
    x12.jpg
    14.9 KB · Views: 392
Upvote 0

boten

Active Member
Licensed User
Longtime User
Thanks. Much better but still the "tails" of lettergs like y & g are not entirely seen.

I can use font-size that is up to 80% of lbl.height (insted of 100%), or just stick to the method of canvas.drawtext where I have full control of vertical position and I'm able to use "the full height" if needed, which leads me to another question:

How much more overhead (in terms of memory, etc..) is used if I use the drawtext (on a canvas initialized to the label) instead of just the label.text? (since i think everything is eventually "drawn" on the screen by the OS)
 
Upvote 0

boten

Active Member
Licensed User
Longtime User
.... Make sure not to reinitialize the Canvas object every time.

So if I have many labels (or imageviews for that matter) should I:

1) define a different canvas for each view (resulting in many canvases)

or

2) define a single canvas and initialize it every time to the view I want to draw on

What is the consequence of re-intializing the same canvas over & over to a different view vs. DIMing many canvases?
 
Upvote 0

thedesolatesoul

Expert
Licensed User
Longtime User
I had a problem with canvases.
Remember each time you initialize a canvas, it creates a new bitmap the size of the view you initialize it to.
If you want to keep the bitmap of the previous label, then remember that each time you initialize the canvas to draw on different labels, you will have that many bitmaps in memory.
So if you have 100 labels, the canvas drawing will cause 100 bitmaps.

As far as I know, the matter is not how many times you Dim the (same) canvas. The canvas cannot be destroyed as long as the view holds a reference to the canvas bitmap. If you release the canvas bitmap, it will be destroyed, but you also lose your bitmap!

That is only my understanding.
 
Upvote 0

boten

Active Member
Licensed User
Longtime User
so, if I have canvas1, canvas2, ..... canvas100 - Each one initialized to a different label (label1,...label100) I will have 100 bitmaps, BUT I will also have 100 bitmaps if I have ONLY ONE canvas, initialized every time to a different label (canvas.initialize(label1) ....canvas.initialize(label100)

I will need memory for 100 bitmaps no matter which approach I take. Much easier to re-use the same canvas again and again.
 
Upvote 0

boten

Active Member
Licensed User
Longtime User
As I feel suited. Using several "larger than label" bitmaps to draw several "labels" that are "close by".

Will memory requirement be the same if using 5 bitmaps each 100x100 or if using 1 bitmap of 500x100 (just as example)
 
Upvote 0

boten

Active Member
Licensed User
Longtime User
That's what I was thinking too, negligble overhead.

To come back to the original subject, It's a pity we can't "utilize" the entire height of a label, nor control the exact position of text within the label, hence resorting to drawing text on an imageview.
 
Upvote 0
Top