CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-pygame

Cross-platform library for developing multimedia applications and video games in Python built on top of SDL

Overview
Eval results
Files

text-font.mddocs/

Text and Font Rendering

Font loading and text rendering including system fonts, TrueType fonts, text metrics, and styling options. Pygame provides comprehensive text rendering capabilities for displaying text in games and applications.

Capabilities

Font System Management

Initialize and manage the font rendering system.

def init() -> None:
    """Initialize font module."""

def quit() -> None:
    """Uninitialize font module."""

def get_init() -> bool:
    """
    Check if font module is initialized.

    Returns:
        bool: True if font module is initialized
    """

def get_default_font() -> str:
    """
    Get filename of default font.

    Returns:
        str: Path to default font file
    """

System Fonts

Access and use system-installed fonts.

def get_fonts() -> list[str]:
    """
    Get list of available system fonts.

    Returns:
        list[str]: List of font names available on system
    """

def match_font(name: str, bold: bool = False, italic: bool = False) -> str:
    """
    Find system font file path by name.

    Args:
        name (str): Font name to search for
        bold (bool): Whether to look for bold variant
        italic (bool): Whether to look for italic variant

    Returns:
        str: Path to font file or None if not found
    """

def SysFont(name: str, size: int, bold: bool = False, italic: bool = False) -> pygame.font.Font:
    """
    Create font from system font by name.

    Args:
        name (str): System font name
        size (int): Font size in pixels
        bold (bool): Use bold variant
        italic (bool): Use italic variant

    Returns:
        pygame.font.Font: Font object
    """

Font Class

Main font object for rendering text with various styling options.

class Font:
    def __init__(self, filename, size: int):
        """
        Create font from file or use default font.

        Args:
            filename: Font file path or None for default font
            size (int): Font size in pixels
        """

    def render(self, text: str, antialias: bool, color, background = None) -> pygame.Surface:
        """
        Render text to a surface.

        Args:
            text (str): Text to render
            antialias (bool): Use antialiasing for smoother text
            color: Text color
            background: Background color (None for transparent)

        Returns:
            pygame.Surface: Surface containing rendered text
        """

    def size(self, text: str) -> tuple[int, int]:
        """
        Get dimensions of text if it were rendered.

        Args:
            text (str): Text to measure

        Returns:
            tuple[int, int]: (width, height) in pixels
        """

    def get_height(self) -> int:
        """
        Get height of font in pixels.

        Returns:
            int: Font height including line spacing
        """

    def get_linesize(self) -> int:
        """
        Get recommended line spacing.

        Returns:
            int: Pixels between lines
        """

    def get_ascent(self) -> int:
        """
        Get font ascent (height above baseline).

        Returns:
            int: Pixels above baseline
        """

    def get_descent(self) -> int:
        """
        Get font descent (height below baseline).

        Returns:
            int: Pixels below baseline
        """

    def metrics(self, text: str) -> list:
        """
        Get metrics for each character in text.

        Args:
            text (str): Text to analyze

        Returns:
            list: List of (min_x, max_x, min_y, max_y, advance) for each character
        """

    def get_bold(self) -> bool:
        """
        Check if font is bold.

        Returns:
            bool: True if font is bold
        """

    def set_bold(self, bold: bool) -> None:
        """
        Set font bold style.

        Args:
            bold (bool): True for bold text
        """

    def get_italic(self) -> bool:
        """
        Check if font is italic.

        Returns:
            bool: True if font is italic
        """

    def set_italic(self, italic: bool) -> None:
        """
        Set font italic style.

        Args:
            italic (bool): True for italic text
        """

    def get_underline(self) -> bool:
        """
        Check if font is underlined.

        Returns:
            bool: True if font is underlined
        """

    def set_underline(self, underline: bool) -> None:
        """
        Set font underline style.

        Args:
            underline (bool): True for underlined text
        """

    def get_strikethrough(self) -> bool:
        """
        Check if font has strikethrough.

        Returns:
            bool: True if font has strikethrough
        """

    def set_strikethrough(self, strikethrough: bool) -> None:
        """
        Set font strikethrough style.

        Args:
            strikethrough (bool): True for strikethrough text
        """

Advanced Font Rendering (FreeType)

Enhanced font rendering with advanced typography features (available when pygame built with FreeType).

# pygame.freetype module (if available)
def init(cache_size: int = 64, resolution: int = 72) -> None:
    """
    Initialize FreeType font system.

    Args:
        cache_size (int): Number of fonts to cache
        resolution (int): DPI resolution
    """

def quit() -> None:
    """Uninitialize FreeType system."""

def get_init() -> bool:
    """
    Check if FreeType is initialized.

    Returns:
        bool: True if initialized
    """

