-
Notifications
You must be signed in to change notification settings - Fork 0
/
text.py
82 lines (71 loc) · 3.03 KB
/
text.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
from PIL import Image, ImageDraw
from word import Word
from random import randint, randrange
from PIL import ImageFont
from aabb import AABB
class Text:
def __init__(self, top_left):
self.lines = []
self.top_left = top_left
def __iter__(self):
for line in self.lines:
for word in line:
yield word
def generate_words(self, words, font, font_size, color, line_max_count=3):
"""
Generates words from the given string list words. Words are placed in order.
Randomly decides how many lines the text contains and how many words a line should contain.
"""
self.lines = []
line_count = randint(1, line_max_count)
lines = [[] for _ in range(line_count)]
for word in words:
lines[randrange(line_count)].append(word)
font = ImageFont.truetype(font, font_size)
white_space_width, white_space_height = font.getsize(" ")
pos_y = self.top_left[1]
for line in lines:
word_line = []
pos_x = self.top_left[0]
max_height = white_space_height
for raw_word in line:
word = Word(raw_word, font, color, (pos_x, pos_y))
pos_x += word.width + white_space_width
max_height = max(max_height, word.height)
word_line.append(word)
self.lines.append(word_line)
pos_y += max_height + 1
self.calculate_aabb()
def calculate_aabb(self):
bottom_right = None
for word in self:
if(bottom_right is None):
bottom_right = word.aabb.bottom_right
else:
bottom_right = (max(bottom_right[0], word.aabb.bottom_right[0]), max(bottom_right[1], word.aabb.bottom_right[1]))
self.aabb = AABB(self.top_left, bottom_right)
def draw(self, image_draw, debug=False):
if(debug):
bottom_right = self.aabb.bottom_right
image_draw.rectangle([self.top_left, bottom_right], outline=(0, 0, 255))
for word in self:
word.draw(image_draw, debug=debug)
def get_word_aabbs(self):
return [(word.aabb.top_left, word.aabb.bottom_right) for word in self]
def overlaps(self, value):
try:
if(isinstance(value, AABB)):
return self.aabb.intersects(value)
elif isinstance(getattr(value, 'aabb'), AABB):
return self.aabb.intersects(value.aabb)
else:
raise TypeError('"value" argument has to be of type AABB or contain an "aabb" property of type AABB')
except AttributeError:
raise TypeError('"value" argument has to be of type AABB or contain an "aabb" property of type AABB')
if __name__ == "__main__":
text = Text((100, 100))
text.generate_words(["test", "Hello", "World", "This", "nice"], "fonts/Roboto/Roboto-Regular.ttf", 20, (255, 0, 0))
image = Image.new("RGB", (400, 400))
draw = ImageDraw.Draw(image)
text.draw(draw, True)
image.save("test.png")