Skip to main content
edited title
Link
janos
  • 111.7k
  • 15
  • 152
  • 391

Making my pygame wrap text function more concise Wrap a long string to an array of short-enough strings

Source Link

Making my pygame wrap text function more concise

I have made a function that wraps text in pygame (i.e. it turns a long string into an array of smaller strings that are short enough so they fit within the given width when rendered in the given font).

My function is below. text is the string we want to break up, font is a pygame font object, and max_width is the number of pixels wide we want the lines to be at maximum (an integer).

def wrap_text(text, font, max_width):
    lines = []
    words = text.split(" ")

    while words:
        line = words.pop(0)
        if words:
            width = font.size(" ".join((line, words[0])))[0]
            while width < max_width:
                if words[0] == "\n":
                    # Forced newline when "\n" is in the text
                    del words[0]
                    break
                line = " ".join((line, words.pop(0)))
                if not words:
                    break
                width = font.size(" ".join((line, words[0])))[0]

        if font.size(line)[0] > max_width:
            # When there is only one word on the line and it is still
            # too long to fit within the given maximum width.
            raise ValueError("".join(("\"", line, "\"", " is too long to be wrapped.")))
        lines.append(line)

    return lines

note: font.size(string) returns a tuple containing the width and height the string will be when rendered in the given font.

As you can see, I have the statements while words:, if words: and if not words: all within each other. I have been trying to refactor this by moving things around but I simply cannot think of a way to remove any of the 3 statements above. Any help is much appreciated :). Any comments about anything else in my code is welcome too.