Forum Archive

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

ywangd

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?

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."

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.

ccc

Hint... This is a monospaced font.

Webmaster4o

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.

ywangd

Thanks everyone.

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