#!/usr/bin/python3 from wobbl_tools.pygame_tools.utils import * class MultilineText: """ Creates a surface with text on it. You can use "\\n" to create a newline. When the max_width parameter is set, newlines generate automatically. If you know the width of the widest character in your font, you can set the char_width parameter, it will make the text creation a bit faster. Use "surface.blit(multiline_text.surface, pos)" to draw it on a surface. """ def __init__(self, text: str, font: pygame.font.Font=default_font, color: tuple=white, max_width: int=None): self.text = text self.font = font self.color = color self.max_width = max_width self.surface = self.generate_surface() def generate_surface(self): lines = [] line = "" length = 1 if self.max_width is None: for char in self.text: if char == "\n": lines.append(line) length = 1 line = "" else: line += char length += 1 else: for char in self.text: if char == "\n": lines.append(line) length = 1 line = "" elif self.font.size(line)[0] >= self.max_width - 8: if " " in line: # remove last word words = line.split(" ") last_word = words[len(words) - 1] words.pop(len(words) - 1) line = "" for word in words: # convert the list back to a string line += word + " " line = line[:len(line) - 1] # remove last space character lines.append(line) line = last_word + char else: lines.append(line) length = 1 line = char else: line += char length += 1 lines.append(line) texts = [] for line in lines: texts.append(self.font.render(line, True, self.color)) if self.max_width is None: w = max(texts, key=lambda t: t.get_width()).get_width() else: w = self.max_width h = texts[0].get_height() sh = h * len(lines) surface = pygame.Surface((w, sh), flags=pygame.SRCALPHA) x, y = 0, 0 for text in texts: surface.blit(text, (x, y)) y += h return surface