or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

audio.mdevents-input.mdfile-io.mdfonts-text.mdgraphics-rendering.mdimage-processing.mdindex.mdjoystick-input.mdsprites-animation.mdsystem-utils.mdtimer.mdwindow-display.md

fonts-text.mddocs/

0

# Font and Text Rendering

1

2

TrueType font loading and text rendering through SDL2_ttf integration and bitmap font support. PySDL2 provides both low-level TTF functions and high-level font management classes.

3

4

## Capabilities

5

6

### TTF Initialization and Management

7

8

Core functions for initializing and managing the TTF system.

9

10

```python { .api }

11

def TTF_Init() -> int:

12

"""

13

Initialize TTF system.

14

15

Returns:

16

0 on success, -1 on failure

17

"""

18

19

def TTF_Quit() -> None:

20

"""Shut down TTF system and free resources."""

21

22

def TTF_WasInit() -> int:

23

"""Check if TTF system is initialized."""

24

25

def TTF_GetError() -> bytes:

26

"""Get last TTF error message."""

27

28

def TTF_SetError(fmt: bytes) -> None:

29

"""Set TTF error message."""

30

```

31

32

### Font Loading and Management

33

34

Functions for loading and managing TrueType fonts.

35

36

```python { .api }

37

def TTF_OpenFont(file: bytes, ptsize: int) -> TTF_Font:

38

"""

39

Load font from file at specified point size.

40

41

Parameters:

42

- file: path to font file as bytes

43

- ptsize: font size in points

44

45

Returns:

46

TTF_Font object or None on failure

47

"""

48

49

def TTF_OpenFontIndex(file: bytes, ptsize: int, index: int) -> TTF_Font:

50

"""

51

Load font from file at specified point size and face index.

52

53

Parameters:

54

- file: path to font file as bytes

55

- ptsize: font size in points

56

- index: face index in font file

57

58

Returns:

59

TTF_Font object or None on failure

60

"""

61

62

def TTF_OpenFontRW(src: SDL_RWops, freesrc: int, ptsize: int) -> TTF_Font:

63

"""Load font from SDL_RWops source."""

64

65

def TTF_OpenFontIndexRW(src: SDL_RWops, freesrc: int, ptsize: int, index: int) -> TTF_Font:

66

"""Load font from SDL_RWops source with face index."""

67

68

def TTF_CloseFont(font: TTF_Font) -> None:

69

"""Close font and free resources."""

70

```

71

72

### Font Metrics and Properties

73

74

Functions for querying font properties and metrics.

75

76

```python { .api }

77

def TTF_FontHeight(font: TTF_Font) -> int:

78

"""Get font height (baseline to baseline distance)."""

79

80

def TTF_FontAscent(font: TTF_Font) -> int:

81

"""Get font ascent (baseline to top)."""

82

83

def TTF_FontDescent(font: TTF_Font) -> int:

84

"""Get font descent (baseline to bottom)."""

85

86

def TTF_FontLineSkip(font: TTF_Font) -> int:

87

"""Get recommended line spacing."""

88

89

def TTF_FontFaces(font: TTF_Font) -> int:

90

"""Get number of faces in font."""

91

92

def TTF_FontFaceIsFixedWidth(font: TTF_Font) -> int:

93

"""Check if font is monospace."""

94

95

def TTF_FontFaceFamilyName(font: TTF_Font) -> bytes:

96

"""Get font family name."""

97

98

def TTF_FontFaceStyleName(font: TTF_Font) -> bytes:

99

"""Get font style name."""

100

101

def TTF_GetFontStyle(font: TTF_Font) -> int:

102

"""Get font style flags."""

103

104

def TTF_SetFontStyle(font: TTF_Font, style: int) -> None:

105

"""Set font style flags."""

106

107

def TTF_GetFontOutline(font: TTF_Font) -> int:

108

"""Get font outline thickness."""

109

110

def TTF_SetFontOutline(font: TTF_Font, outline: int) -> None:

111

"""Set font outline thickness."""

112

113

def TTF_GetFontHinting(font: TTF_Font) -> int:

114

"""Get font hinting mode."""

115

116

def TTF_SetFontHinting(font: TTF_Font, hinting: int) -> None:

117

"""Set font hinting mode."""

118

119

def TTF_GetFontKerning(font: TTF_Font) -> int:

120

"""Get font kerning enabled state."""

121

122

def TTF_SetFontKerning(font: TTF_Font, allowed: int) -> None:

123

"""Enable/disable font kerning."""

124

```

