1 # This file is part of Librarian, licensed under GNU Affero GPLv3 or later.
2 # Copyright © Fundacja Wolne Lektury. See NOTICE for more information.
5 from librarian.cover import Cover, Metric
6 from .utils.color import algo_contrast_or_hue, luminance, is_very_bright
7 from .utils.textbox import DoesNotFit
8 from .widgets.author import AuthorBox
9 from .widgets.background import Background
10 from .widgets.image import WLLogo, Label
11 from .widgets.marquise import Marquise
12 from .widgets.title import TitleBox
15 class MarquiseCover(Cover):
17 square_variant = False
29 'rgb': (0xc3, 0x27, 0x21),
33 'rgb': (0xa0, 0xbf, 0x38),
37 'rgb': (0xed, 0xc0, 0x16),
41 'rgb': (0x47, 0x66, 0x75),
45 for c in color_schemes:
46 c['luminance'] = luminance(c['rgb'])
47 cim = PIL.Image.new('RGB', (1, 1))
48 cim.putpixel((0, 0), c['rgb'])
50 c['hsv'] = cim.getpixel((0, 0))
53 def set_size(self, final_width, final_height):
54 if final_width is None:
55 self.m = Metric(self, 1)
57 if final_width > self.width:
58 self.m = Metric(self, final_width / self.width)
60 self.m = Metric(self, 1)
61 self.scale_after = final_width / self.width
63 if final_height is not None:
64 self.height = round(final_height / self.scale_after / self.m._scale)
66 self.square_variant = self.height / self.width < 250 / 210
68 marquise_square_small = int(self.width / 2) - 300
69 marquise_square_big = int(self.width / 2) - 100
70 marquise_a4_small = 2970 - self.width
71 marquise_a4_big = marquise_a4_small + 100
73 self.marquise_small = int(round(marquise_square_small + (marquise_a4_small - marquise_square_small) * (self.height - self.width) / (2970 - 2100)))
74 self.marquise_big = int(round(marquise_square_big + (marquise_a4_big - marquise_square_big) * (self.height - self.width) / (2970 - 2100)))
75 self.marquise_xl = self.marquise_big + 200
77 if self.marquise_small > self.marquise_big:
78 self.marquise_small = self.marquise_big
80 def set_color_scheme_from(self, img):
81 self.color_scheme = algo_contrast_or_hue(img, self.color_schemes)
82 self.is_very_bright = is_very_bright(img)
85 img = PIL.Image.new('RGB', (self.m.width, self.m.height), self.background_color)
88 bg = Background(self, crop_to_square=False)
92 self.m.width, self.m.height
96 if self.square_variant:
98 (self.m.marquise_small, 1),
99 (self.m.marquise_big, 2),
100 (self.m.marquise_big, 3),
101 (self.m.marquise_big, None),
105 (self.m.marquise_small, 2),
106 (self.m.marquise_small, 1),
107 (self.m.marquise_big, 3),
108 (self.m.marquise_xl, 4),
109 (self.m.marquise_xl, None),
112 # Trying all the layout options with decreasing scale.
115 while title_box is None:
116 for marquise_h, lines in layout_options:
117 title_box_height = marquise_h - self.m.title_box_top - self.m.margin
119 title_box = TitleBox(
121 self.m.width - 2 * self.m.margin,
132 self.marquise_height = marquise_h
133 marquise = Marquise(self, self.marquise_height)
137 0, marquise.edge_top,
138 self.m.width, self.m.height - marquise.edge_top
140 self.set_color_scheme_from(
142 0, marquise.edge_top,
143 self.m.width, marquise.edge_top + (
144 self.m.height - marquise.edge_top
150 img, 0, 0, self.m.width
154 marquise.title_box_position[0],
155 marquise.title_box_position[1],
158 AuthorBox(self, self.m.author_width).apply(
159 img, self.m.width - self.m.margin - self.m.author_width, self.m.margin
161 WLLogo(self).apply(img, self.m.margin, self.m.margin, None, self.m.logo_h)
164 for logo in self.additional_logos:
165 LogoSticker(self, logo).apply(img, 0, 0)
172 class LabelMarquiseCover(MarquiseCover):
179 img = super().image()
180 if not self.predesigned:
184 self.marquise_height - self.label_top,