diff --git a/nodes/generate.py b/nodes/generate.py index ca5f1e7..c80b65d 100644 --- a/nodes/generate.py +++ b/nodes/generate.py @@ -1,5 +1,3 @@ -import threading -from typing import cast import qrcode from PIL import Image @@ -192,6 +190,7 @@ def bbox_dim(bbox): height = lower - upper return width, height +# TODO: Auto install the base font to ComfyUI/fonts class TextToImage: """Utils to convert text to image using a font. @@ -213,7 +212,7 @@ class TextToImage: for extension in font_extensions: try: if comfy_dir.exists(): - fonts.extend(comfy_dir.glob(f"**/{extension}")) + fonts.extend(comfy_dir.glob(f"fonts/**/{extension}")) else: log.warn(f"Directory {comfy_dir} does not exist.") except Exception as e: @@ -233,8 +232,9 @@ class TextToImage: @classmethod def INPUT_TYPES(cls): if not cls.fonts: - thread = threading.Thread(target=cls.CACHE_FONTS) - thread.start() + # thread = threading.Thread(target=cls.CACHE_FONTS) + # thread.start() + cls.CACHE_FONTS() else: log.debug(f"Using cached fonts (count: {len(cls.fonts)})") return { @@ -244,13 +244,25 @@ class TextToImage: {"default": "Hello world!"}, ), "font": ((sorted(cls.fonts.keys())),), + # "wrap": ( + # "INT", + # {"default": 120, "min": 0, "max": 8096, "step": 1}, + # ), "wrap": ( - "INT", - {"default": 120, "min": 0, "max": 8096, "step": 1}, + "BOOLEAN", + {"default": True} + ), + "trim": ( + "BOOLEAN", + {"default": True} + ), + "line_height": ( + "FLOAT", + {"default": 1.0, "min": 0, "step":0.1}, ), "font_size": ( "INT", - {"default": 12, "min": 1, "max": 2500, "step": 1}, + {"default": 32, "min": 1, "max": 2500, "step": 1}, ), "width": ( "INT", @@ -280,9 +292,11 @@ class TextToImage: def text_to_image( self, - text, + text:str, font, wrap, + trim, + line_height, font_size, width, height, @@ -297,12 +311,14 @@ class TextToImage: font_path = self.fonts[font] + text = text.encode("ascii", "ignore").decode().strip() if trim else text # Handle word wrapping if wrap: - lines = textwrap.wrap(text, width=wrap) + wrap_width = (width / font_size) * 2 + lines = textwrap.wrap(text, width=wrap_width) else: lines = [text] - font = ImageFont.truetype(font_path, font_size) + font = ImageFont.truetype(font_path, size=font_size) # font = ImageFont.truetype(font_path, font_size) # if wrap == 0: # wrap = width / font_size @@ -311,20 +327,20 @@ class TextToImage: img = Image.new("RGBA", (width, height), background) draw = ImageDraw.Draw(img) - text_height = sum(font.getsize(line)[1] for line in lines) + line_height = line_height * font_size + # Vertical alignment if v_align == "top": y_text = 0 elif v_align == "center": - y_text = (height - text_height) // 2 + y_text = (height - (line_height * len(lines))) // 2 else: # bottom - y_text = height - text_height + y_text = height - (line_height * len(lines)) # Draw each line of text for line in lines: - line_width, line_height = font.getsize(line) - + line_width = font.getlength(line) # Horizontal alignment if h_align == "left": x_text = 0 diff --git a/web/debug.js b/web/debug.js index 319bf1b..92128f9 100644 --- a/web/debug.js +++ b/web/debug.js @@ -41,7 +41,7 @@ app.registerExtension({ type, index, connected, - link_info + link_info, ) { const r = onConnectionsChange ? onConnectionsChange.apply(this, arguments) @@ -52,7 +52,7 @@ app.registerExtension({ //- infer type if (link_info) { const fromNode = this.graph._nodes.find( - (otherNode) => otherNode.id == link_info.origin_id + (otherNode) => otherNode.id == link_info.origin_id, ) const type = fromNode.outputs[link_info.origin_slot].type this.inputs[index].type = type @@ -63,6 +63,7 @@ app.registerExtension({ this.inputs[index].type = '*' this.inputs[index].label = `anything_${index + 1}` } + return r } const onExecuted = nodeType.prototype.onExecuted @@ -86,7 +87,7 @@ app.registerExtension({ if (message.text) { for (const txt of message.text) { const w = this.addCustomWidget( - MtbWidgets.DEBUG_STRING(`${prefix}_${widgetI}`, escapeHtml(txt)) + MtbWidgets.DEBUG_STRING(`${prefix}_${widgetI}`, escapeHtml(txt)), ) w.parent = this widgetI++ @@ -95,7 +96,7 @@ app.registerExtension({ if (message.b64_images) { for (const img of message.b64_images) { const w = this.addCustomWidget( - MtbWidgets.DEBUG_IMG(`${prefix}_${widgetI}`, img) + MtbWidgets.DEBUG_IMG(`${prefix}_${widgetI}`, img), ) w.parent = this widgetI++