or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

advanced-drawing.mdaudio-sound.mdcore-system.mddrawing-shapes.mdevent-input.mdgame-objects.mdgraphics-display.mdindex.mdinput-devices.mdjoystick-gamepad.mdmath-utils.mdsurface-image.mdtext-font.mdtime-animation.mdtransform-image.md

text-font.mddocs/

0

# Text and Font Rendering

1

2

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.

3

4

## Capabilities

5

6

### Font System Management

7

8

Initialize and manage the font rendering system.

9

10

```python { .api }

11

def init() -> None:

12

"""Initialize font module."""

13

14

def quit() -> None:

15

"""Uninitialize font module."""

16

17

def get_init() -> bool:

18

"""

19

Check if font module is initialized.

20

21

Returns:

22

bool: True if font module is initialized

23

"""

24

25

def get_default_font() -> str:

26

"""

27

Get filename of default font.

28

29

Returns:

30

str: Path to default font file

31

"""

32

```

33

34

### System Fonts

35

36

Access and use system-installed fonts.

37

38

```python { .api }

39

def get_fonts() -> list[str]:

40

"""

41

Get list of available system fonts.

42

43

Returns:

44

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

45

"""

46

47

def match_font(name: str, bold: bool = False, italic: bool = False) -> str:

48

"""

49

Find system font file path by name.

50

51

Args:

52

name (str): Font name to search for

53

bold (bool): Whether to look for bold variant

54

italic (bool): Whether to look for italic variant

55

56

Returns:

57

str: Path to font file or None if not found

58

"""

59

60

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

61

"""

62

Create font from system font by name.

63

64

Args:

65

name (str): System font name

66

size (int): Font size in pixels

67

bold (bool): Use bold variant

68

italic (bool): Use italic variant

69

70

Returns:

71

pygame.font.Font: Font object

72

"""

73

```

74

75

### Font Class

76

77

Main font object for rendering text with various styling options.

78

79

```python { .api }

80

class Font:

81

def __init__(self, filename, size: int):

82

"""

83

Create font from file or use default font.

84

85

Args:

86

filename: Font file path or None for default font

87

size (int): Font size in pixels

88

"""

89

90

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

91

"""

92

Render text to a surface.

93

94

Args:

95

text (str): Text to render

96

antialias (bool): Use antialiasing for smoother text

97

color: Text color

98

background: Background color (None for transparent)

99

100

Returns:

101

pygame.Surface: Surface containing rendered text

102

"""

103

104

def size(self, text: str) -> tuple[int, int]:

105

"""

106

Get dimensions of text if it were rendered.

107

108

Args:

109

text (str): Text to measure

110

111

Returns:

112

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

113

"""

114

115

def get_height(self) -> int:

116

"""

117

Get height of font in pixels.

118

119

Returns:

120

int: Font height including line spacing

121

"""

122

123

def get_linesize(self) -> int:

124

"""

125

Get recommended line spacing.

126

127

Returns:

128

int: Pixels between lines

129

"""

130

131

def get_ascent(self) -> int:

132

"""

133

Get font ascent (height above baseline).

134

135

Returns:

136

int: Pixels above baseline

137

"""

138

139

def get_descent(self) -> int:

140

"""

141

Get font descent (height below baseline).

142

143

Returns:

144

int: Pixels below baseline

145

"""

146

147

def metrics(self, text: str) -> list:

148

"""

149

Get metrics for each character in text.

150

151

Args:

152

text (str): Text to analyze

153

154

Returns:

155

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

156

"""

157

158

def get_bold(self) -> bool:

159

"""

160

Check if font is bold.

161

162

Returns:

163

bool: True if font is bold

164

"""

165

166

def set_bold(self, bold: bool) -> None:

167

"""

168

Set font bold style.

169

170

Args:

171

bold (bool): True for bold text

172

"""

173

174

def get_italic(self) -> bool:

175

"""

176

Check if font is italic.

177

178

Returns:

179

bool: True if font is italic

180

"""

181

182

def set_italic(self, italic: bool) -> None:

183

"""

184

Set font italic style.

185

186

Args:

187

italic (bool): True for italic text

188

"""

189

190

def get_underline(self) -> bool:

191

"""

192

Check if font is underlined.

193

194

Returns:

195

bool: True if font is underlined

196

"""

197

198

def set_underline(self, underline: bool) -> None:

199

"""

200

Set font underline style.

201

202

Args:

203

underline (bool): True for underlined text

204

"""

205

206

def get_strikethrough(self) -> bool:

207

"""

208

Check if font has strikethrough.

209

210

Returns:

211

bool: True if font has strikethrough

212

"""

213

214

def set_strikethrough(self, strikethrough: bool) -> None:

215

"""

216

Set font strikethrough style.

217

218

Args:

219

strikethrough (bool): True for strikethrough text

220

"""

221

```

