Refactoring

Move line formatting code into its own class.
This commit is contained in:
Matthias Bisping 2023-01-23 12:13:21 +01:00
parent 3d0c2396ee
commit b3480491be

View File

@ -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)