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?
Forum Archive
[Question] Calculate number of chars in X, Y dimensions of a TextView
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."
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.
Hint... This is a monospaced font.
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.
Thanks everyone.
@omz Yes the ui.measure_string is bugged in 1.5. Luckily I do have the beta.