222

223

### Advanced Font Rendering (FreeType)

224

225

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

226

227

```python { .api }

228

# pygame.freetype module (if available)

229

def init(cache_size: int = 64, resolution: int = 72) -> None:

230

"""

231

Initialize FreeType font system.

232

233

Args:

234

cache_size (int): Number of fonts to cache

235

resolution (int): DPI resolution

236

"""

237

238

def quit() -> None:

239

"""Uninitialize FreeType system."""

240

241

def get_init() -> bool:

242

"""

243

Check if FreeType is initialized.

244

245

Returns:

246

bool: True if initialized

247

"""

248

249

class Font:

250

def __init__(self, file, size: int = 0, font_index: int = 0, resolution: int = 0, ucs4: bool = False):

251

"""

252

Create FreeType font object.

253

254

Args:

255

file: Font file path or file object

256

size (int): Font size (0 for scalable)

257

font_index (int): Font index in collection

258

resolution (int): DPI resolution

259

ucs4 (bool): Enable UCS-4 character encoding

260

"""

261

262

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

263

"""

264

Render text with advanced options.

265

266

Args:

267

text (str): Text to render

268

fgcolor: Foreground color

269

bgcolor: Background color

270

style (int): Style flags (STYLE_BOLD, etc.)

271

rotation (int): Rotation angle in degrees

272

size (int): Font size override

273

274

Returns:

275

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

276

"""

277

278

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:

279

"""

280

Render text directly to a surface.

281

282

Args:

283

surf (pygame.Surface): Destination surface

284

dest: Position to render at

285

text (str): Text to render

286

(other args same as render())

287

288

Returns:

289

pygame.Rect: Rectangle where text was rendered

290

"""

291

292

def get_rect(self, text: str, style: int = 0, rotation: int = 0, size: int = 0) -> pygame.Rect:

293

"""

294

Get rectangle that would contain rendered text.

295

296

Args:

297

text (str): Text to measure

298

style (int): Style flags

299

rotation (int): Rotation angle

300

size (int): Font size

301

302

Returns:

303

pygame.Rect: Bounding rectangle

304

"""

305

306

def get_metrics(self, text: str, size: int = 0) -> list:

307

"""

308

Get detailed character metrics.

309

310

Args:

311

text (str): Text to analyze

312

size (int): Font size

313

314

Returns:

315

list: Character metric data

316

"""

317

```

318

319

## Font Style Constants

320

321

```python { .api }

322

# Style flags for FreeType fonts

323

STYLE_NORMAL: int

324

STYLE_UNDERLINE: int

325

STYLE_OBLIQUE: int

326

STYLE_STRONG: int

327

STYLE_WIDE: int

328

STYLE_DEFAULT: int

329

```

330

331

## Usage Examples

332

333

### Basic Text Rendering

334

335

```python

336

import pygame

337

338

pygame.init()

339

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

340

341

# Create font objects

342

default_font = pygame.font.Font(None, 36) # Default font

343

system_font = pygame.font.SysFont('arial', 24) # System font

344

345

# Try to load custom font

346

try:

347

custom_font = pygame.font.Font('custom_font.ttf', 48)

348

except:

349

custom_font = default_font

350

351

running = True

352

while running:

353

for event in pygame.event.get():

354

if event.type == pygame.QUIT:

355

running = False

356

357

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

358

359

# Render different text samples

360

text1 = default_font.render("Default Font", True, (0, 0, 0))

361

screen.blit(text1, (50, 50))

362

363

text2 = system_font.render("System Arial Font", True, (255, 0, 0))

364

screen.blit(text2, (50, 100))

365

366

text3 = custom_font.render("Custom Font", True, (0, 0, 255))

367

screen.blit(text3, (50, 150))

368

369

# Text with background

370

text4 = default_font.render("Text with Background", True, (255, 255, 255), (0, 128, 0))

371

screen.blit(text4, (50, 200))

372

373

pygame.display.flip()

374

375

pygame.quit()

376

```