125

126

### Font Style Constants

127

128

```python { .api }

129

TTF_STYLE_NORMAL: int = 0x00 # Normal text

130

TTF_STYLE_BOLD: int = 0x01 # Bold text

131

TTF_STYLE_ITALIC: int = 0x02 # Italic text

132

TTF_STYLE_UNDERLINE: int = 0x04 # Underlined text

133

TTF_STYLE_STRIKETHROUGH: int = 0x08 # Strikethrough text

134

135

# Hinting modes

136

TTF_HINTING_NORMAL: int = 0 # Normal hinting

137

TTF_HINTING_LIGHT: int = 1 # Light hinting

138

TTF_HINTING_MONO: int = 2 # Monochrome hinting

139

TTF_HINTING_NONE: int = 3 # No hinting

140

```

141

142

### Text Measurement

143

144

Functions for measuring text dimensions before rendering.

145

146

```python { .api }

147

def TTF_SizeText(font: TTF_Font, text: bytes, w: ctypes.POINTER(ctypes.c_int),

148

h: ctypes.POINTER(ctypes.c_int)) -> int:

149

"""

150

Calculate size of text when rendered.

151

152

Parameters:

153

- font: font to use

154

- text: text to measure as bytes

155

- w, h: pointers to store width and height

156

157

Returns:

158

0 on success, -1 on failure

159

"""

160

161

def TTF_SizeUTF8(font: TTF_Font, text: bytes, w: ctypes.POINTER(ctypes.c_int),

162

h: ctypes.POINTER(ctypes.c_int)) -> int:

163

"""Calculate size of UTF-8 text when rendered."""

164

165

def TTF_SizeUNICODE(font: TTF_Font, text: ctypes.POINTER(ctypes.c_uint16),

166

w: ctypes.POINTER(ctypes.c_int), h: ctypes.POINTER(ctypes.c_int)) -> int:

167

"""Calculate size of Unicode text when rendered."""

168

169

def TTF_MeasureText(font: TTF_Font, text: bytes, measure_width: int,

170

extent: ctypes.POINTER(ctypes.c_int), count: ctypes.POINTER(ctypes.c_int)) -> int:

171

"""Measure text for word wrapping."""

172

173

def TTF_MeasureUTF8(font: TTF_Font, text: bytes, measure_width: int,

174

extent: ctypes.POINTER(ctypes.c_int), count: ctypes.POINTER(ctypes.c_int)) -> int:

175

"""Measure UTF-8 text for word wrapping."""

176

177

def TTF_MeasureUNICODE(font: TTF_Font, text: ctypes.POINTER(ctypes.c_uint16), measure_width: int,

178

extent: ctypes.POINTER(ctypes.c_int), count: ctypes.POINTER(ctypes.c_int)) -> int:

179

"""Measure Unicode text for word wrapping."""

180

```

181

182

### Text Rendering

183

184

Functions for rendering text to surfaces.

185

186

