Android Code Snippet [B4X] [XUI] Accurate Text Measurement and Drawing

Discussion in 'Code Snippets' started by Erel, May 9, 2018.

  1. Erel

    Erel Administrator Staff Member Licensed User

    (It took me 7 years to get this one right.)

    text.gif


    [​IMG]

    [​IMG]

    XUI v1.60 includes a new method named B4XCanvas.MeasureText. This method accurately measures single line strings.
    It returns a B4XRect object with the width and height of the measured string. The Top field returns the highest point relative to the baseline.

    With these values it is possible to accurately vertically center the text with this code (works in all three platforms):
    Code:
    Dim r As B4XRect = cvs1.MeasureText(Text, Fnt)
    Dim BaseLine As Int = CenterY - r.Height / 2 - r.Top
    cvs1.DrawText(Text, CenterX, BaseLine, Fnt, Clr, 
    "CENTER")
    Sub that also draws the border and the baseline:
    Code:
    Sub DrawTextWithBorder (cvs1 As B4XCanvas, Text As String, Fnt As B4XFont, Clr As Int, CenterX As Int, CenterY As Int)
       
    Dim r As B4XRect = cvs1.MeasureText(Text, Fnt)
       
    Dim BaseLine As Int = CenterY - r.Height / 2 - r.Top
       cvs1.DrawText(Text, CenterX, BaseLine, Fnt, Clr, 
    "CENTER")
       cvs1.DrawCircle(CenterX, CenterY, 
    3dip, xui.Color_Blue, True0)
       r.Initialize(CenterX - r.Width / 
    2, CenterY - r.Height / 2, CenterX + r.Width / 2, CenterY + r.Height / 2)
       cvs1.DrawLine(r.Left, BaseLine, r.Right, BaseLine, xui.Color_Gray, 
    1dip)
       cvs1.DrawRect(r, xui.Color_Gray, 
    False2dip)
    End Sub
    Note that in B4i there was a small change in the way the offsets are set internally in B4XCanvas.DrawText.

    The XUI libraries are internal libraries. iXUI v1.60 and jXUI v1.60 will be included in the next versions of B4i and B4J. B4A XUI 1.60: https://www.b4x.com/android/forum/threads/updates-to-internal-libraries.59340/#post-587118
     
  2. Filippo

    Filippo Expert Licensed User

    Then you have been too slow. :D

    Thank you Erel! You never stop bringing something new. :)
     
  3. LucaMs

    LucaMs Expert Licensed User

    I guess because:

    1) it is not so simple as it seems;
    2) in the meantime, maybe you've done other things too.

    But I'm happy to read this: the app I have in my mind (and not published) is at least 4 years old, so... :)
     
  4. Erel

    Erel Administrator Staff Member Licensed User

    Both are true.
     
    KMatle likes this.
  5. KMatle

    KMatle Expert Licensed User

    Since two years I'm good with using the known methods. What makes wonder is the object's/method's name "B4XCanvas.MeasureText".

    Here a canvas is used to measure a text. I would have done it (if I was Google) like "Textobject.NeededWidth" or "Textobject.NeededHeight" depending on the content and given textsize or even vice versa "Textobject.MaxTextsizeToFit" when you set the height and width.

    Strange that Google did not implement such a basic thing.
     
  6. Johan Hormaza

    Johan Hormaza Active Member Licensed User

    Excelent... Good job
    Thank you Erel!!!
     
  7. Jeffrey Cameron

    Jeffrey Cameron Active Member Licensed User

    We need a "REALLY Like" button. :)
     
    Johan Hormaza and klaus like this.
  8. Erel

    Erel Administrator Staff Member Licensed User

    Note that it is not possible to accurately draw a border around text, like done in this example, with the standard Canvas.MeasureStringHeight method as it only returns the total height and lacks the height above baseline.

    This is a good point. In B4J and B4i you can call this method without initializing the B4XCanvas object as the internal canvas features are not needed. In B4A you do need to initialize it however you can create a 1x1 pixel canvas and use it for all measurements.
     
    KMatle and Johan Hormaza like this.
  9. ivan.tellez

    ivan.tellez Active Member Licensed User

    Thanks, that was just on Time @Erel

    I started to update an App after 2 years. Actually was really easy to draw Accurate text with AcceleratedSurface, but now I want limit the use of Libs to make the iOS version.

    I was about to drop XUI for the lack of text measurement. Are you also going to add DrawRoundRect ?
     
  10. Erel

    Erel Administrator Staff Member Licensed User

    Already possible. Start a new thread and I'll show you how.
     
    Myron and Johan Hormaza like this.
Loading...
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice