#!/usr/bin/env python3

# Pygame font chart - render all available system fonts in a scrollable list
# (C) 2026, bensnotebook.net
# Released under MIT License
# v2.0

import pygame
from sys import exit
pygame.init()

BACKGROUND_COLOR = pygame.Color(0, 0, 0)
HEADER_COLOR = pygame.Color(255, 255, 166)
TEXT_COLOR = pygame.Color(255, 255, 255)
FONTS = sorted(pygame.font.get_fonts())
HEADER_FONT = pygame.font.SysFont(None, 28)

WINDOW_WIDTH = 720
WINDOW_HEIGHT = 900
pygame.display.set_caption(f"View the {len(FONTS)} available fonts for Pygame")
display = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT))
clock = pygame.time.Clock()

start_idx = 0
font_size = 20
dirty = True
while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            exit()
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_ESCAPE:
                pygame.quit()
                exit()
            
            elif event.key == pygame.K_EQUALS: # plus key
                font_size += 1
                dirty = True
            elif event.key == pygame.K_MINUS:
                font_size -= 1
                dirty = True
            elif event.key == pygame.K_UP and start_idx > 0:
                start_idx -= 2
                dirty = True
            elif event.key == pygame.K_DOWN and start_idx < len(FONTS) - 2:
                start_idx += 2
                dirty = True
        
        elif event.type == pygame.MOUSEWHEEL:
            start_idx -= event.y * 2
            if start_idx < 0:
                start_idx = 0
            dirty = True

    while dirty: # may need to re-render if we can see past the end of the list
        dirty = False
        header = pygame.Surface((WINDOW_WIDTH, WINDOW_HEIGHT)).convert()
        header_text = f"Font size: {font_size}    (adjust with +/- keys)"
        header_surface = HEADER_FONT.render(header_text, True, HEADER_COLOR)
        header_rect = header_surface.get_rect()
        header_rect.centerx = WINDOW_WIDTH // 2
        display.fill(BACKGROUND_COLOR)
        display.blit(header_surface, header_rect)
        pygame.draw.line(display,
                         HEADER_COLOR,
                         (0, header_rect.height),
                         (WINDOW_WIDTH, header_rect.height),
                         width=2)

        idx = start_idx
        y = header_rect.height + 5
        while y < WINDOW_HEIGHT - font_size:
            if idx >= len(FONTS):
                start_idx -= 1
                dirty = True
                break
            font_name = FONTS[idx]
            font = pygame.font.SysFont(font_name, font_size)
            text_surface = font.render(font_name, True, TEXT_COLOR)
            text_rect = text_surface.get_rect()
            text_rect.topleft = (5, y)
            display.blit(text_surface, text_rect)
            y += text_rect.height
            idx += 1
        
        if not dirty:
            pygame.display.flip()

    clock.tick(20)
