From b3480491be0a81d8beeff3f1b6450876070dbe78 Mon Sep 17 00:00:00 2001 From: Matthias Bisping Date: Mon, 23 Jan 2023 12:13:21 +0100 Subject: [PATCH] Refactoring Move line formatting code into its own class. --- test/fixtures/page_generation/page.py | 81 ++++++++++++++++----------- 1 file changed, 49 insertions(+), 32 deletions(-) diff --git a/test/fixtures/page_generation/page.py b/test/fixtures/page_generation/page.py index f8c6922..5f7ae1e 100644 --- a/test/fixtures/page_generation/page.py +++ b/test/fixtures/page_generation/page.py @@ -1,3 +1,4 @@ +import abc import io import itertools import random @@ -411,7 +412,11 @@ class ContentGenerator: tables_1 = lmap(generate_recursive_random_table, every_nth(2, text_boxes[1:])) # TODO: Refactor: Figures should be their own class - plots, captions = map(list, zip(*map(generate_random_figure, every_nth(2, figure_boxes)))) + try: + plots, captions = map(list, zip(*map(generate_random_figure, every_nth(2, figure_boxes)))) + except ValueError: + plots, captions = [], [] + tables_2 = lmap(generate_recursive_random_table, every_nth(2, figure_boxes[1:])) boxes = text_boxes + plots + captions + tables_1 + tables_2 @@ -918,40 +923,16 @@ def write_lines_to_image(lines: List[str], rectangle: Rectangle, font=None) -> I return image -class TextBlock(ContentRectangle): - def __init__(self, x1, y1, x2, y2): - super().__init__(x1, y1, x2, y2) - self.blank_line_percentage = random.uniform(0, 0.5) - self.font = ImageFont.load_default() # pick_random_font_available_on_system() +class LineFormatter(abc.ABC): + pass - def __call__(self, *args, **kwargs): - pass - def generate_random_text(self, rectangle: Rectangle, n_sentences=3000): - lines = generate_random_text_lines(rectangle, self.format_lines, n_sentences) - image = write_lines_to_image(lines, rectangle, self.font) - return self.__put_content(image) +class ParagraphLineFormatter(LineFormatter): + def __init__(self, blank_line_percentage=None): + self.blank_line_percentage = blank_line_percentage or random.uniform(0, 0.5) - def put_text(self, text: str, rectangle: Rectangle): - - text_width, text_height = self.font.getsize(text) - - width_delta = text_width - rectangle.width - height_delta = text_height - rectangle.height - - image = Image.new("RGBA", (text_width, text_height), (0, 255, 255, 0)) - - if width_delta > 0 or height_delta > 0: - image = image.resize((int(rectangle.width * 0.9), text_height)) - - draw = ImageDraw.Draw(image) - draw.text((0, 0), text, font=self.font, fill=(0, 0, 0, 255)) - return self.__put_content(image) - - def __put_content(self, image: Image.Image): - self.content = image if not self.content else superimpose_texture_with_transparency(self.content, image) - assert self.content.mode == "RGBA" - return self + def __call__(self, lines, last_full): + return self.format_lines(lines, last_full) def format_lines(self, lines, last_full): def truncate_current_line(): @@ -982,6 +963,42 @@ class TextBlock(ContentRectangle): return line +class TextBlock(ContentRectangle): + def __init__(self, x1, y1, x2, y2, line_formatter=None): + super().__init__(x1, y1, x2, y2) + self.font = ImageFont.load_default() # pick_random_font_available_on_system() + self.line_formatter = line_formatter or ParagraphLineFormatter(blank_line_percentage=random.uniform(0, 0.5)) + + def __call__(self, *args, **kwargs): + pass + + def generate_random_text(self, rectangle: Rectangle, n_sentences=3000): + lines = generate_random_text_lines(rectangle, self.line_formatter, n_sentences) + image = write_lines_to_image(lines, rectangle, self.font) + return self.__put_content(image) + + def put_text(self, text: str, rectangle: Rectangle): + + text_width, text_height = self.font.getsize(text) + + width_delta = text_width - rectangle.width + height_delta = text_height - rectangle.height + + image = Image.new("RGBA", (text_width, text_height), (0, 255, 255, 0)) + + if width_delta > 0 or height_delta > 0: + image = image.resize((int(rectangle.width * 0.9), text_height)) + + draw = ImageDraw.Draw(image) + draw.text((0, 0), text, font=self.font, fill=(0, 0, 0, 255)) + return self.__put_content(image) + + def __put_content(self, image: Image.Image): + self.content = image if not self.content else superimpose_texture_with_transparency(self.content, image) + assert self.content.mode == "RGBA" + return self + + def generate_random_text_lines(rectangle: Rectangle, line_formatter=identity, n_sentences=3000) -> List[str]: text = Faker().paragraph(nb_sentences=n_sentences, variable_nb_sentences=False, ext_word_list=None) unformatted_lines = textwrap.wrap(text, width=rectangle.width, break_long_words=False)