from typing import Optional import typing import pygame def draw_cursor(surface, cur_position, high, c, size=4): pygame.draw.line(surface, c, cur_position, (cur_position[0], cur_position[1] + high), size) def get_word_length(ft, word: str): word_surface = ft.render(word, 0, pygame.Color('black')) return word_surface.get_size() def render_text(surface, position: typing.Tuple[int, int], font: pygame.font, text: str, c=pygame.Color('black'), cursor_position: Optional[int] = None) -> int: """Render text with hyphenation""" if len(list(filter(bool, text.split()))) == 0: return 0 need_cursor = cursor_position is not None lines = [word.split() for word in text.splitlines()] space_size = font.size(' ')[0] max_width, max_height = surface.get_size() x, y = position symbols_counter = 0 for line in lines: for word in line: w, h = get_word_length(font, word) if w > max_width or h > max_height: raise ValueError("Surface is too small") if x + w >= max_width: x = position[0] y += h surface.blit(font.render(word, 0, c), (x, y)) if need_cursor and symbols_counter + len(word) >= cursor_position: # It means that cursor is in this word or after this word cur_coord = (x + get_word_length(font, word[:cursor_position - symbols_counter])[0], y) draw_cursor(surface, cur_coord, h, c) need_cursor = False symbols_counter += len(word) + 1 x += w + space_size y += h x = position[0] return y