pgzero-plus 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of pgzero-plus might be problematic. Click here for more details.
- pgzero/__init__.py +41 -0
- pgzero/__main__.py +3 -0
- pgzero/actor.py +597 -0
- pgzero/animation.py +244 -0
- pgzero/builtins.py +45 -0
- pgzero/clock.py +200 -0
- pgzero/constants.py +33 -0
- pgzero/data/icon.png +0 -0
- pgzero/data/joypad.png +0 -0
- pgzero/game.py +573 -0
- pgzero/keyboard.py +67 -0
- pgzero/loaders.py +308 -0
- pgzero/music.py +180 -0
- pgzero/ptext.py +500 -0
- pgzero/rect.py +523 -0
- pgzero/runner.py +233 -0
- pgzero/screen.py +210 -0
- pgzero/soundfmt.py +105 -0
- pgzero/spellcheck.py +173 -0
- pgzero/sprites.py +182 -0
- pgzero/storage.py +191 -0
- pgzero/tilemaps.py +307 -0
- pgzero/tone.py +132 -0
- pgzero_plus-0.1.0.dist-info/METADATA +259 -0
- pgzero_plus-0.1.0.dist-info/RECORD +30 -0
- pgzero_plus-0.1.0.dist-info/WHEEL +5 -0
- pgzero_plus-0.1.0.dist-info/entry_points.txt +2 -0
- pgzero_plus-0.1.0.dist-info/licenses/COPYING +165 -0
- pgzero_plus-0.1.0.dist-info/top_level.txt +2 -0
- pgzrun.py +34 -0
pgzero/ptext.py
ADDED
|
@@ -0,0 +1,500 @@
|
|
|
1
|
+
"""pygame-text - high-level text rendering with Pygame.
|
|
2
|
+
|
|
3
|
+
This module is directly copied from
|
|
4
|
+
|
|
5
|
+
https://github.com/cosmologicon/pygame-text
|
|
6
|
+
|
|
7
|
+
at revision c04e59b7382a832e117f0598cdcbc1bb3eb26db5
|
|
8
|
+
and used under CC0.
|
|
9
|
+
|
|
10
|
+
"""
|
|
11
|
+
# ptext module: place this in your import directory.
|
|
12
|
+
|
|
13
|
+
# ptext.draw(text, pos=None, **options)
|
|
14
|
+
|
|
15
|
+
# Please see README.md for explanation of options.
|
|
16
|
+
# https://github.com/cosmologicon/pygame-text
|
|
17
|
+
|
|
18
|
+
# flake8: noqa: E501
|
|
19
|
+
from __future__ import division
|
|
20
|
+
|
|
21
|
+
from math import ceil, sin, cos, radians
|
|
22
|
+
import pygame
|
|
23
|
+
|
|
24
|
+
DEFAULT_FONT_SIZE = 24
|
|
25
|
+
REFERENCE_FONT_SIZE = 100
|
|
26
|
+
DEFAULT_LINE_HEIGHT = 1.0
|
|
27
|
+
DEFAULT_FONT_NAME = None
|
|
28
|
+
FONT_NAME_TEMPLATE = "%s"
|
|
29
|
+
DEFAULT_COLOR = "white"
|
|
30
|
+
DEFAULT_BACKGROUND = None
|
|
31
|
+
DEFAULT_OUTLINE_COLOR = "black"
|
|
32
|
+
DEFAULT_SHADOW_COLOR = "black"
|
|
33
|
+
OUTLINE_UNIT = 1 / 24
|
|
34
|
+
SHADOW_UNIT = 1 / 18
|
|
35
|
+
DEFAULT_ALIGN = "left" # left, center, or right
|
|
36
|
+
DEFAULT_ANCHOR = 0, 0 # 0, 0 = top left ; 1, 1 = bottom right
|
|
37
|
+
DEFAULT_STRIP = True
|
|
38
|
+
ALPHA_RESOLUTION = 16
|
|
39
|
+
ANGLE_RESOLUTION_DEGREES = 3
|
|
40
|
+
|
|
41
|
+
AUTO_CLEAN = True
|
|
42
|
+
MEMORY_LIMIT_MB = 64
|
|
43
|
+
MEMORY_REDUCTION_FACTOR = 0.5
|
|
44
|
+
|
|
45
|
+
pygame.font.init()
|
|
46
|
+
|
|
47
|
+
_font_cache = {}
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def getfont(fontname=None, fontsize=None, sysfontname=None,
|
|
51
|
+
bold=None, italic=None, underline=None):
|
|
52
|
+
if fontname is not None and sysfontname is not None:
|
|
53
|
+
raise ValueError("Can't set both fontname and sysfontname")
|
|
54
|
+
if fontname is None and sysfontname is None:
|
|
55
|
+
fontname = DEFAULT_FONT_NAME
|
|
56
|
+
if fontsize is None:
|
|
57
|
+
fontsize = DEFAULT_FONT_SIZE
|
|
58
|
+
key = fontname, fontsize, sysfontname, bold, italic, underline
|
|
59
|
+
if key in _font_cache:
|
|
60
|
+
return _font_cache[key]
|
|
61
|
+
if sysfontname is not None:
|
|
62
|
+
font = pygame.font.SysFont(
|
|
63
|
+
sysfontname, fontsize, bold or False, italic or False)
|
|
64
|
+
else:
|
|
65
|
+
if fontname is not None:
|
|
66
|
+
fontname = FONT_NAME_TEMPLATE % fontname
|
|
67
|
+
try:
|
|
68
|
+
font = pygame.font.Font(fontname, fontsize)
|
|
69
|
+
except IOError:
|
|
70
|
+
raise IOError("unable to read font filename: %s" % fontname)
|
|
71
|
+
if bold is not None:
|
|
72
|
+
font.set_bold(bold)
|
|
73
|
+
if italic is not None:
|
|
74
|
+
font.set_italic(italic)
|
|
75
|
+
if underline is not None:
|
|
76
|
+
font.set_underline(underline)
|
|
77
|
+
_font_cache[key] = font
|
|
78
|
+
return font
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def wrap(text, fontname=None, fontsize=None, sysfontname=None,
|
|
82
|
+
bold=None, italic=None, underline=None, width=None, widthem=None, strip=None):
|
|
83
|
+
if widthem is None:
|
|
84
|
+
font = getfont(fontname, fontsize, sysfontname,
|
|
85
|
+
bold, italic, underline)
|
|
86
|
+
elif width is not None:
|
|
87
|
+
raise ValueError("Can't set both width and widthem")
|
|
88
|
+
else:
|
|
89
|
+
font = getfont(fontname, REFERENCE_FONT_SIZE,
|
|
90
|
+
sysfontname, bold, italic, underline)
|
|
91
|
+
width = widthem * REFERENCE_FONT_SIZE
|
|
92
|
+
if strip is None:
|
|
93
|
+
strip = DEFAULT_STRIP
|
|
94
|
+
texts = text.replace("\t", " ").split("\n")
|
|
95
|
+
lines = []
|
|
96
|
+
for text in texts:
|
|
97
|
+
if strip:
|
|
98
|
+
text = text.rstrip(" ")
|
|
99
|
+
if width is None:
|
|
100
|
+
lines.append(text)
|
|
101
|
+
continue
|
|
102
|
+
if not text:
|
|
103
|
+
lines.append("")
|
|
104
|
+
continue
|
|
105
|
+
# Preserve leading spaces in all cases.
|
|
106
|
+
a = len(text) - len(text.lstrip(" "))
|
|
107
|
+
# At any time, a is the rightmost known index you can legally split a line. I.e. it's legal
|
|
108
|
+
# to add text[:a] to lines, and line is what will be added to lines if
|
|
109
|
+
# text is split at a.
|
|
110
|
+
a = text.index(" ", a) if " " in text else len(text)
|
|
111
|
+
line = text[:a]
|
|
112
|
+
while a + 1 < len(text):
|
|
113
|
+
# b is the next legal place to break the line, with bline the
|
|
114
|
+
# corresponding line to add.
|
|
115
|
+
if " " not in text[a + 1:]:
|
|
116
|
+
b = len(text)
|
|
117
|
+
bline = text
|
|
118
|
+
elif strip:
|
|
119
|
+
# Lines may be split at any space character that immediately follows a non-space
|
|
120
|
+
# character.
|
|
121
|
+
b = text.index(" ", a + 1)
|
|
122
|
+
while text[b - 1] == " ":
|
|
123
|
+
if " " in text[b + 1:]:
|
|
124
|
+
b = text.index(" ", b + 1)
|
|
125
|
+
else:
|
|
126
|
+
b = len(text)
|
|
127
|
+
break
|
|
128
|
+
bline = text[:b]
|
|
129
|
+
else:
|
|
130
|
+
# Lines may be split at any space character, or any character immediately following
|
|
131
|
+
# a space character.
|
|
132
|
+
b = a + 1 if text[a] == " " else text.index(" ", a + 1)
|
|
133
|
+
bline = text[:b]
|
|
134
|
+
if font.size(bline)[0] <= width:
|
|
135
|
+
a, line = b, bline
|
|
136
|
+
else:
|
|
137
|
+
lines.append(line)
|
|
138
|
+
text = text[a:].lstrip(" ") if strip else text[a:]
|
|
139
|
+
a = text.index(" ", 1) if " " in text[1:] else len(text)
|
|
140
|
+
line = text[:a]
|
|
141
|
+
if text:
|
|
142
|
+
lines.append(line)
|
|
143
|
+
return lines
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
_fit_cache = {}
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
def _fitsize(text, fontname, sysfontname, bold, italic, underline, width, height, lineheight, strip):
|
|
150
|
+
key = text, fontname, sysfontname, bold, italic, underline, width, height, lineheight, strip
|
|
151
|
+
if key in _fit_cache:
|
|
152
|
+
return _fit_cache[key]
|
|
153
|
+
|
|
154
|
+
def fits(fontsize):
|
|
155
|
+
texts = wrap(text, fontname, fontsize, sysfontname,
|
|
156
|
+
bold, italic, underline, width, strip)
|
|
157
|
+
font = getfont(fontname, fontsize, sysfontname,
|
|
158
|
+
bold, italic, underline)
|
|
159
|
+
w = max(font.size(line)[0] for line in texts)
|
|
160
|
+
linesize = font.get_linesize() * lineheight
|
|
161
|
+
h = int(round((len(texts) - 1) * linesize)) + font.get_height()
|
|
162
|
+
return w <= width and h <= height
|
|
163
|
+
a, b = 1, 256
|
|
164
|
+
if not fits(a):
|
|
165
|
+
fontsize = a
|
|
166
|
+
elif fits(b):
|
|
167
|
+
fontsize = b
|
|
168
|
+
else:
|
|
169
|
+
while b - a > 1:
|
|
170
|
+
c = (a + b) // 2
|
|
171
|
+
if fits(c):
|
|
172
|
+
a = c
|
|
173
|
+
else:
|
|
174
|
+
b = c
|
|
175
|
+
fontsize = a
|
|
176
|
+
_fit_cache[key] = fontsize
|
|
177
|
+
return fontsize
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
def _resolvecolor(color, default):
|
|
181
|
+
if color is None:
|
|
182
|
+
color = default
|
|
183
|
+
if color is None:
|
|
184
|
+
return None
|
|
185
|
+
try:
|
|
186
|
+
return tuple(pygame.Color(color))
|
|
187
|
+
except ValueError:
|
|
188
|
+
return tuple(color)
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
def _resolvealpha(alpha):
|
|
192
|
+
if alpha >= 1:
|
|
193
|
+
return 1
|
|
194
|
+
return max(int(round(alpha * ALPHA_RESOLUTION)) / ALPHA_RESOLUTION, 0)
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
def _resolveangle(angle):
|
|
198
|
+
if not angle:
|
|
199
|
+
return 0
|
|
200
|
+
angle %= 360
|
|
201
|
+
return int(round(angle / ANGLE_RESOLUTION_DEGREES)) * ANGLE_RESOLUTION_DEGREES
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
# Return the set of points in the circle radius r, using Bresenham's
|
|
205
|
+
# circle algorithm
|
|
206
|
+
_circle_cache = {}
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
def _circlepoints(r):
|
|
210
|
+
r = int(round(r))
|
|
211
|
+
if r in _circle_cache:
|
|
212
|
+
return _circle_cache[r]
|
|
213
|
+
x, y, e = r, 0, 1 - r
|
|
214
|
+
_circle_cache[r] = points = []
|
|
215
|
+
while x >= y:
|
|
216
|
+
points.append((x, y))
|
|
217
|
+
y += 1
|
|
218
|
+
if e < 0:
|
|
219
|
+
e += 2 * y - 1
|
|
220
|
+
else:
|
|
221
|
+
x -= 1
|
|
222
|
+
e += 2 * (y - x) - 1
|
|
223
|
+
points += [(y, x) for x, y in points if x > y]
|
|
224
|
+
points += [(-x, y) for x, y in points if x]
|
|
225
|
+
points += [(x, -y) for x, y in points if y]
|
|
226
|
+
points.sort()
|
|
227
|
+
return points
|
|
228
|
+
|
|
229
|
+
|
|
230
|
+
_surf_cache = {}
|
|
231
|
+
_surf_tick_usage = {}
|
|
232
|
+
_surf_size_total = 0
|
|
233
|
+
_unrotated_size = {}
|
|
234
|
+
_tick = 0
|
|
235
|
+
|
|
236
|
+
|
|
237
|
+
def getsurf(text, fontname=None, fontsize=None, sysfontname=None, bold=None, italic=None,
|
|
238
|
+
underline=None, width=None, widthem=None, strip=None, color=None,
|
|
239
|
+
background=None, antialias=True, ocolor=None, owidth=None, scolor=None, shadow=None,
|
|
240
|
+
gcolor=None, alpha=1.0, align=None, lineheight=None, angle=0, cache=True):
|
|
241
|
+
global _tick, _surf_size_total
|
|
242
|
+
if fontname is None:
|
|
243
|
+
fontname = DEFAULT_FONT_NAME
|
|
244
|
+
if fontsize is None:
|
|
245
|
+
fontsize = DEFAULT_FONT_SIZE
|
|
246
|
+
fontsize = int(round(fontsize))
|
|
247
|
+
if align is None:
|
|
248
|
+
align = DEFAULT_ALIGN
|
|
249
|
+
if align in ["left", "center", "right"]:
|
|
250
|
+
align = [0, 0.5, 1][["left", "center", "right"].index(align)]
|
|
251
|
+
if lineheight is None:
|
|
252
|
+
lineheight = DEFAULT_LINE_HEIGHT
|
|
253
|
+
color = _resolvecolor(color, DEFAULT_COLOR)
|
|
254
|
+
background = _resolvecolor(background, DEFAULT_BACKGROUND)
|
|
255
|
+
gcolor = _resolvecolor(gcolor, None)
|
|
256
|
+
ocolor = None if owidth is None else _resolvecolor(
|
|
257
|
+
ocolor, DEFAULT_OUTLINE_COLOR)
|
|
258
|
+
scolor = None if shadow is None else _resolvecolor(
|
|
259
|
+
scolor, DEFAULT_SHADOW_COLOR)
|
|
260
|
+
opx = None if owidth is None else ceil(owidth * fontsize * OUTLINE_UNIT)
|
|
261
|
+
spx = None if shadow is None else tuple(
|
|
262
|
+
ceil(s * fontsize * SHADOW_UNIT) for s in shadow)
|
|
263
|
+
alpha = _resolvealpha(alpha)
|
|
264
|
+
angle = _resolveangle(angle)
|
|
265
|
+
strip = DEFAULT_STRIP if strip is None else strip
|
|
266
|
+
key = (text, fontname, fontsize, sysfontname, bold, italic, underline, width, widthem, strip,
|
|
267
|
+
color, background, antialias, ocolor, opx, scolor, spx, gcolor, alpha, align, lineheight, angle)
|
|
268
|
+
if key in _surf_cache:
|
|
269
|
+
_surf_tick_usage[key] = _tick
|
|
270
|
+
_tick += 1
|
|
271
|
+
return _surf_cache[key]
|
|
272
|
+
texts = wrap(text, fontname, fontsize, sysfontname, bold, italic, underline,
|
|
273
|
+
width=width, widthem=widthem, strip=strip)
|
|
274
|
+
if angle:
|
|
275
|
+
surf0 = getsurf(text, fontname, fontsize, sysfontname, bold, italic, underline,
|
|
276
|
+
width, widthem, strip, color, background, antialias,
|
|
277
|
+
ocolor, owidth, scolor, shadow, gcolor, alpha, align, lineheight, cache=cache)
|
|
278
|
+
if angle in (90, 180, 270):
|
|
279
|
+
surf = pygame.transform.rotate(surf0, angle)
|
|
280
|
+
else:
|
|
281
|
+
surf = pygame.transform.rotozoom(surf0, angle, 1.0)
|
|
282
|
+
_unrotated_size[(surf.get_size(), angle, text)] = surf0.get_size()
|
|
283
|
+
elif alpha < 1.0:
|
|
284
|
+
surf0 = getsurf(text, fontname, fontsize, sysfontname, bold, italic, underline,
|
|
285
|
+
width, widthem, strip, color, background, antialias,
|
|
286
|
+
ocolor, owidth, scolor, shadow, gcolor=gcolor, align=align,
|
|
287
|
+
lineheight=lineheight, cache=cache)
|
|
288
|
+
surf = surf0.copy()
|
|
289
|
+
array = pygame.surfarray.pixels_alpha(surf)
|
|
290
|
+
array[:, :] = (array[:, :] * alpha).astype(array.dtype)
|
|
291
|
+
del array
|
|
292
|
+
elif spx is not None:
|
|
293
|
+
surf0 = getsurf(text, fontname, fontsize, sysfontname, bold, italic, underline,
|
|
294
|
+
width, widthem, strip, color=color, background=(0, 0, 0, 0), antialias=antialias,
|
|
295
|
+
gcolor=gcolor, align=align, lineheight=lineheight, cache=cache)
|
|
296
|
+
ssurf = getsurf(text, fontname, fontsize, sysfontname, bold, italic, underline,
|
|
297
|
+
width, widthem, strip, color=scolor, background=(0, 0, 0, 0), antialias=antialias,
|
|
298
|
+
align=align, lineheight=lineheight, cache=cache)
|
|
299
|
+
w0, h0 = surf0.get_size()
|
|
300
|
+
sx, sy = spx
|
|
301
|
+
surf = pygame.Surface((w0 + abs(sx), h0 + abs(sy))).convert_alpha()
|
|
302
|
+
surf.fill(background or (0, 0, 0, 0))
|
|
303
|
+
dx, dy = max(sx, 0), max(sy, 0)
|
|
304
|
+
surf.blit(ssurf, (dx, dy))
|
|
305
|
+
x0, y0 = abs(sx) - dx, abs(sy) - dy
|
|
306
|
+
if len(color) > 3 and color[3] == 0:
|
|
307
|
+
array = pygame.surfarray.pixels_alpha(surf)
|
|
308
|
+
array0 = pygame.surfarray.pixels_alpha(surf0)
|
|
309
|
+
array[x0:x0 + w0, y0:y0 +
|
|
310
|
+
h0] -= array0.clip(max=array[x0:x0 + w0, y0:y0 + h0])
|
|
311
|
+
del array, array0
|
|
312
|
+
else:
|
|
313
|
+
surf.blit(surf0, (x0, y0))
|
|
314
|
+
elif opx is not None:
|
|
315
|
+
surf0 = getsurf(text, fontname, fontsize, sysfontname, bold, italic, underline,
|
|
316
|
+
width, widthem, strip, color=color, background=(0, 0, 0, 0), antialias=antialias,
|
|
317
|
+
gcolor=gcolor, align=align, lineheight=lineheight, cache=cache)
|
|
318
|
+
osurf = getsurf(text, fontname, fontsize, sysfontname, bold, italic, underline,
|
|
319
|
+
width, widthem, strip, color=ocolor, background=(0, 0, 0, 0), antialias=antialias,
|
|
320
|
+
align=align, lineheight=lineheight, cache=cache)
|
|
321
|
+
w0, h0 = surf0.get_size()
|
|
322
|
+
surf = pygame.Surface((w0 + 2 * opx, h0 + 2 * opx)).convert_alpha()
|
|
323
|
+
surf.fill(background or (0, 0, 0, 0))
|
|
324
|
+
for dx, dy in _circlepoints(opx):
|
|
325
|
+
surf.blit(osurf, (dx + opx, dy + opx))
|
|
326
|
+
if len(color) > 3 and color[3] == 0:
|
|
327
|
+
array = pygame.surfarray.pixels_alpha(surf)
|
|
328
|
+
array0 = pygame.surfarray.pixels_alpha(surf0)
|
|
329
|
+
array[opx:-opx, opx:-
|
|
330
|
+
opx] -= array0.clip(max=array[opx:-opx, opx:-opx])
|
|
331
|
+
del array, array0
|
|
332
|
+
else:
|
|
333
|
+
surf.blit(surf0, (opx, opx))
|
|
334
|
+
else:
|
|
335
|
+
font = getfont(fontname, fontsize, sysfontname,
|
|
336
|
+
bold, italic, underline)
|
|
337
|
+
# pygame.Font.render does not allow passing None as an argument value
|
|
338
|
+
# for background.
|
|
339
|
+
if background is None or (len(background) > 3 and background[3] == 0) or gcolor is not None:
|
|
340
|
+
lsurfs = [font.render(text, antialias, color).convert_alpha()
|
|
341
|
+
for text in texts]
|
|
342
|
+
else:
|
|
343
|
+
lsurfs = [font.render(text, antialias, color,
|
|
344
|
+
background).convert_alpha() for text in texts]
|
|
345
|
+
if gcolor is not None:
|
|
346
|
+
import numpy
|
|
347
|
+
for lsurf in lsurfs:
|
|
348
|
+
m = numpy.clip(numpy.arange(
|
|
349
|
+
lsurf.get_height()) * 2.0 / font.get_ascent() - 1.0, 0, 1)
|
|
350
|
+
array = pygame.surfarray.pixels3d(lsurf)
|
|
351
|
+
for j in (0, 1, 2):
|
|
352
|
+
array[:, :, j] = (
|
|
353
|
+
(1.0 - m) * array[:, :, j] + m * gcolor[j]).astype(array.dtype)
|
|
354
|
+
del array
|
|
355
|
+
|
|
356
|
+
if len(lsurfs) == 1 and gcolor is None:
|
|
357
|
+
surf = lsurfs[0]
|
|
358
|
+
else:
|
|
359
|
+
w = max(lsurf.get_width() for lsurf in lsurfs)
|
|
360
|
+
linesize = font.get_linesize() * lineheight
|
|
361
|
+
ys = [int(round(k * linesize)) for k in range(len(lsurfs))]
|
|
362
|
+
h = ys[-1] + font.get_height()
|
|
363
|
+
surf = pygame.Surface((w, h)).convert_alpha()
|
|
364
|
+
surf.fill(background or (0, 0, 0, 0))
|
|
365
|
+
for y, lsurf in zip(ys, lsurfs):
|
|
366
|
+
x = int(round(align * (w - lsurf.get_width())))
|
|
367
|
+
surf.blit(lsurf, (x, y))
|
|
368
|
+
if cache:
|
|
369
|
+
w, h = surf.get_size()
|
|
370
|
+
_surf_size_total += 4 * w * h
|
|
371
|
+
_surf_cache[key] = surf
|
|
372
|
+
_surf_tick_usage[key] = _tick
|
|
373
|
+
_tick += 1
|
|
374
|
+
return surf
|
|
375
|
+
|
|
376
|
+
|
|
377
|
+
_default_surf_sentinel = ()
|
|
378
|
+
|
|
379
|
+
|
|
380
|
+
def draw(text, pos=None,
|
|
381
|
+
fontname=None, fontsize=None, sysfontname=None,
|
|
382
|
+
antialias=True, bold=None, italic=None, underline=None,
|
|
383
|
+
color=None, background=None,
|
|
384
|
+
top=None, left=None, bottom=None, right=None,
|
|
385
|
+
topleft=None, bottomleft=None, topright=None, bottomright=None,
|
|
386
|
+
midtop=None, midleft=None, midbottom=None, midright=None,
|
|
387
|
+
center=None, centerx=None, centery=None,
|
|
388
|
+
width=None, widthem=None, lineheight=None, strip=None,
|
|
389
|
+
align=None,
|
|
390
|
+
owidth=None, ocolor=None,
|
|
391
|
+
shadow=None, scolor=None,
|
|
392
|
+
gcolor=None,
|
|
393
|
+
alpha=1.0,
|
|
394
|
+
anchor=None,
|
|
395
|
+
angle=0,
|
|
396
|
+
surf=_default_surf_sentinel,
|
|
397
|
+
cache=True):
|
|
398
|
+
|
|
399
|
+
if topleft:
|
|
400
|
+
left, top = topleft
|
|
401
|
+
if bottomleft:
|
|
402
|
+
left, bottom = bottomleft
|
|
403
|
+
if topright:
|
|
404
|
+
right, top = topright
|
|
405
|
+
if bottomright:
|
|
406
|
+
right, bottom = bottomright
|
|
407
|
+
if midtop:
|
|
408
|
+
centerx, top = midtop
|
|
409
|
+
if midleft:
|
|
410
|
+
left, centery = midleft
|
|
411
|
+
if midbottom:
|
|
412
|
+
centerx, bottom = midbottom
|
|
413
|
+
if midright:
|
|
414
|
+
right, centery = midright
|
|
415
|
+
if center:
|
|
416
|
+
centerx, centery = center
|
|
417
|
+
|
|
418
|
+
x, y = pos or (None, None)
|
|
419
|
+
hanchor, vanchor = anchor or (None, None)
|
|
420
|
+
if left is not None:
|
|
421
|
+
x, hanchor = left, 0
|
|
422
|
+
if centerx is not None:
|
|
423
|
+
x, hanchor = centerx, 0.5
|
|
424
|
+
if right is not None:
|
|
425
|
+
x, hanchor = right, 1
|
|
426
|
+
if top is not None:
|
|
427
|
+
y, vanchor = top, 0
|
|
428
|
+
if centery is not None:
|
|
429
|
+
y, vanchor = centery, 0.5
|
|
430
|
+
if bottom is not None:
|
|
431
|
+
y, vanchor = bottom, 1
|
|
432
|
+
if x is None:
|
|
433
|
+
raise ValueError("Unable to determine horizontal position")
|
|
434
|
+
if y is None:
|
|
435
|
+
raise ValueError("Unable to determine vertical position")
|
|
436
|
+
|
|
437
|
+
if align is None:
|
|
438
|
+
align = hanchor
|
|
439
|
+
if hanchor is None:
|
|
440
|
+
hanchor = DEFAULT_ANCHOR[0]
|
|
441
|
+
if vanchor is None:
|
|
442
|
+
vanchor = DEFAULT_ANCHOR[1]
|
|
443
|
+
|
|
444
|
+
tsurf = getsurf(text, fontname, fontsize, sysfontname, bold, italic, underline, width, widthem,
|
|
445
|
+
strip, color, background, antialias, ocolor, owidth, scolor, shadow, gcolor, alpha, align,
|
|
446
|
+
lineheight, angle, cache)
|
|
447
|
+
angle = _resolveangle(angle)
|
|
448
|
+
if angle:
|
|
449
|
+
w0, h0 = _unrotated_size[(tsurf.get_size(), angle, text)]
|
|
450
|
+
S, C = sin(radians(angle)), cos(radians(angle))
|
|
451
|
+
dx, dy = (0.5 - hanchor) * w0, (0.5 - vanchor) * h0
|
|
452
|
+
x += dx * C + dy * S - 0.5 * tsurf.get_width()
|
|
453
|
+
y += -dx * S + dy * C - 0.5 * tsurf.get_height()
|
|
454
|
+
else:
|
|
455
|
+
x -= hanchor * tsurf.get_width()
|
|
456
|
+
y -= vanchor * tsurf.get_height()
|
|
457
|
+
x = int(round(x))
|
|
458
|
+
y = int(round(y))
|
|
459
|
+
|
|
460
|
+
if surf is _default_surf_sentinel:
|
|
461
|
+
surf = pygame.display.get_surface()
|
|
462
|
+
if surf is not None:
|
|
463
|
+
surf.blit(tsurf, (x, y))
|
|
464
|
+
|
|
465
|
+
if AUTO_CLEAN:
|
|
466
|
+
clean()
|
|
467
|
+
|
|
468
|
+
return tsurf, (x, y)
|
|
469
|
+
|
|
470
|
+
|
|
471
|
+
def drawbox(text, rect, fontname=None, sysfontname=None, lineheight=None, anchor=None,
|
|
472
|
+
bold=None, italic=None, underline=None, strip=None, **kwargs):
|
|
473
|
+
if fontname is None:
|
|
474
|
+
fontname = DEFAULT_FONT_NAME
|
|
475
|
+
if lineheight is None:
|
|
476
|
+
lineheight = DEFAULT_LINE_HEIGHT
|
|
477
|
+
hanchor, vanchor = anchor = anchor or (0.5, 0.5)
|
|
478
|
+
rect = pygame.Rect(rect)
|
|
479
|
+
x = rect.x + hanchor * rect.width
|
|
480
|
+
y = rect.y + vanchor * rect.height
|
|
481
|
+
fontsize = _fitsize(text, fontname, sysfontname, bold, italic, underline,
|
|
482
|
+
rect.width, rect.height, lineheight, strip)
|
|
483
|
+
return draw(text, (x, y), fontname=fontname, fontsize=fontsize, lineheight=lineheight,
|
|
484
|
+
width=rect.width, strip=strip, anchor=anchor, **kwargs)
|
|
485
|
+
|
|
486
|
+
|
|
487
|
+
def clean():
|
|
488
|
+
global _surf_size_total
|
|
489
|
+
memory_limit = MEMORY_LIMIT_MB * (1 << 20)
|
|
490
|
+
if _surf_size_total < memory_limit:
|
|
491
|
+
return
|
|
492
|
+
memory_limit *= MEMORY_REDUCTION_FACTOR
|
|
493
|
+
keys = sorted(_surf_cache, key=_surf_tick_usage.get)
|
|
494
|
+
for key in keys:
|
|
495
|
+
w, h = _surf_cache[key].get_size()
|
|
496
|
+
del _surf_cache[key]
|
|
497
|
+
del _surf_tick_usage[key]
|
|
498
|
+
_surf_size_total -= 4 * w * h
|
|
499
|
+
if _surf_size_total < memory_limit:
|
|
500
|
+
break
|