162215fe558645a63d9633746e925e67e0a22f95
[librarian.git] / src / librarian / covers / widgets / author.py
1 import PIL.ImageFont
2 from librarian import get_resource
3 from librarian.cover import Metric
4 from ..utils.textbox import TextBox, DoesNotFit, split_words
5 from .base import Widget
6
7
8 class AuthorBox(Widget):
9     font_size = 75
10     leading = 92
11
12     def __init__(self, cover, width):
13         self.width = width
14         self.m = Metric(self, cover.m._scale)
15         super().__init__(cover)
16
17     def setup(self):
18         author_font = PIL.ImageFont.truetype(
19             get_resource('fonts/SourceSans3VF-Roman.ttf'),
20             self.m.font_size,
21             layout_engine=PIL.ImageFont.LAYOUT_BASIC
22         )
23         author_font.set_variation_by_axes([600])
24
25         translator_font = PIL.ImageFont.truetype(
26             get_resource('fonts/SourceSans3VF-Roman.ttf'),
27             self.m.font_size,
28             layout_engine=PIL.ImageFont.LAYOUT_BASIC
29         )
30         translator_font.set_variation_by_axes([400])
31
32         authors = [a.readable() for a in self.cover.book_info.authors]
33         translators = [a.readable() for a in self.cover.book_info.translators]
34
35         authors_written = False
36         if authors and translators:
37             author_str = ', '.join(authors)
38             translator_str = '(tłum. ' + ', '.join(translators) + ')'
39             # just print
40             parts = [author_str, translator_str]
41
42             try:
43                 self.textboxes = [
44                     TextBox(
45                         self.width,
46                         self.m.leading * 2,
47                         [author_str],
48                         author_font,
49                         1,
50                         self.m.leading,
51                         0,
52                         1, 0
53                     ),
54                     TextBox(
55                         self.width,
56                         self.m.leading * 2,
57                         [translator_str],
58                         translator_font,
59                         1,
60                         self.m.leading,
61                         0,
62                         1, 0
63                     )
64                 ]
65             except DoesNotFit:
66                 pass
67             else:
68                 authors_written = True
69
70         if not authors_written:
71             assert authors
72             if len(authors) == 2:
73                 parts = authors
74             elif len(authors) > 2:
75                 parts = [author + ',' for author in authors[:-1]] + [authors[-1]]
76             else:
77                 parts = split_words(authors[0])
78
79             try:
80                 self.textboxes = [
81                     TextBox(
82                         self.width,
83                         self.m.leading * 2,
84                         parts,
85                         author_font,
86                         2,
87                         self.m.leading,
88                         0,
89                         1, 0
90                     )
91                 ]
92             except:
93                 self.textboxes = [
94                     TextBox(
95                         self.width,
96                         self.m.leading * 2,
97                         parts,
98                         author_font,
99                         1,
100                         self.m.leading,
101                         0,
102                         1, 0
103                     )
104                 ]
105         self.margin_top = self.textboxes[0].margin_top
106
107     def build(self, w, h):
108         img = PIL.Image.new('RGBA', (self.width, self.m.leading * 2))
109         offset = 0
110         for i, tb in enumerate(self.textboxes):
111             sub_img = tb.as_pil_image(self.cover.color_scheme['text'])
112             img.paste(sub_img, (0, self.m.leading * i), sub_img)
113         
114         return img