or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

3d-models.mdapp-clock.mdaudio-video.mdgraphics-rendering.mdgui.mdimages-textures.mdindex.mdinput-devices.mdmath.mdopengl.mdresource-management.mdsprites-shapes.mdtext-rendering.mdwindowing.md
IMPROVEMENTS.md

text-rendering.mddocs/

0

# Text Rendering

1

2

Font loading, text labels, layouts, and editing with caret support.

3

4

## Quick Reference

5

6

```python

7

# Load font

8

font = pyglet.font.load('Arial', 16, bold=False, italic=False)

9

pyglet.font.add_file('custom.ttf') # Add custom font

10

11

# Simple label

12

label = pyglet.text.Label(

13

'Hello World',

14

font_name='Arial', font_size=16,

15

x=10, y=10,

16

color=(255, 255, 255, 255),

17

batch=batch

18

)

19

20

# HTML text

21

doc = pyglet.text.decode_html('<b>Bold</b> and <i>italic</i>')

22

layout = pyglet.text.layout.TextLayout(doc, width=200, height=100)

23

```

24

25

## Font Loading

26

27

```python

28

def pyglet.font.load(name=None, size=None, weight='normal',

29

italic=False, stretch=False, dpi=None):

30

"""

31

Args:

32

name: Font family name or list of names (None = default)

33

size: Font size in points (None = 12)

34

weight: 'normal', 'bold', 'light', etc.

35

italic: True/False or 'oblique'

36

stretch: True/False or 'condensed', 'expanded'

37

dpi: DPI for size calculation (default: 96)

38

"""

39

40

def pyglet.font.add_file(font: str | BinaryIO | bytes):

41

"""Add font file to search path"""

42

43

def pyglet.font.add_directory(directory: str):

44

"""Add directory of .ttf files"""

45

46

def pyglet.font.have_font(name: str) -> bool:

47

"""Check if font available"""

48

```

49

50

## Text Label

51

52

```python

53

class pyglet.text.Label:

54

__init__(text='', font_name=None, font_size=None, weight='normal',

55

italic=False, color=(255,255,255,255), x=0, y=0,

56

width=None, height=None, anchor_x='left', anchor_y='baseline',

57

align='left', multiline=False, dpi=None, batch=None, group=None)

58

59

# Properties

60

text: str

61

font_name: str

62

font_size: float

63

bold, italic: bool

64

color: tuple # RGBA (0-255)

65

x, y: float

66

width, height: float | None

67

anchor_x: str # 'left', 'center', 'right'

68

anchor_y: str # 'top', 'center', 'baseline', 'bottom'

69

multiline: bool

70

71

# Methods

72

def draw()

73

```

74

75

**Anchor Points:**

76

- `anchor_x`: 'left', 'center', 'right'

77

- `anchor_y`: 'top', 'center', 'baseline', 'bottom'

78

79

**Alignment (multiline):**

80

- `align`: 'left', 'center', 'right'

81

82

## Text Layouts

83

84

```python

85

# Basic layout

86

layout = pyglet.text.layout.TextLayout(document, width=None, height=None,

87

multiline=False, dpi=None, batch=None, group=None)

88

89

# Scrollable layout

90

layout = pyglet.text.layout.ScrollableTextLayout(document, width, height,

91

multiline=False, dpi=None, batch=None, group=None)

92

93

# Incremental layout (large documents)

94

layout = pyglet.text.layout.IncrementalTextLayout(document, width, height,

95

multiline=False, dpi=None, batch=None, group=None)

96

```

97

98

## HTML Text

99

100

