From cef5307b16e8df550c9ecf9704449e55b9137be2 Mon Sep 17 00:00:00 2001 From: Radek Czajka Date: Fri, 23 Jun 2023 13:30:37 +0200 Subject: [PATCH] Add support for predesigned covers to Marquise. Remove support for changing cover class by metadata. --- src/librarian/cover.py | 14 +- src/librarian/covers/marquise.py | 155 +++++++++++---------- src/librarian/covers/widgets/background.py | 37 +++-- 3 files changed, 117 insertions(+), 89 deletions(-) diff --git a/src/librarian/cover.py b/src/librarian/cover.py index 0e9b079..9cd813a 100644 --- a/src/librarian/cover.py +++ b/src/librarian/cover.py @@ -153,6 +153,15 @@ class Cover(object): def __init__(self, book_info, format=None, width=None, height=None, cover_logo=None): self.book_info = book_info + + self.predesigned = False + if book_info.cover_class == 'image': + self.predesigned = True + + # TODO: deprecated + if book_info.cover_box_position == 'none': + self.predesigned = True + self.authors = [auth.readable() for auth in book_info.authors] self.title = book_info.title if format is not None: @@ -1005,9 +1014,10 @@ COVER_CLASSES = { def make_cover(book_info, *args, **kwargs): + cover_class_name = None if 'cover_class' in kwargs: cover_class_name = kwargs.pop('cover_class') - else: - cover_class_name = book_info.cover_class + if not cover_class_name: + cover_class_name = 'default' cover_class = COVER_CLASSES[cover_class_name] return cover_class(book_info, *args, **kwargs) diff --git a/src/librarian/covers/marquise.py b/src/librarian/covers/marquise.py index d0ce49e..830c7b6 100644 --- a/src/librarian/covers/marquise.py +++ b/src/librarian/covers/marquise.py @@ -81,74 +81,81 @@ class MarquiseCover(Cover): 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), - ] + if self.predesigned: + bg = Background(self, crop_to_square=False) + bg.apply( + img, + 0, 0, + self.m.width, self.m.height + ) 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), - ] - - # Trying all the layout options with decreasing scale. - title_box = None - title_scale = 1 - while title_box is 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, - scale=title_scale - ) - except DoesNotFit: - continue - else: - break - title_scale *= .99 - - 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(( + 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), + ] + + # Trying all the layout options with decreasing scale. + title_box = None + title_scale = 1 + while title_box is 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, + scale=title_scale + ) + except DoesNotFit: + continue + else: + break + title_scale *= .99 + + self.marquise_height = marquise_h + marquise = Marquise(self, self.marquise_height) + + bg.apply( + img, 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.author_width).apply( - img, self.m.width - self.m.margin - self.m.author_width, self.m.margin - ) - WLLogo(self).apply(img, self.m.margin, self.m.margin, None, self.m.logo_h) + 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.author_width).apply( + img, self.m.width - self.m.margin - self.m.author_width, self.m.margin + ) + WLLogo(self).apply(img, self.m.margin, self.m.margin, None, self.m.logo_h) for logo in self.additional_logos: @@ -167,13 +174,13 @@ class LabelMarquiseCover(MarquiseCover): 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 - ) + if not self.predesigned: + Label(self).apply( + img, + self.m.label_left, + self.marquise_height - self.label_top, + self.m.label_w, + self.m.label_h + ) return img diff --git a/src/librarian/covers/widgets/background.py b/src/librarian/covers/widgets/background.py index 7836b5c..fd8c764 100644 --- a/src/librarian/covers/widgets/background.py +++ b/src/librarian/covers/widgets/background.py @@ -8,6 +8,10 @@ from .base import Widget class Background(Widget): transparency = False + def __init__(self, cover, crop_to_square=True): + self.crop_to_square = crop_to_square + super().__init__(cover) + def setup(self): self.img = None if self.cover.book_info.cover_url: @@ -21,25 +25,32 @@ class Background(Widget): img = PIL.Image.open(data) - # crop top square. - if img.size[1] > img.size[0]: - img = img.crop((0, 0, img.size[0], img.size[0])) - else: - left = round((img.size[0] - img.size[1])/2) - img = img.crop(( - left, - 0, - left + img.size[1], - img.size[1] - )) + if self.crop_to_square: + # crop top square. + if img.size[1] > img.size[0]: + img = img.crop((0, 0, img.size[0], img.size[0])) + else: + left = round((img.size[0] - img.size[1])/2) + img = img.crop(( + left, + 0, + left + img.size[1], + img.size[1] + )) self.img = img def build(self, w, h): if not self.img: return - kwadrat = round(max(w, h)) img = self.img - img = self.img.resize((kwadrat, kwadrat)) + scale = max( + w / img.size[0], + h / img.size[1] + ) + img = self.img.resize(( + round(scale * img.size[0]), + round(scale * img.size[1]), + )) img = img.crop(( int((img.size[0] - w) / 2), 0, -- 2.20.1