omz:forum

    • Register
    • Login
    • Search
    • Recent
    • Popular

    Welcome!

    This is the community forum for my apps Pythonista and Editorial.

    For individual support questions, you can also send an email. If you have a very short question or just want to say hello — I'm @olemoritz on Twitter.


    [Question] Calculate number of chars in X, Y dimensions of a TextView

    Pythonista
    4
    6
    4276
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • ywangd
      ywangd last edited by

      Given a text font and size (e.g. 'DejaVuSansMono', 12), and the bounds of a TextView (e.g. 400, 100), how can I reliably calculate the exact number of characters that can fit into the width and height of the TextView?

      1 Reply Last reply Reply Quote 0
      • Webmaster4o
        Webmaster4o last edited by Webmaster4o

        Use scene.render_text() or ImageFont and ImageDraw.

        With ImageFont and ImageDraw:

        from PIL import ImageFont, ImageDraw
        
        def charsfit(font, dimensions):
            """Calculate how many characters can fit into the width and height
               of a textbox based on a tuple describing a font and dimensions of
               the textbox"""
            #Font name and font size, TextView width and height
            fname, fsize = font
            bw, bh = dimensions
            #Load font
            font = ImageFont.truetype(fname, fsize)
            #Width and height are the width and height of one character.
            width, height = font.getsize("D")
            return bw/width, bh/height
        
        if __name__ == "__main__":
            print charsfit(('DejaVuSansMono', 12), (400, 100))
        

        This prints (57, 7)

        Also, I'm not sure how to do this with scene.render_text(), but the documentation says

        "This can be used to determine the size of a string before drawing it, or to repeatedly draw the same text slightly more efficiently."

        1 Reply Last reply Reply Quote 0
        • omz
          omz last edited by omz

          You can also use the ui.measure_string function. I can't test this right now, but I think there's a bug in version 1.5 (if you're not in the beta) that causes this to work only within an active drawing context.

          You can work around it like this:

          with ui.ImageContext(1, 1):
            w, h = ui.measure_string('Hello', font=('DejaVuSansMono', 12), max_width=400)
          

          (without the ImageContext the function may not work properly in 1.5)

          The exact number of characters that fit into a text view also depend on the words, i.e. where line breaks would occur, so you can't really determine it without testing a specific piece of text.

          1 Reply Last reply Reply Quote 2
          • ccc
            ccc last edited by

            Hint... This is a monospaced font.

            1 Reply Last reply Reply Quote 0
            • Webmaster4o
              Webmaster4o last edited by

              Good answer @omz because it doesn't require importing extra modules. I thought there was a solution within ui but I couldn't remember what it was called.

              1 Reply Last reply Reply Quote 0
              • ywangd
                ywangd last edited by

                Thanks everyone.

                @omz Yes the ui.measure_string is bugged in 1.5. Luckily I do have the beta.

                1 Reply Last reply Reply Quote 0
                • First post
                  Last post
                Powered by NodeBB Forums | Contributors