```python { .api }

187

def TTF_RenderText_Solid(font: TTF_Font, text: bytes, fg: SDL_Color) -> SDL_Surface:

188

"""

189

Render text in solid color.

190

191

Parameters:

192

- font: font to use

193

- text: text to render as bytes

194

- fg: foreground color

195

196

Returns:

197

SDL_Surface containing rendered text or None on failure

198

"""

199

200

def TTF_RenderUTF8_Solid(font: TTF_Font, text: bytes, fg: SDL_Color) -> SDL_Surface:

201

"""Render UTF-8 text in solid color."""

202

203

def TTF_RenderUNICODE_Solid(font: TTF_Font, text: ctypes.POINTER(ctypes.c_uint16), fg: SDL_Color) -> SDL_Surface:

204

"""Render Unicode text in solid color."""

205

206

def TTF_RenderText_Shaded(font: TTF_Font, text: bytes, fg: SDL_Color, bg: SDL_Color) -> SDL_Surface:

207

"""

208

Render text with background color (shaded).

209

210

Parameters:

211

- font: font to use

212

- text: text to render as bytes

213

- fg: foreground color

214

- bg: background color

215

216

Returns:

217

SDL_Surface containing rendered text or None on failure

218

"""

219

220

def TTF_RenderUTF8_Shaded(font: TTF_Font, text: bytes, fg: SDL_Color, bg: SDL_Color) -> SDL_Surface:

221

"""Render UTF-8 text with background color."""

222

223

def TTF_RenderUNICODE_Shaded(font: TTF_Font, text: ctypes.POINTER(ctypes.c_uint16),

224

fg: SDL_Color, bg: SDL_Color) -> SDL_Surface:

225

"""Render Unicode text with background color."""

226

227

def TTF_RenderText_Blended(font: TTF_Font, text: bytes, fg: SDL_Color) -> SDL_Surface:

228

"""

229

Render anti-aliased text (blended).

230

231

Parameters:

232

- font: font to use

233

- text: text to render as bytes

234

- fg: foreground color

235

236

Returns:

237

SDL_Surface containing rendered text or None on failure

238

"""

239

240

def TTF_RenderUTF8_Blended(font: TTF_Font, text: bytes, fg: SDL_Color) -> SDL_Surface:

241

"""Render anti-aliased UTF-8 text."""

242

243

def TTF_RenderUNICODE_Blended(font: TTF_Font, text: ctypes.POINTER(ctypes.c_uint16), fg: SDL_Color) -> SDL_Surface:

244

"""Render anti-aliased Unicode text."""

245

246

def TTF_RenderText_Blended_Wrapped(font: TTF_Font, text: bytes, fg: SDL_Color, wrapLength: int) -> SDL_Surface:

247

"""

248

Render anti-aliased text with word wrapping.

249

250

Parameters:

251

- font: font to use

252

- text: text to render as bytes

253

- fg: foreground color

254

- wrapLength: maximum line width in pixels

255

256

Returns:

257

SDL_Surface containing rendered text or None on failure

258

"""

259

260

def TTF_RenderUTF8_Blended_Wrapped(font: TTF_Font, text: bytes, fg: SDL_Color, wrapLength: int) -> SDL_Surface:

261

"""Render anti-aliased UTF-8 text with word wrapping."""

262

263

def TTF_RenderUNICODE_Blended_Wrapped(font: TTF_Font, text: ctypes.POINTER(ctypes.c_uint16),

264

fg: SDL_Color, wrapLength: int) -> SDL_Surface:

265

"""Render anti-aliased Unicode text with word wrapping."""

266

```

267

268

### High-Level Font Classes

269

270

Extension module classes for simplified font management.

271

272

```python { .api }

273

class FontTTF:

274

"""High-level TrueType font class."""

275

276

def __init__(self, font_path: str, size: int, index: int = 0):

277

"""

278

Load TrueType font.

279

280

Parameters:

281

- font_path: path to font file

282

- size: font size in points

283

- index: face index for multi-face fonts

284

"""

285

286

def render(self, text: str, color: tuple[int, int, int] = (255, 255, 255),

287

bg: tuple[int, int, int] = None) -> SDL_Surface:

288

"""

289

Render text to surface.

290

291

Parameters:

292

- text: text string to render

293

- color: RGB foreground color (0-255 each)

294

- bg: RGB background color (None for transparent)

295

296

Returns:

297

SDL_Surface containing rendered text

298

"""

299

300

def render_blended(self, text: str, color: tuple[int, int, int] = (255, 255, 255)) -> SDL_Surface:

301

"""

302

Render anti-aliased text.

303

304

Parameters:

305

- text: text string to render

306

- color: RGB foreground color

307

308

Returns:

309

SDL_Surface containing rendered text

310

"""

311

312

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

313

"""

314

Get text size when rendered.

315

316

Parameters:

317

- text: text to measure

318

319

Returns:

320

(width, height) tuple in pixels

321

"""

322

323

@property

324

def height(self) -> int:

325

"""Get font height."""

326

327

@property

328

def ascent(self) -> int:

329

"""Get font ascent."""

330

331

@property

332

def descent(self) -> int:

333

"""Get font descent."""

334

335

@property

336

def line_skip(self) -> int:

337

"""Get recommended line spacing."""

338

339

class FontManager:

340

"""Manager for multiple fonts with caching."""

341

342

def __init__(self, font_path: str, alias: str = None, size: int = 16):

343

"""

344

Create font manager.

345

346

Parameters:

347

- font_path: default font file path

348

- alias: alias for default font

349

- size: default font size

350

"""

351

352

def add(self, font_path: str, alias: str = None, size: int = 16) -> None:

353

"""

354

Add font to manager.

355

356

Parameters:

357

- font_path: path to font file

358

- alias: font alias (uses filename if None)

359

- size: font size in points

360

"""

361

362

def get(self, alias: str, size: int = 16) -> FontTTF:

363

"""

364

Get font by alias and size.

365

366

Parameters:

367

- alias: font alias

368

- size: font size in points

369

370

Returns:

371

FontTTF object

372

"""

373

374

def close(self) -> None:

375

"""Close all fonts and free resources."""

376

```

