diff --git a/dcc/text.py b/dcc/text.py index 06b5a2e..75df5b4 100644 --- a/dcc/text.py +++ b/dcc/text.py @@ -1,11 +1,13 @@ import dcc.config import dcc.doom_base import sys +import textwrap import wand.drawing import wand.image -def draw_text(self, img, text, font_size=64): +def draw_text(self, img, text, font_size=64, wrap_dist=0.75): + textlines = text.splitlines() with wand.drawing.Drawing() as draw: draw.font = self.thumbnail_font draw.font_size = font_size @@ -13,11 +15,41 @@ def draw_text(self, img, text, font_size=64): draw.stroke_color = wand.color.Color(self.thumbnail_text_stroke) draw.stroke_width = font_size * 5 / 32 draw.text_interline_spacing = -font_size / 4 - draw.text(5, int(draw.font_size) + 5, text) + + target_width = wrap_dist * img.width + + def eval_metrics(txt): + metrics = draw.get_font_metrics(img, wrapped_text, True) + return (metrics.text_width, metrics.text_height) + + for idx, wrapped_text in enumerate(textlines): + while True: + width, height = eval_metrics(wrapped_text) + if width <= target_width: + break + columns = len(wrapped_text) + while columns > 0: + columns -= 1 + wrapped_text = '\n'.join( + textwrap.wrap(wrapped_text, columns) + ) + wrapped_width, _ = eval_metrics(wrapped_text) + if wrapped_width <= target_width: + break + if columns == 0: + raise Exception( + "couldn't calculate text wrapping; " + + f"final attempt was {wrapped_text}" + ) + textlines[idx] = wrapped_text + + wrapped_text = '\n'.join(textlines) + + draw.text(5, int(draw.font_size) + 5, wrapped_text) draw(img) draw.stroke_color = wand.color.Color("none") draw.stroke_width = 0 - draw.text(5, int(draw.font_size)+5, text) + draw.text(5, int(draw.font_size)+5, wrapped_text) draw(img)