377

378

### Font Styling and Metrics

379

380

```python

381

import pygame

382

383

pygame.init()

384

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

385

386

# Create font with different styles

387

font = pygame.font.SysFont('arial', 32)

388

389

# Test text

390

test_text = "Styled Text Example"

391

392

# Get text dimensions

393

text_width, text_height = font.size(test_text)

394

print(f"Text dimensions: {text_width} x {text_height}")

395

396

# Get font metrics

397

print(f"Font height: {font.get_height()}")

398

print(f"Font ascent: {font.get_ascent()}")

399

print(f"Font descent: {font.get_descent()}")

400

print(f"Line size: {font.get_linesize()}")

401

402

running = True

403

while running:

404

for event in pygame.event.get():

405

if event.type == pygame.QUIT:

406

running = False

407

408

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

409

410

y_pos = 50

411

412

# Normal text

413

normal_text = font.render(test_text, True, (0, 0, 0))

414

screen.blit(normal_text, (50, y_pos))

415

y_pos += 50

416

417

# Bold text

418

font.set_bold(True)

419

bold_text = font.render(test_text, True, (0, 0, 0))

420

screen.blit(bold_text, (50, y_pos))

421

font.set_bold(False)

422

y_pos += 50

423

424

# Italic text

425

font.set_italic(True)

426

italic_text = font.render(test_text, True, (0, 0, 0))

427

screen.blit(italic_text, (50, y_pos))

428

font.set_italic(False)

429

y_pos += 50

430

431

# Underlined text

432

font.set_underline(True)

433

underline_text = font.render(test_text, True, (0, 0, 0))

434

screen.blit(underline_text, (50, y_pos))

435

font.set_underline(False)

436

y_pos += 50

437

438

# Strikethrough text

439

font.set_strikethrough(True)

440

strike_text = font.render(test_text, True, (0, 0, 0))

441

screen.blit(strike_text, (50, y_pos))

442

font.set_strikethrough(False)

443

444

pygame.display.flip()

445

446

pygame.quit()

447

```

448

449

### Dynamic Text Input and Display

450

451

```python

452

import pygame

453

454

pygame.init()

455

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

456

457

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

458

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

459

460

# Text input variables

461

input_text = ""

462

messages = []

463

464

running = True

465

clock = pygame.time.Clock()

466

467

while running:

468

for event in pygame.event.get():

469

if event.type == pygame.QUIT:

470

running = False

471

elif event.type == pygame.KEYDOWN:

472

if event.key == pygame.K_RETURN:

473

if input_text.strip():

474

messages.append(input_text)

475

if len(messages) > 15: # Keep only last 15 messages

476

messages = messages[-15:]

477

input_text = ""

478

elif event.key == pygame.K_BACKSPACE:

479

input_text = input_text[:-1]

480

elif event.type == pygame.TEXTINPUT:

481

input_text += event.text

482

483

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

484

485

# Draw title

486

title = font.render("Type messages and press Enter:", True, (0, 0, 0))

487

screen.blit(title, (50, 20))

488

489

# Draw input box

490

input_box = pygame.Rect(50, 60, 700, 40)

491

pygame.draw.rect(screen, (255, 255, 255), input_box)

492

pygame.draw.rect(screen, (0, 0, 0), input_box, 2)

493

494

# Draw input text

495

if input_text:

496

input_surface = input_font.render(input_text, True, (0, 0, 0))

497

screen.blit(input_surface, (input_box.x + 5, input_box.y + 8))

498

499

# Draw cursor

500

if pygame.time.get_ticks() % 1000 < 500: # Blinking cursor

501

cursor_x = input_box.x + 5

502

if input_text:

503

cursor_x += input_font.size(input_text)[0]

504

pygame.draw.line(screen, (0, 0, 0), (cursor_x, input_box.y + 5), (cursor_x, input_box.y + 35))

505

506

# Draw message history

507

y_offset = 120

508

for i, message in enumerate(messages):

509

# Alternate colors for readability

510

color = (0, 0, 100) if i % 2 == 0 else (100, 0, 0)

511

msg_surface = input_font.render(f"{i+1}: {message}", True, color)

512

screen.blit(msg_surface, (50, y_offset))

513

y_offset += 30

514

515

pygame.display.flip()

516

clock.tick(60)

517

518

pygame.quit()

519

```

