CircuitPython word wrap for Label() text

This example code contains a function called wrap_nicely that can be used to reformat string text and add line brakes to wrap text at a given text count.

# return a reformatted string with wordwrapping
#@staticmethod
def wrap_nicely(string, max_chars):
    """A helper that will return the string with word-break wrapping.
    :param str string: The text to be wrapped.
    :param int max_chars: The maximum number of characters on a line before wrapping.
    """
    string = string.replace('\n', '').replace('\r', '') # strip confusing newlines
    words = string.split(' ')
    the_lines = []
    the_line = ""
    for w in words:
        if len(the_line+' '+w) <= max_chars:
            the_line += ' '+w
        else:
            the_lines.append(the_line)
            the_line = w
    if the_line:
        the_lines.append(the_line)
    the_lines[0] = the_lines[0][1:]
    the_newline = ""
    for w in the_lines:
        the_newline += '\n'+w
    return the_newline

There is a glitch with text rendering when the Label.text is updated with this reformatted text. To fix this I recommend updating Label.text with “” to clear out whatever is glitching.

Here is the full example code where I have added recalculation of the Label.y position to account for the position change due to the number of text lines.

import time
import board
import displayio
from adafruit_bitmap_font import bitmap_font
from adafruit_display_text import label

display = board.DISPLAY
 
# ---------- Set the font and preload letters ---------- 
# Be sure to put your font into a folder named "fonts".
font = bitmap_font.load_font("/fonts/Helvetica-Bold-16.bdf")
# This will preload the text images.
font.load_glyphs(b'abcdefghjiklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ- ()')

glyph_box = font.get_bounding_box()
glyph_h = glyph_box[1] + abs(glyph_box[3])
 
# ---------- Create the text label object ---------- 
# font: the font used
# text: some words that you want to display
# color: set the font color
# max_glyphs: the number of letters that can appear in this label
text_area = label.Label(font, text="HELLO WORLD", color=0xFF00FF, max_glyphs=200)

# Set the location
text_area.x = 20
text_area.y = 100

# Set the size of the text in whole numbers. 1 = full size and 2 = twice the size.
text_area.scale = 1

# return a reformatted string with wordwrapping
#@staticmethod
def wrap_nicely(string, max_chars):
    """A helper that will return the string with word-break wrapping.
    :param str string: The text to be wrapped.
    :param int max_chars: The maximum number of characters on a line before wrapping.
    """
    string = string.replace('\n', '').replace('\r', '') # strip confusing newlines
    words = string.split(' ')
    the_lines = []
    the_line = ""
    for w in words:
        if len(the_line+' '+w) <= max_chars:
            the_line += ' '+w
        else:
            the_lines.append(the_line)
            the_line = w
    if the_line:
        the_lines.append(the_line)
    the_lines[0] = the_lines[0][1:]
    the_newline = ""
    for w in the_lines:
        the_newline += '\n'+w
    return the_newline

# Show it
display.show(text_area)

while True:
    # this is used to clear the text buffer
    text_area.text = "" # Odd things happen without this
    # Create the Wrapped text string and set it to new_text
    new_text = wrap_nicely("The first command is 0xe1 with 15 (0xf) parameters following. The second and third are 0x11 and 0x29 respectively with delays (0x80) of 120ms (0x78) and no parameters.", 33)
    # Calculate the new text_area.y based on the number of text lines.
    text_area.y = round(new_text.count("\n")*glyph_h/2)
    # Send the new wrapped string to text_area.text
    text_area.text = new_text

    time.sleep(3)
    text_area.text = "" # Odd things happen without this
    new_text = wrap_nicely("Now this is a fine mess that we are in.", 13)
    text_area.y = round(new_text.count("\n")*glyph_h/2)
    text_area.text = new_text
    time.sleep(3)

The wrap_nicely() function is based on a similar function used in the adafruit_pyportal.py library for CircuitPython.

https://github.com/adafruit/Adafruit_CircuitPython_PyPortal/blob/81c82035649007bbccb7d0ec75ce192f3b2ca058/adafruit_pyportal.py