From: Radek Czajka Date: Wed, 5 Feb 2025 10:44:26 +0000 (+0100) Subject: Bidi text in titles. X-Git-Tag: 24.5.5 X-Git-Url: https://git.mdrn.pl/librarian.git/commitdiff_plain/aeb59958474fc1036ac19618fb1bdbdefd52da60?hp=72e0675156f925cf91d6cf1a3da4799a1f28b02a Bidi text in titles. --- diff --git a/setup.py b/setup.py index cde62c2..4a651a4 100755 --- a/setup.py +++ b/setup.py @@ -22,7 +22,7 @@ def whole_tree(prefix, path): setup( name='librarian', - version='24.5.4', + version='24.5.5', description='Converter from WolneLektury.pl XML-based language to XHTML, TXT and other formats', author="Marek Stępniowski", author_email='marek@stepniowski.com', diff --git a/src/librarian/covers/utils/textbox.py b/src/librarian/covers/utils/textbox.py index e82bee4..c81922b 100644 --- a/src/librarian/covers/utils/textbox.py +++ b/src/librarian/covers/utils/textbox.py @@ -3,6 +3,7 @@ # import PIL.Image import PIL.ImageDraw +import bidi def split_words(text): @@ -17,16 +18,6 @@ def split_words(text): return words - -def text_with_tracking(draw, tracking, pos, text, fill=None, font=None): - x, y = pos - for c in text: - # TODO: adjust for kerning? - width = font.getlength(c) - draw.text((x, y), c, fill=fill, font=font) - x += width + tracking - - class DoesNotFit(Exception): pass @@ -34,11 +25,13 @@ class DoesNotFit(Exception): class TextBox: def __init__(self, width, height, texts, font, lines, leading, tracking, - align_h, align_v): + align_h, align_v, + font_fallbacks=None): self.width = width self.height = height self.texts = texts self.font = font + self.font_fallbacks = font_fallbacks self.lines = lines self.leading = leading self.tracking = tracking @@ -58,9 +51,36 @@ class TextBox: if self.grouping is None: raise DoesNotFit() + def get_font_for_char(self, c): + if self.font_fallbacks: + for char_range, font in self.font_fallbacks.items(): + if char_range[0] <= c <= char_range[1]: + return font + return self.font + def get_length(self, text): - return self.font.getlength(text) + self.tracking * len(text) - + text = bidi.get_display(text, base_dir='L') + groups = [] + for c in text: + font = self.get_font_for_char(c) + if groups and font is groups[-1][0]: + groups[-1][1] += c + else: + groups.append([font, c]) + + return sum( + font.getlength(t) + for (font, t) in groups + ) + self.tracking * len(text) + + def text_with_tracking(self, draw, pos, text, fill=None): + x, y = pos + for c in bidi.get_display(text, base_dir='L'): + cfont = self.get_font_for_char(c) + width = cfont.getlength(c) + draw.text((x, y), c, fill=fill, font=cfont) + x += width + self.tracking + def as_pil_image(self, color): img = PIL.Image.new('RGBA', (self.width, self.height + 2 * self.margin_top)) draw = PIL.ImageDraw.ImageDraw(img) @@ -72,9 +92,9 @@ class TextBox: x = (self.width - group[0] + self.tracking) * self.align_h self.align_h * - group[0] / 2 for s, w in group[1]: - text_with_tracking( - draw, self.tracking, (x, y), - w, fill=color, font=self.font + self.text_with_tracking( + draw, (x, y), + w, fill=color ) x += s + self.glue y += self.leading diff --git a/src/librarian/covers/widgets/title.py b/src/librarian/covers/widgets/title.py index d5a6334..b9dc8cb 100644 --- a/src/librarian/covers/widgets/title.py +++ b/src/librarian/covers/widgets/title.py @@ -27,6 +27,15 @@ class TitleBox(Widget): layout_engine=PIL.ImageFont.Layout.BASIC ) title_font.set_variation_by_axes([800]) + title_font_2 = PIL.ImageFont.truetype( + get_resource('fonts/OpenSans-VariableFont_wdth,wght.ttf'), + self.m.font_size, + layout_engine=PIL.ImageFont.Layout.BASIC + ) + title_font_2.set_variation_by_axes([700, 700]) + font_fallbacks = { + ('\u0590', '\u05FF'): title_font_2, + } lines = self.lines or (int(self.height * (176/200) / self.m.leading) - 0) @@ -38,7 +47,8 @@ class TitleBox(Widget): lines, self.m.leading, self.m.tracking, - .5, .5 + .5, .5, + font_fallbacks=font_fallbacks ) self.margin_top = self.tb.margin_top diff --git a/src/librarian/fonts/OpenSans-VariableFont_wdth,wght.ttf b/src/librarian/fonts/OpenSans-VariableFont_wdth,wght.ttf new file mode 100644 index 0000000..ac587b4 Binary files /dev/null and b/src/librarian/fonts/OpenSans-VariableFont_wdth,wght.ttf differ diff --git a/src/librarian/html.py b/src/librarian/html.py index 456f281..d6482dc 100644 --- a/src/librarian/html.py +++ b/src/librarian/html.py @@ -9,7 +9,7 @@ import urllib.parse import urllib.request from lxml import etree -from librarian import XHTMLNS, ParseError, OutputFile +from librarian import XHTMLNS, DCNS, ParseError, OutputFile from librarian import functions from PIL import Image @@ -112,6 +112,10 @@ def transform(wldoc, stylesheet='legacy', options=None, flags=None, css=None, ga for flag in flags: document.edoc.getroot().set(flag, 'yes') + ltag = document.edoc.find('//' + DCNS('language')) + lang = functions.lang_code_3to2(ltag.text) or 'pl' + document.edoc.getroot().set('lang', lang) + document.clean_ed_note() document.clean_ed_note('abstrakt') document.fix_pa_akap() diff --git a/src/librarian/xslt/book2html.xslt b/src/librarian/xslt/book2html.xslt index b128b7e..6296fc8 100644 --- a/src/librarian/xslt/book2html.xslt +++ b/src/librarian/xslt/book2html.xslt @@ -95,6 +95,9 @@
+ + +