class Font:
    def __init__(self, file, size: int = 0, font_index: int = 0, resolution: int = 0, ucs4: bool = False):
        """
        Create FreeType font object.

        Args:
            file: Font file path or file object
            size (int): Font size (0 for scalable)
            font_index (int): Font index in collection
            resolution (int): DPI resolution
            ucs4 (bool): Enable UCS-4 character encoding
        """

    def render(self, text: str, fgcolor = None, bgcolor = None, style: int = 0, rotation: int = 0, size: int = 0) -> tuple[pygame.Surface, pygame.Rect]:
        """
        Render text with advanced options.

        Args:
            text (str): Text to render
            fgcolor: Foreground color
            bgcolor: Background color
            style (int): Style flags (STYLE_BOLD, etc.)
            rotation (int): Rotation angle in degrees
            size (int): Font size override

        Returns:
            tuple[pygame.Surface, pygame.Rect]: Rendered surface and text rectangle
        """

    def render_to(self, surf: pygame.Surface, dest, text: str, fgcolor = None, bgcolor = None, style: int = 0, rotation: int = 0, size: int = 0) -> pygame.Rect:
        """
        Render text directly to a surface.

        Args:
            surf (pygame.Surface): Destination surface
            dest: Position to render at
            text (str): Text to render
            (other args same as render())

        Returns:
            pygame.Rect: Rectangle where text was rendered
        """

    def get_rect(self, text: str, style: int = 0, rotation: int = 0, size: int = 0) -> pygame.Rect:
        """
        Get rectangle that would contain rendered text.

        Args:
            text (str): Text to measure
            style (int): Style flags
            rotation (int): Rotation angle
            size (int): Font size

        Returns:
            pygame.Rect: Bounding rectangle
        """

    def get_metrics(self, text: str, size: int = 0) -> list:
        """
        Get detailed character metrics.

        Args:
            text (str): Text to analyze
            size (int): Font size

        Returns:
            list: Character metric data
        """

Font Style Constants

# Style flags for FreeType fonts
STYLE_NORMAL: int
STYLE_UNDERLINE: int
STYLE_OBLIQUE: int
STYLE_STRONG: int
STYLE_WIDE: int
STYLE_DEFAULT: int

Usage Examples

Basic Text Rendering

import pygame

pygame.init()
screen = pygame.display.set_mode((800, 600))

# Create font objects
default_font = pygame.font.Font(None, 36)  # Default font
system_font = pygame.font.SysFont('arial', 24)  # System font

# Try to load custom font
try:
    custom_font = pygame.font.Font('custom_font.ttf', 48)
except:
    custom_font = default_font

running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

    screen.fill((255, 255, 255))

    # Render different text samples
    text1 = default_font.render("Default Font", True, (0, 0, 0))
    screen.blit(text1, (50, 50))

    text2 = system_font.render("System Arial Font", True, (255, 0, 0))
    screen.blit(text2, (50, 100))

    text3 = custom_font.render("Custom Font", True, (0, 0, 255))
    screen.blit(text3, (50, 150))

    # Text with background
    text4 = default_font.render("Text with Background", True, (255, 255, 255), (0, 128, 0))
    screen.blit(text4, (50, 200))

    pygame.display.flip()

pygame.quit()

Font Styling and Metrics

import pygame

pygame.init()
screen = pygame.display.set_mode((800, 600))

# Create font with different styles
font = pygame.font.SysFont('arial', 32)

# Test text
test_text = "Styled Text Example"

# Get text dimensions
text_width, text_height = font.size(test_text)
print(f"Text dimensions: {text_width} x {text_height}")

# Get font metrics
print(f"Font height: {font.get_height()}")
print(f"Font ascent: {font.get_ascent()}")
print(f"Font descent: {font.get_descent()}")
print(f"Line size: {font.get_linesize()}")

running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

    screen.fill((255, 255, 255))

    y_pos = 50

    # Normal text
    normal_text = font.render(test_text, True, (0, 0, 0))
    screen.blit(normal_text, (50, y_pos))
    y_pos += 50

    # Bold text
    font.set_bold(True)
    bold_text = font.render(test_text, True, (0, 0, 0))
    screen.blit(bold_text, (50, y_pos))
    font.set_bold(False)
    y_pos += 50

    # Italic text
    font.set_italic(True)
    italic_text = font.render(test_text, True, (0, 0, 0))
    screen.blit(italic_text, (50, y_pos))
    font.set_italic(False)
    y_pos += 50

    # Underlined text
    font.set_underline(True)
    underline_text = font.render(test_text, True, (0, 0, 0))
    screen.blit(underline_text, (50, y_pos))
    font.set_underline(False)
    y_pos += 50

    # Strikethrough text
    font.set_strikethrough(True)
    strike_text = font.render(test_text, True, (0, 0, 0))
    screen.blit(strike_text, (50, y_pos))
    font.set_strikethrough(False)

    pygame.display.flip()

pygame.quit()

Dynamic Text Input and Display

import pygame

pygame.init()
screen = pygame.display.set_mode((800, 600))

font = pygame.font.Font(None, 36)
input_font = pygame.font.Font(None, 28)

# Text input variables
input_text = ""
messages = []

running = True
clock = pygame.time.Clock()

