pygkit 1.0.1__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.
pygkit/utils/text.py ADDED
@@ -0,0 +1,147 @@
1
+ from pathlib import Path
2
+ from typing import List, Tuple, Union
3
+
4
+ import pygame
5
+ from pygame import Surface
6
+ from pygame.font import Font
7
+
8
+
9
+ def load_font(
10
+ path: Union[str, Path],
11
+ size: int,
12
+ default_size: int | None = None,
13
+ ) -> Font:
14
+ if isinstance(path, str):
15
+ path = Path(path)
16
+ try:
17
+ if path.exists():
18
+ return Font(str(path), size)
19
+ except (FileNotFoundError, pygame.error, ValueError):
20
+ pass
21
+ return Font(None, default_size if default_size is not None else size)
22
+
23
+
24
+ def outline(
25
+ font: Font,
26
+ text: str,
27
+ color: tuple[int, int, int],
28
+ outline_color: tuple[int, int, int],
29
+ thickness: int = 1,
30
+ ) -> Surface:
31
+ base = font.render(text, True, color)
32
+ w = base.get_width() + thickness * 2
33
+ h = base.get_height() + thickness * 2
34
+ surf = Surface((w, h))
35
+ surf.set_colorkey((0, 0, 0))
36
+ surf.fill((0, 0, 0))
37
+
38
+ for dx in range(-thickness, thickness + 1):
39
+ for dy in range(-thickness, thickness + 1):
40
+ if dx == 0 and dy == 0:
41
+ continue
42
+ surf.blit(font.render(text, True, outline_color), (thickness + dx, thickness + dy))
43
+
44
+ surf.blit(base, (thickness, thickness))
45
+ return surf
46
+
47
+
48
+ def shadow(
49
+ font: Font,
50
+ text: str,
51
+ color: tuple[int, int, int],
52
+ shadow_color: tuple[int, int, int],
53
+ offset: tuple[int, int] = (2, 2),
54
+ ) -> Surface:
55
+ base = font.render(text, True, color)
56
+ shade = font.render(text, True, shadow_color)
57
+
58
+ w = base.get_width() + abs(offset[0])
59
+ h = base.get_height() + abs(offset[1])
60
+ surf = Surface((w, h))
61
+ surf.set_colorkey((0, 0, 0))
62
+ surf.fill((0, 0, 0))
63
+
64
+ sx = max(0, offset[0])
65
+ sy = max(0, offset[1])
66
+ surf.blit(shade, (sx, sy))
67
+ bx = max(0, -offset[0])
68
+ by = max(0, -offset[1])
69
+ surf.blit(base, (bx, by))
70
+ return surf
71
+
72
+
73
+ def wrap(
74
+ font: Font,
75
+ text: str,
76
+ max_width: int,
77
+ ) -> List[str]:
78
+ lines: List[str] = []
79
+ for paragraph in text.split("\n"):
80
+ words = paragraph.split()
81
+ if not words:
82
+ lines.append("")
83
+ continue
84
+ current = words[0]
85
+ for word in words[1:]:
86
+ test = f"{current} {word}"
87
+ if font.size(test)[0] <= max_width:
88
+ current = test
89
+ else:
90
+ lines.append(current)
91
+ current = word
92
+ lines.append(current)
93
+ return lines
94
+
95
+
96
+ def render_multiline(
97
+ font: Font,
98
+ text: str,
99
+ color: tuple[int, int, int],
100
+ max_width: int | None = None,
101
+ line_spacing: int = 2,
102
+ align: str = "left",
103
+ ) -> Surface:
104
+ if max_width is not None:
105
+ lines = wrap(font, text, max_width)
106
+ else:
107
+ lines = text.split("\n")
108
+
109
+ line_h = font.get_linesize()
110
+ total_h = len(lines) * line_h + (len(lines) - 1) * line_spacing
111
+ max_line_w = max(font.size(l)[0] for l in lines) if lines else 0
112
+
113
+ surf = Surface((max_line_w, total_h))
114
+ surf.set_colorkey((0, 0, 0))
115
+ surf.fill((0, 0, 0))
116
+
117
+ for i, line in enumerate(lines):
118
+ rendered = font.render(line, True, color)
119
+ x = 0
120
+ if align == "center":
121
+ x = (max_line_w - rendered.get_width()) // 2
122
+ elif align == "right":
123
+ x = max_line_w - rendered.get_width()
124
+ y = i * (line_h + line_spacing)
125
+ surf.blit(rendered, (x, y))
126
+
127
+ return surf
128
+
129
+
130
+ def fit(
131
+ font: Font,
132
+ text: str,
133
+ max_width: int,
134
+ max_height: int,
135
+ min_size: int = 8,
136
+ ) -> int:
137
+ size = font.get_height()
138
+ while size >= min_size:
139
+ try:
140
+ test = Font(font.name, size)
141
+ except FileNotFoundError:
142
+ test = Font(None, size)
143
+ w, h = test.size(text)
144
+ if w <= max_width and h <= max_height:
145
+ return size
146
+ size -= 1
147
+ return min_size
pygkit/utils/timer.py ADDED
@@ -0,0 +1,35 @@
1
+ import pygame
2
+
3
+
4
+ class Timer:
5
+ __slots__ = ("interval", "start_timer")
6
+
7
+ def __init__(self, interval: float | int, stale_init: bool = False) -> None:
8
+ self.start_timer = pygame.time.get_ticks()
9
+ if stale_init:
10
+ self.start_timer -= int(interval) - 1
11
+ self.interval = int(interval)
12
+
13
+ def reset(self) -> None:
14
+ self.start_timer = pygame.time.get_ticks()
15
+
16
+ def reached(self) -> bool:
17
+ return self.elapsed() >= self.interval
18
+
19
+ def reached_at(self, ratio: float) -> bool:
20
+ if ratio <= 0 or ratio >= 1.0:
21
+ return False
22
+ return self.elapsed() >= int(self.interval * ratio)
23
+
24
+ def stale(self) -> None:
25
+ if self.interval > 0:
26
+ self.start_timer -= self.interval - 1
27
+
28
+ def elapsed(self) -> int:
29
+ return pygame.time.get_ticks() - self.start_timer
30
+
31
+ def ratio(self) -> float:
32
+ td = self.elapsed()
33
+ if td >= self.interval:
34
+ return 1.0
35
+ return td / self.interval