1 # -*- coding: utf-8 -*-
3 # This file is part of Librarian, licensed under GNU Affero GPLv3 or later.
4 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
6 import Image, ImageFont, ImageDraw, ImageFilter
7 from librarian import get_resource
13 background_color = '#fff'
18 author_margin_left = 20
19 author_margin_right = 20
28 title_margin_left = 20
29 title_margin_right = 20
53 def person_shortener(text):
56 n_chunks = len(chunks)
57 # make initials from given names, starting from last
58 for i in range(n_chunks - 2, -1, -1):
59 chunks[i] = chunks[i][0] + '.'
60 yield " ".join(chunks)
61 # remove given names initials, starting from last
62 while len(chunks) > 2:
64 yield " ".join(chunks)
67 def title_shortener(text):
70 n_chunks = len(chunks)
71 # remove words, starting from last one
72 while len(chunks) > 1:
74 yield " ".join(chunks) + u'…'
77 def draw_text(text, img, font, align, shortener, margin_left, width, pos_y, lineskip, color, shadow_color):
79 shadow_img = Image.new('RGBA', img.size)
80 shadow_draw = ImageDraw.Draw(shadow_img)
81 text_img = Image.new('RGBA', img.size)
82 text_draw = ImageDraw.Draw(text_img)
85 for line in shortener(text):
86 if text_draw.textsize(line, font=font)[0] <= width:
91 while text_draw.textsize(line, font=font)[0] > width:
93 line, ext = line.rsplit(' ', 1)
96 text = text[len(line)+1:]
99 pos_x += (width - text_draw.textsize(line, font=font)[0]) / 2
101 pos_x += (width - text_draw.textsize(line, font=font)[0])
103 shadow_draw.text((pos_x + 3, pos_y + 3), line, font=font, fill=shadow_color)
104 text_draw.text((pos_x, pos_y), line, font=font, fill=color)
107 shadow_img = shadow_img.filter(ImageFilter.BLUR)
108 img.paste(shadow_img, None, shadow_img)
109 img.paste(text_img, None, text_img)
113 def __init__(self, author='', title=''):
117 def pretty_author(self):
120 def pretty_title(self):
124 img = Image.new('RGB', (self.width, self.height), self.background_color)
126 if self.background_img:
127 background = Image.open(self.background_img)
129 img.paste(background, None, background)
130 except ValueError, e:
131 img.paste(background)
136 logo = Image.open(get_resource('res/wl-logo.png'))
137 logo = logo.resize((self.logo_width, logo.size[1] * self.logo_width / logo.size[0]))
138 img.paste(logo, ((self.width - self.logo_width) / 2, img.size[1] - logo.size[1] - self.logo_bottom))
140 author_font = self.author_font or ImageFont.truetype(get_resource('fonts/DejaVuSerif.ttf'), 30)
141 author_shortener = None if self.author_wrap else self.person_shortener
142 title_y = self.draw_text(self.pretty_author(), img, author_font, self.author_align, author_shortener,
143 self.author_margin_left, self.width - self.author_margin_left - self.author_margin_right, self.author_top,
144 self.author_lineskip, self.author_color, self.author_shadow) + self.title_top
145 title_shortener = None if self.title_wrap else self.title_shortener
146 title_font = self.title_font or ImageFont.truetype(get_resource('fonts/DejaVuSerif.ttf'), 40)
147 self.draw_text(self.pretty_title(), img, title_font, self.title_align, title_shortener,
148 self.title_margin_left, self.width - self.title_margin_left - self.title_margin_right, title_y,
149 self.title_lineskip, self.title_color, self.title_shadow)
154 return self.mime_types[self.format]
157 return self.exts[self.format]
159 def save(self, *args, **kwargs):
160 return self.image().save(format=self.format, *args, **kwargs)
164 class VirtualoCover(Cover):
173 class PrestigioCover(Cover):
176 background_img = get_resource('res/cover-prestigio.png')
179 author_margin_left = 118
180 author_margin_right = 62
182 author_color = '#fff'
183 author_shadow = '#000'
184 author_font = ImageFont.truetype(get_resource('fonts/JunicodeWL-Italic.ttf'), 50)
187 title_margin_left = 118
188 title_margin_right = 62
191 title_shadow = '#000'
192 title_font = ImageFont.truetype(get_resource('fonts/JunicodeWL-Italic.ttf'), 50)
194 def pretty_title(self):
195 return u"„%s”" % self.title
198 class BookotekaCover(Cover):
201 background_img = get_resource('res/cover-bookoteka.png')
204 author_margin_left = 307
205 author_margin_right = 233
206 author_lineskip = 156
207 author_color = '#d9d919'
208 author_font = ImageFont.truetype(get_resource('fonts/JunicodeWL-Regular.ttf'), 130)
211 title_margin_left = 307
212 title_margin_right = 233
214 title_color = '#d9d919'
215 title_font = ImageFont.truetype(get_resource('fonts/JunicodeWL-Regular.ttf'), 140)
220 class GandalfCover(Cover):
223 background_img = get_resource('res/cover-gandalf.png')
224 author_font = ImageFont.truetype(get_resource('fonts/JunicodeWL-Regular.ttf'), 30)
225 title_font = ImageFont.truetype(get_resource('fonts/JunicodeWL-Regular.ttf'), 40)
231 class ArtaTechCover(Cover):
234 background_img = get_resource('res/cover-arta-tech.jpg')
236 author_margin_left = 235
237 author_margin_right = 23
239 author_font = ImageFont.truetype(get_resource('fonts/DroidSans.ttf'), 32)
240 author_color = '#555555'
243 title_margin_right = 21
244 title_margin_left = 60
246 title_font = ImageFont.truetype(get_resource('fonts/EBGaramond-Regular.ttf'), 42)
247 title_color = '#222222'
251 def pretty_author(self):
252 return self.author.upper()
256 """ a class factory for simple image covers """
257 img = Image.open(img)
259 class ImgCover(Cover):
265 return self.image().format