377

378

### Bitmap Font Support

379

380

Simple bitmap font class for pixel-perfect text rendering.

381

382

```python { .api }

383

class BitmapFont:

384

"""Bitmap font class for pixel-perfect text rendering."""

385

386

def __init__(self, surface: SDL_Surface, size: tuple[int, int], mapping: list[str] = None):

387

"""

388

Create bitmap font from surface.

389

390

Parameters:

391

- surface: surface containing font characters

392

- size: (width, height) of each character

393

- mapping: list of characters in font surface order

394

"""

395

396

def render(self, text: str, bpp: int = None) -> SDL_Surface:

397

"""

398

Render text using bitmap font.

399

400

Parameters:

401

- text: text to render

402

- bpp: bits per pixel for rendered surface

403

404

Returns:

405

SDL_Surface containing rendered text

406

"""

407

408

def can_render(self, text: str) -> bool:

409

"""

410

Check if font can render all characters in text.

411

412

Parameters:

413

- text: text to check

414

415

Returns:

416

True if all characters can be rendered

417

"""

418

419

@property

420

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

421

"""Get character size as (width, height) tuple."""

422

```

423

424

### Text Direction Support

425

426

Constants and functions for text direction and rendering.

427

428

```python { .api }

429

# Text direction constants (for advanced text layout)

430

HB_DIRECTION_LTR: int = 0 # Left-to-right

431

HB_DIRECTION_RTL: int = 1 # Right-to-left

432

HB_DIRECTION_TTB: int = 2 # Top-to-bottom

433

HB_DIRECTION_BTT: int = 3 # Bottom-to-top

434

435

def TTF_SetDirection(direction: int) -> int:

436

"""Set text direction for complex text layout."""

437

438

def TTF_SetScript(script: int) -> int:

439

"""Set script for complex text layout."""

440

```

441

442

## Types

443

444

```python { .api }

445

class TTF_Font:

446

"""Opaque structure representing a loaded font."""

447

448

class SDL_Color:

449

"""Color structure for text rendering."""

450

r: int # Red component (0-255)

451

g: int # Green component (0-255)

452

b: int # Blue component (0-255)

453

a: int # Alpha component (0-255)

454

```

455

456

## Usage Examples

457

458

### Basic Text Rendering

459

460