while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_RETURN:
                if input_text.strip():
                    messages.append(input_text)
                    if len(messages) > 15:  # Keep only last 15 messages
                        messages = messages[-15:]
                input_text = ""
            elif event.key == pygame.K_BACKSPACE:
                input_text = input_text[:-1]
        elif event.type == pygame.TEXTINPUT:
            input_text += event.text

    screen.fill((240, 240, 240))

    # Draw title
    title = font.render("Type messages and press Enter:", True, (0, 0, 0))
    screen.blit(title, (50, 20))

    # Draw input box
    input_box = pygame.Rect(50, 60, 700, 40)
    pygame.draw.rect(screen, (255, 255, 255), input_box)
    pygame.draw.rect(screen, (0, 0, 0), input_box, 2)

    # Draw input text
    if input_text:
        input_surface = input_font.render(input_text, True, (0, 0, 0))
        screen.blit(input_surface, (input_box.x + 5, input_box.y + 8))

    # Draw cursor
    if pygame.time.get_ticks() % 1000 < 500:  # Blinking cursor
        cursor_x = input_box.x + 5
        if input_text:
            cursor_x += input_font.size(input_text)[0]
        pygame.draw.line(screen, (0, 0, 0), (cursor_x, input_box.y + 5), (cursor_x, input_box.y + 35))

    # Draw message history
    y_offset = 120
    for i, message in enumerate(messages):
        # Alternate colors for readability
        color = (0, 0, 100) if i % 2 == 0 else (100, 0, 0)
        msg_surface = input_font.render(f"{i+1}: {message}", True, color)
        screen.blit(msg_surface, (50, y_offset))
        y_offset += 30

    pygame.display.flip()
    clock.tick(60)

pygame.quit()

Multi-line Text and Word Wrapping

import pygame

def render_multiline_text(text, font, color, max_width):
    """Render text with automatic word wrapping."""
    words = text.split(' ')
    lines = []
    current_line = ""

    for word in words:
        test_line = current_line + " " + word if current_line else word
        test_width = font.size(test_line)[0]

        if test_width <= max_width:
            current_line = test_line
        else:
            if current_line:
                lines.append(current_line)
            current_line = word

    if current_line:
        lines.append(current_line)

    surfaces = []
    for line in lines:
        surface = font.render(line, True, color)
        surfaces.append(surface)

    return surfaces

pygame.init()
screen = pygame.display.set_mode((800, 600))
font = pygame.font.Font(None, 24)

long_text = """This is a very long text that demonstrates how to render multiple lines of text with automatic word wrapping. The text will be split into multiple lines that fit within the specified width. This technique is useful for creating text boxes, dialog systems, and other UI elements that need to display longer pieces of text in a readable format."""

running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

    screen.fill((255, 255, 255))

    # Render multiline text
    text_surfaces = render_multiline_text(long_text, font, (0, 0, 0), 700)

    # Draw text lines
    y_offset = 50
    line_height = font.get_linesize()

    for surface in text_surfaces:
        screen.blit(surface, (50, y_offset))
        y_offset += line_height

    pygame.display.flip()

pygame.quit()

System Font Browser

import pygame

pygame.init()
screen = pygame.display.set_mode((800, 600))

# Get list of system fonts
system_fonts = pygame.font.get_fonts()
print(f"Found {len(system_fonts)} system fonts")

# Display fonts
font_size = 20
display_font = pygame.font.Font(None, 16)
sample_text = "Sample Text 123"

scroll_offset = 0
fonts_per_page = 25

running = True
clock = pygame.time.Clock()

while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_UP:
                scroll_offset = max(0, scroll_offset - 1)
            elif event.key == pygame.K_DOWN:
                scroll_offset = min(len(system_fonts) - fonts_per_page, scroll_offset + 1)

    screen.fill((255, 255, 255))

    # Title
    title = pygame.font.Font(None, 32).render("System Fonts (Use UP/DOWN to scroll)", True, (0, 0, 0))
    screen.blit(title, (50, 20))

    # Display fonts
    y_offset = 70
    for i in range(fonts_per_page):
        font_index = scroll_offset + i
        if font_index >= len(system_fonts):
            break

        font_name = system_fonts[font_index]

        # Font name
        name_surface = display_font.render(f"{font_index}: {font_name}", True, (0, 0, 0))
        screen.blit(name_surface, (50, y_offset))

        # Sample text in that font
        try:
            sample_font = pygame.font.SysFont(font_name, font_size)
            sample_surface = sample_font.render(sample_text, True, (100, 100, 100))
            screen.blit(sample_surface, (300, y_offset))
        except:
            error_surface = display_font.render("(Error loading font)", True, (255, 0, 0))
            screen.blit(error_surface, (300, y_offset))

        y_offset += 22

    pygame.display.flip()
    clock.tick(30)

pygame.quit()

Install with Tessl CLI

npx tessl i tessl/pypi-pygame

docs

advanced-drawing.md

audio-sound.md

core-system.md

drawing-shapes.md

event-input.md

game-objects.md

graphics-display.md

index.md

input-devices.md

joystick-gamepad.md

math-utils.md

surface-image.md

text-font.md

time-animation.md

transform-image.md

tile.json