French MeasureStringHeight - Bug ?

scrat

Active Member
Licensed User
Longtime User
Bonjour

J'utilise une fonction pour tracer du texte sur un canvas d'une ImageView et je rencontre un problème

La fonction :
B4X:
Sub DrawTextCenter(T As String, Cv As Canvas,Obj As ImageView,Bg As Bitmap, Cl As Int)
Dim Wt As Int
Dim Ht As Int
Dim Src,Dst As Rect
Wt = Cv.MeasureStringWidth(T, Typeface.DEFAULT,FontStd)
Ht = Cv.MeasureStringHeight("p",Typeface.DEFAULT,FontStd)
cl=Colors.White
Src.Initialize(0,0,Bg.Width,Bg.Height)
Dst.Initialize(0,0,obj.Width,Obj.Height)
Cv.DrawBitmap(Bg,Src,Dst)
Cv.DrawText(T,Obj.Width/2,(Obj.Height+Ht)/2, Typeface.DEFAULT,FontStd,Cl,"CENTER")
End Sub


La fonction MesureStringWidth fonctionne parfaitement, par contre MesureStringHeight ne retourne pas la bonne dimension lorsque on a un jambage descendant.

Par exemple :le mot "Gestion" sera bien centré verticalement mais pas le mot "Apercevoir"

Par contre si on ne passe que "p" a MesureStringWidth alors Apercevoir sera parfaitement centré verticalement

Avez vous déjà rencontré ce PB ?
 

klaus

Expert
Licensed User
Longtime User
La fonction MesureStringHeight donne la hauteur effective du texte et non la hauteur de la ligne compète.
Par exemple:
Log(cv.MeasureStringHeight("Option",Typeface.DEFAULT,16))
Log(cv.MeasureStringHeight("O",Typeface.DEFAULT,16))
Log(cv.MeasureStringHeight("p",Typeface.DEFAULT,16))

Option > 16
O > 12
p > 13

donc pour être sûr que tout texte soit centré de même manière il faut utiliser systématiquement au moins une majuscule et une lettre avec un jambage:
Log(cv.MeasureStringHeight("Op",Typeface.DEFAULT,16))

Meilleures salutations.
 

scrat

Active Member
Licensed User
Longtime User
En fait le souci vient de "drawtext" qui trace le texte, non pas a partir du haut ou du bas du texte, mais à l'origine de la lettre sans jambage.
Un peu comme on écrirait sur un cahier d'écolier
un petit dessin étant plus parlant



Y0 et le point Zéro du drawtext
Ht et le retour de la fonction MeasureStringHeight



Pour avoir un texte centré verticalement il faut donc savoir si on a un jambage et en soustraire la moitié

B4X:
Y0 = Cv.MeasureStringHeight("o",Typeface.DEFAULT,FontStd)
Ymini = Cv.MeasureStringHeight("p",Typeface.DEFAULT,FontStd)
Jambage=Ymini-Y0
Cv.DrawText(T,Obj.Width/2,(Obj.Height/2)+(((Obj.Height/2)-Jambage)/2), Typeface.DEFAULT,FontStd,Cl,"CENTER")
 

klaus

Expert
Licensed User
Longtime User
Je n'avais jamais pris garde que la cote y0 correspondait à la ligne de base du texte, je pensais que c'était par rapport à la ligne inférieure.
Mais finalement ça dépend de ce que l'on entend par centrer un texte. Centrer par rapport à quoi, le centre de la hauteur du texte actuel donc 4 hauteurs différents possibles: "o" "O" "p" "Op"?
Du moment que la cote y0 correspond à la ligne de base je choisirais plutôt de centrer par rapport aux minuscules sans jambage. Les majuscules débordant vers le haut et les lettres avec jambage déborderaient vers le bas.

Meilleures salutations.
 

scrat

Active Member
Licensed User
Longtime User
Oui c'est vrai que le terme "centré" est très relatif

Dans mon cas, je cherche à avoir autant d'espace entre les parties extremes haute/basse du texte par rapport au bord sup et inf de l'élément sur lequel je trace.

Ce qui m'a fait chercher un moment, c'est cette ligne de base qui dans les autres compilo que j'utilise et généralement en haut du texte.
 
Top