```python

101

# Decode HTML

102

document = pyglet.text.decode_html(html_string, location=None)

103

104

# Decode HTML from file

105

with open('text.html') as f:

106

document = pyglet.text.decode_html(f.read())

107

108

# Supported tags: <b>, <i>, <u>, <font>, <br>, <p>, <span>

109

html = '''

110

<font face="Arial" size="16" color="#FF0000">

111

<b>Bold red text</b><br/>

112

<i>Italic text</i>

113

</font>

114

'''

115

document = pyglet.text.decode_html(html)

116

layout = pyglet.text.layout.TextLayout(document, width=400, height=200)

117

layout.x = 10

118

layout.y = 10

119

120

@window.event

121

def on_draw():

122

window.clear()

123

layout.draw()

124

```

125

126

## Text Editing with Caret

127

128

```python

129

# Create editable text

130

document = pyglet.text.document.UnformattedDocument('Edit me')

131

layout = pyglet.text.layout.IncrementalTextLayout(document, width=400, height=200)

132

caret = pyglet.text.caret.Caret(layout)

133

134

# Attach to window

135

layout.x = 10

136

layout.y = 10

137

window.push_handlers(caret)

138

139

@window.event

140

def on_draw():

141

window.clear()

142

layout.draw()

143

144

# Caret properties

145

caret.visible: bool

146

caret.position: int # Character index

147

caret.mark: int | None # Selection start (None = no selection)

148

caret.color: tuple # RGB

149

150

# Caret methods

151

caret.select_all()

152

caret.select_word()

153

caret.select_paragraph()

154

caret.delete_selection()

155

caret.move_to_point(x, y)

156

```

157

158

## Examples

159

160

### Centered Text

161

```python

162

label = pyglet.text.Label(

163

'Centered Text',

164

font_name='Arial',

165

font_size=24,

166

x=window.width // 2,

167

y=window.height // 2,

168

anchor_x='center',

169

anchor_y='center'

170

)

171

```

172

173

### Multiline Text

174

```python

175

label = pyglet.text.Label(

176

'Line 1\nLine 2\nLine 3',

177

font_name='Arial',

178

font_size=16,

179

x=10, y=window.height - 10,

180

width=200,

181

multiline=True,

182

anchor_y='top'

183

)

184

```

185

186

### Animated Text Color

187

```python

188

label = pyglet.text.Label('Pulsing Text', font_size=24, x=100, y=100)

189

190

def update(dt):

191

import math

192

intensity = int(128 + 127 * math.sin(pyglet.clock.get_default().time() * 2))

193

label.color = (intensity, intensity, 255, 255)

194

195

pyglet.clock.schedule(update)

196

```

197

198

### Text with Shadow

199

```python

200

batch = pyglet.graphics.Batch()

201

bg_group = pyglet.graphics.Group(order=0)

202

fg_group = pyglet.graphics.Group(order=1)

203

204

# Shadow (behind)

205

shadow = pyglet.text.Label(

206

'Text with Shadow', font_size=24,

207

x=102, y=98, color=(0, 0, 0, 128),

208

batch=batch, group=bg_group

209

)

210

211

# Main text (front)

212

text = pyglet.text.Label(

213

'Text with Shadow', font_size=24,

214

x=100, y=100, color=(255, 255, 255, 255),

215

batch=batch, group=fg_group

216

)

217

218

@window.event

219

def on_draw():

220

window.clear()

221

batch.draw()

222

```

223

224

## Performance Tips

225

226

1. **Use batch rendering**: Add labels to Batch

227

2. **Avoid frequent text changes**: Cache labels when possible

228

3. **Use appropriate layout**: TextLayout for simple, IncrementalTextLayout for large/dynamic

229

4. **Preload fonts**: Call `pyglet.font.load()` during initialization

230

5. **Limit multiline width**: Large widths slow down wrapping

231

232

## Common Issues

233

234

1. **Font not found**: Check name with `pyglet.font.have_font()`

235

2. **Text position**: Remember (0,0) is bottom-left

236

3. **Multiline wrapping**: Requires `width` parameter

237

4. **Color format**: RGBA values are 0-255, not 0.0-1.0

238

5. **Anchor point**: Affects where (x,y) is relative to text

239