```python

461

import sdl2

462

import sdl2.sdlttf

463

import sdl2.ext

464

465

# Initialize SDL2 and TTF

466

sdl2.SDL_Init(sdl2.SDL_INIT_VIDEO)

467

sdl2.sdlttf.TTF_Init()

468

469

# Create window and renderer

470

window = sdl2.SDL_CreateWindow(b"Text Rendering",

471

sdl2.SDL_WINDOWPOS_CENTERED, sdl2.SDL_WINDOWPOS_CENTERED,

472

800, 600, sdl2.SDL_WINDOW_SHOWN)

473

renderer = sdl2.SDL_CreateRenderer(window, -1, sdl2.SDL_RENDERER_ACCELERATED)

474

475

# Load font

476

font = sdl2.sdlttf.TTF_OpenFont(b"arial.ttf", 24)

477

if not font:

478

print("Failed to load font")

479

exit(1)

480

481

# Render text

482

color = sdl2.SDL_Color(255, 255, 255, 255) # White text

483

text_surface = sdl2.sdlttf.TTF_RenderText_Blended(font, b"Hello, PySDL2!", color)

484

text_texture = sdl2.SDL_CreateTextureFromSurface(renderer, text_surface)

485

sdl2.SDL_FreeSurface(text_surface)

486

487

# Get text dimensions

488

text_w = ctypes.c_int()

489

text_h = ctypes.c_int()

490

sdl2.SDL_QueryTexture(text_texture, None, None, text_w, text_h)

491

492

# Main loop

493

running = True

494

event = sdl2.SDL_Event()

495

496

while running:

497

while sdl2.SDL_PollEvent(event):

498

if event.type == sdl2.SDL_QUIT:

499

running = False

500

501

# Clear screen

502

sdl2.SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255)

503

sdl2.SDL_RenderClear(renderer)

504

505

# Render text centered

506

dest_rect = sdl2.SDL_Rect(

507

(800 - text_w.value) // 2,

508

(600 - text_h.value) // 2,

509

text_w.value,

510

text_h.value

511

)

512

sdl2.SDL_RenderCopy(renderer, text_texture, None, dest_rect)

513

514

# Present frame

515

sdl2.SDL_RenderPresent(renderer)

516

517

# Cleanup

518

sdl2.SDL_DestroyTexture(text_texture)

519

sdl2.sdlttf.TTF_CloseFont(font)

520

sdl2.SDL_DestroyRenderer(renderer)

521

sdl2.SDL_DestroyWindow(window)

522

sdl2.sdlttf.TTF_Quit()

523

sdl2.SDL_Quit()

524

```

525

526

### High-Level Font Usage

527

528

```python

529

import sdl2.ext

530

531

# Initialize SDL2 extensions

532

sdl2.ext.init()

533

534

# Create window and renderer

535

window = sdl2.ext.Window("High-Level Text", size=(800, 600))

536

window.show()

537

renderer = sdl2.ext.Renderer(window)

538

539

# Create font manager

540

font_manager = sdl2.ext.FontManager("arial.ttf", "default", 24)

541

font_manager.add("times.ttf", "serif", 18)

542

font_manager.add("courier.ttf", "mono", 16)

543

544

# Get fonts

545

default_font = font_manager.get("default")

546

title_font = font_manager.get("default", 36) # Larger size

547

mono_font = font_manager.get("mono")

548

549

# Render different text styles

550

title_surface = title_font.render("PySDL2 Text Demo", (255, 255, 0))

551

body_surface = default_font.render("This is regular text.", (255, 255, 255))

552

code_surface = mono_font.render("print('Hello, World!')", (0, 255, 0))

553

554

# Convert surfaces to textures

555

title_texture = sdl2.ext.Texture(renderer, title_surface)

556

body_texture = sdl2.ext.Texture(renderer, body_surface)

557

code_texture = sdl2.ext.Texture(renderer, code_surface)

558

559

# Free surfaces (textures have copies)

560

sdl2.SDL_FreeSurface(title_surface)

561

sdl2.SDL_FreeSurface(body_surface)

562

sdl2.SDL_FreeSurface(code_surface)

563

564

# Main loop

565

running = True

566

while running:

567

events = sdl2.ext.get_events()

568

for event in events:

569

if event.type == sdl2.SDL_QUIT:

570

running = False

571

572

# Clear screen

573

renderer.clear((50, 50, 50))

574

575

# Render text at different positions

576

renderer.copy(title_texture, dstrect=sdl2.SDL_Rect(50, 50, 0, 0))

577

renderer.copy(body_texture, dstrect=sdl2.SDL_Rect(50, 150, 0, 0))

578

renderer.copy(code_texture, dstrect=sdl2.SDL_Rect(50, 200, 0, 0))

579

580

renderer.present()

581

582

# Cleanup

583

font_manager.close()

584

sdl2.ext.quit()

585

```