520

521

### Multi-line Text and Word Wrapping

522

523

```python

524

import pygame

525

526

def render_multiline_text(text, font, color, max_width):

527

"""Render text with automatic word wrapping."""

528

words = text.split(' ')

529

lines = []

530

current_line = ""

531

532

for word in words:

533

test_line = current_line + " " + word if current_line else word

534

test_width = font.size(test_line)[0]

535

536

if test_width <= max_width:

537

current_line = test_line

538

else:

539

if current_line:

540

lines.append(current_line)

541

current_line = word

542

543

if current_line:

544

lines.append(current_line)

545

546

surfaces = []

547

for line in lines:

548

surface = font.render(line, True, color)

549

surfaces.append(surface)

550

551

return surfaces

552

553

pygame.init()

554

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

555

font = pygame.font.Font(None, 24)

556

557

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."""

558

559

running = True

560

while running:

561

for event in pygame.event.get():

562

if event.type == pygame.QUIT:

563

running = False

564

565

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

566

567

# Render multiline text

568

text_surfaces = render_multiline_text(long_text, font, (0, 0, 0), 700)

569

570

# Draw text lines

571

y_offset = 50

572

line_height = font.get_linesize()

573

574

for surface in text_surfaces:

575

screen.blit(surface, (50, y_offset))

576

y_offset += line_height

577

578

pygame.display.flip()

579

580

pygame.quit()

581

```

582

583

### System Font Browser

584

585

```python

586

import pygame

587

588

pygame.init()

589

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

590

591

# Get list of system fonts

592

system_fonts = pygame.font.get_fonts()

593

print(f"Found {len(system_fonts)} system fonts")

594

595

# Display fonts

596

font_size = 20

597

display_font = pygame.font.Font(None, 16)

598

sample_text = "Sample Text 123"

599

600

scroll_offset = 0

601

fonts_per_page = 25

602

603

running = True

604

clock = pygame.time.Clock()

605

606

while running:

607

for event in pygame.event.get():

608

if event.type == pygame.QUIT:

609

running = False

610

elif event.type == pygame.KEYDOWN:

611

if event.key == pygame.K_UP:

612

scroll_offset = max(0, scroll_offset - 1)

613

elif event.key == pygame.K_DOWN:

614

scroll_offset = min(len(system_fonts) - fonts_per_page, scroll_offset + 1)

615

616

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

617

618

# Title

619

title = pygame.font.Font(None, 32).render("System Fonts (Use UP/DOWN to scroll)", True, (0, 0, 0))

620

screen.blit(title, (50, 20))

621

622

# Display fonts

623

y_offset = 70

624

for i in range(fonts_per_page):

625

font_index = scroll_offset + i

626

if font_index >= len(system_fonts):

627

break

628

629

font_name = system_fonts[font_index]

630

631

# Font name

632

name_surface = display_font.render(f"{font_index}: {font_name}", True, (0, 0, 0))

633

screen.blit(name_surface, (50, y_offset))

634

635

# Sample text in that font

636

try:

637

sample_font = pygame.font.SysFont(font_name, font_size)

638

sample_surface = sample_font.render(sample_text, True, (100, 100, 100))

639

screen.blit(sample_surface, (300, y_offset))

640

except:

641

error_surface = display_font.render("(Error loading font)", True, (255, 0, 0))

642

screen.blit(error_surface, (300, y_offset))

643

644

y_offset += 22

645

646

pygame.display.flip()

647

clock.tick(30)

648

649

pygame.quit()

650

```