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, wrap_dist=0.75): textlines = text.splitlines() with wand.drawing.Drawing() as draw: draw.font = self.thumbnail_font draw.font_size = font_size draw.fill_color = wand.color.Color(self.thumbnail_text_fill) draw.stroke_color = wand.color.Color(self.thumbnail_text_stroke) draw.stroke_width = font_size * 5 / 32 draw.text_interline_spacing = -font_size / 4 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, wrapped_text) draw(img) dcc.config.Base.draw_text = draw_text class Text(dcc.doom_base.WadMap): def get_parser(self, prog_name): parser = super().get_parser(prog_name) parser.add_argument("--nomap", action="store_true") parser.add_argument("--nomapname", action="store_true") parser.add_argument("--mapname", "-m", default="") parser.add_argument("--demotype", default="UV-Max Demo") return parser def take_action(self, parsed_args): text = "" if not parsed_args.nomapname: if not parsed_args.nomap: text = f"MAP{parsed_args.map}: " text += self.map_name(parsed_args.mapname, parsed_args.map) text += "\n" text = "{}{}".format(text, parsed_args.demotype) with wand.image.Image( height=self.thumbnail_height, width=self.thumbnail_width ) as img: self.draw_text(img, text, wrap_dist=0.95) img.trim() img.reset_coords() img.save(filename=self.text_thumb_path()) def map_name(self, mapname, mapnum): if mapname != "": return mapname map_names = self._config.get("map_names") if map_names is not None: text = map_names.get(f"map{mapnum}") if text != "": return text return input("Map Name? ")