586

587

### Word Wrapping and Multi-line Text

588

589

```python

590

import sdl2

591

import sdl2.sdlttf

592

593

# Initialize

594

sdl2.SDL_Init(sdl2.SDL_INIT_VIDEO)

595

sdl2.sdlttf.TTF_Init()

596

597

# Create window

598

window = sdl2.SDL_CreateWindow(b"Word Wrapping",

599

sdl2.SDL_WINDOWPOS_CENTERED, sdl2.SDL_WINDOWPOS_CENTERED,

600

600, 400, sdl2.SDL_WINDOW_SHOWN)

601

renderer = sdl2.SDL_CreateRenderer(window, -1, sdl2.SDL_RENDERER_ACCELERATED)

602

603

# Load font

604

font = sdl2.sdlttf.TTF_OpenFont(b"arial.ttf", 18)

605

606

# Long text for word wrapping

607

long_text = b"This is a very long text that will be wrapped across multiple lines to demonstrate the word wrapping functionality of SDL2_ttf."

608

609

# Render wrapped text

610

color = sdl2.SDL_Color(255, 255, 255, 255)

611

wrapped_surface = sdl2.sdlttf.TTF_RenderUTF8_Blended_Wrapped(font, long_text, color, 500)

612

wrapped_texture = sdl2.SDL_CreateTextureFromSurface(renderer, wrapped_surface)

613

sdl2.SDL_FreeSurface(wrapped_surface)

614

615

# Main loop

616

running = True

617

event = sdl2.SDL_Event()

618

619

while running:

620

while sdl2.SDL_PollEvent(event):

621

if event.type == sdl2.SDL_QUIT:

622

running = False

623

624

# Clear and render

625

sdl2.SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255)

626

sdl2.SDL_RenderClear(renderer)

627

628

# Render wrapped text

629

dest_rect = sdl2.SDL_Rect(50, 50, 500, 300)

630

sdl2.SDL_RenderCopy(renderer, wrapped_texture, None, dest_rect)

631

632

sdl2.SDL_RenderPresent(renderer)

633

634

# Cleanup

635

sdl2.SDL_DestroyTexture(wrapped_texture)

636

sdl2.sdlttf.TTF_CloseFont(font)

637

sdl2.SDL_DestroyRenderer(renderer)

638

sdl2.SDL_DestroyWindow(window)

639

sdl2.sdlttf.TTF_Quit()

640

sdl2.SDL_Quit()

641

```

642

643

### Bitmap Font Usage

644

645

```python

646

import sdl2.ext

647

648

# Initialize

649

sdl2.ext.init()

650

window = sdl2.ext.Window("Bitmap Font", size=(640, 480))

651

window.show()

652

653

# Load bitmap font surface (assumes 16x16 character grid)

654

font_surface = sdl2.SDL_LoadBMP(b"bitmap_font.bmp")

655

656

# Character mapping for ASCII printable characters

657

ascii_chars = [chr(i) for i in range(32, 127)]

658

659

# Create bitmap font

660

bitmap_font = sdl2.ext.BitmapFont(font_surface, (8, 16), ascii_chars)

661

662

# Render text with bitmap font

663

text = "Bitmap Font Text!"

664

rendered_surface = bitmap_font.render(text)

665

666

# Main loop

667

running = True

668

while running:

669

events = sdl2.ext.get_events()

670

for event in events:

671

if event.type == sdl2.SDL_QUIT:

672

running = False

673

674

# Clear screen and blit bitmap text

675

window_surface = sdl2.SDL_GetWindowSurface(window.window)

676

sdl2.SDL_FillRect(window_surface, None, 0) # Black background

677

678

dest_rect = sdl2.SDL_Rect(10, 10, 0, 0)

679

sdl2.SDL_BlitSurface(rendered_surface, None, window_surface, dest_rect)

680

681

sdl2.SDL_UpdateWindowSurface(window.window)

682

683

# Cleanup

684

sdl2.SDL_FreeSurface(rendered_surface)

685

sdl2.SDL_FreeSurface(font_surface)

686

sdl2.ext.quit()

687

```