New covers.
[librarian.git] / src / librarian / covers / marquise.py
diff --git a/src/librarian/covers/marquise.py b/src/librarian/covers/marquise.py
new file mode 100644 (file)
index 0000000..283a2be
--- /dev/null
@@ -0,0 +1,172 @@
+import PIL.Image
+from librarian.cover import Cover, Metric
+from .utils.color import algo_contrast_or_hue, luminance, is_very_bright
+from .utils.textbox import DoesNotFit
+from .widgets.author import AuthorBox
+from .widgets.background import Background
+from .widgets.image import WLLogo, Label
+from .widgets.marquise import Marquise
+from .widgets.title import TitleBox
+
+
+class MarquiseCover(Cover):
+    additional_logos = []
+    square_variant = False
+
+    width = 2100
+    height = 2970
+    margin = 100
+    logo_h = 177
+    title_box_top = 262
+
+    color_schemes = [
+        {
+            'rgb': (0xc3, 0x27, 0x21),
+            'text': '#000',
+        },
+        {
+            'rgb': (0xa0, 0xbf, 0x38),
+            'text': '#000',
+        },
+        {
+            'rgb': (0xed, 0xc0, 0x16),
+            'text': '#000',
+        },
+        {
+            'rgb': (0x47, 0x66, 0x75),
+            'text': '#fff',
+        }
+    ]
+    for c in color_schemes:
+        c['luminance'] = luminance(c['rgb'])
+        cim = PIL.Image.new('RGB', (1, 1))
+        cim.putpixel((0, 0), c['rgb'])
+        cim.convert('HSV')
+        c['hsv'] = cim.getpixel((0, 0))
+
+    
+    def set_size(self, final_width, final_height):
+        if final_width is None:
+            self.m = Metric(self, 1)
+        else:
+            if final_width > self.width:
+                self.m = Metric(self, final_width / self.width)
+            else:
+                self.m = Metric(self, 1)
+                self.scale_after = final_width / self.width
+            
+        if final_height is not None:
+            self.height = round(final_height / self.m._scale)
+
+        self.square_variant = self.height / self.width < 250 / 210
+
+        marquise_square_small = int(self.width / 2) - 300
+        marquise_square_big = int(self.width / 2) - 100
+        marquise_a4_small = 2970 - self.width
+        marquise_a4_big = marquise_a4_small + 100
+        
+        self.marquise_small = int(round(marquise_square_small + (marquise_a4_small - marquise_square_small) * (self.height - self.width) / (2970 - 2100)))
+        self.marquise_big = int(round(marquise_square_big + (marquise_a4_big - marquise_square_big) * (self.height - self.width) / (2970 - 2100)))
+        self.marquise_xl = self.marquise_big + 200
+
+        if self.marquise_small > self.marquise_big:
+            self.marquise_small = self.marquise_big
+
+    def set_color_scheme_from(self, img):
+        self.color_scheme = algo_contrast_or_hue(img, self.color_schemes)
+        self.is_very_bright = is_very_bright(img)
+
+    def image(self):
+        img = PIL.Image.new('RGB', (self.m.width, self.m.height), self.background_color)
+        
+        bg = Background(self)
+
+        if self.square_variant:
+            layout_options = [
+                (self.m.marquise_small, 1),
+                (self.m.marquise_big, 2),
+                (self.m.marquise_big, 3),
+                (self.m.marquise_big, None),
+            ]
+        else:
+            layout_options = [
+                (self.m.marquise_small, 2),
+                (self.m.marquise_small, 1),
+                (self.m.marquise_big, 3),
+                (self.m.marquise_xl, 4),
+                (self.m.marquise_xl, None),
+            ]
+
+        for marquise_h, lines in layout_options:
+            title_box_height = marquise_h - self.m.title_box_top - self.m.margin
+            try:
+                title_box = TitleBox(
+                    self,
+                    self.m.width - 2 * self.m.margin,
+                    title_box_height,
+                    lines,
+                    force=lines is None
+                )
+            except DoesNotFit:
+                continue
+            else:
+                break
+
+        self.marquise_height = marquise_h
+        marquise = Marquise(self, marquise_h)
+
+        bg.apply(
+            img,
+            0, marquise.edge_top,
+            self.m.width, self.m.height - marquise.edge_top
+        )
+        self.set_color_scheme_from(
+            img.crop((
+                0, marquise.edge_top,
+                self.m.width, marquise.edge_top + (
+                    self.m.height - marquise.edge_top
+                ) / 4
+            ))
+        )
+
+        marquise.apply(
+            img, 0, 0, self.m.width
+        )
+        title_box.apply(
+            img,
+            marquise.title_box_position[0],
+            marquise.title_box_position[1],
+        )
+
+        AuthorBox(self, self.m.width - self.m.margin).apply(
+            img, 0, self.m.margin
+        )
+        WLLogo(self).apply(img, self.m.margin, self.m.margin, None, self.m.logo_h)
+
+                              
+        for logo in self.additional_logos:
+            LogoSticker(self, logo).apply(img, 0, 0)
+
+
+        return img
+
+
+    
+class LabelMarquiseCover(MarquiseCover):
+    label_left = 95
+    label_top = 105
+    label_w = 710
+    label_h = 710
+    
+    def image(self):
+        img = super().image()
+
+        Label(self).apply(
+            img,
+            self.m.label_left,
+            self.marquise_height - self.m.label_top,
+            self.m.label_w,
+            self.m.label_h
+        )
+
+        return img