Switch font render backend
This commit is contained in:
parent
71b069c7f7
commit
187e150c85
Binary file not shown.
|
@ -212,7 +212,7 @@ async def send_quote_image(
|
|||
image = Image(file=bytesio)
|
||||
else:
|
||||
image = Image(width=64, height=64, background="#FFFF00")
|
||||
quote_image = make_quote_image(sender_name, body, image)
|
||||
quote_image = await make_quote_image(sender_name, body, image)
|
||||
await send_sticker_image(client, room.room_id, quote_image, reply_to)
|
||||
|
||||
else:
|
||||
|
@ -270,7 +270,7 @@ async def send_sticker_image(
|
|||
image.save(file=bytesio)
|
||||
length = bytesio.getbuffer().nbytes
|
||||
bytesio.seek(0)
|
||||
logger.debug(f'Sending Image with length {length}, width={width}, height={height}')
|
||||
logger.debug(f"Sending Image with length {length}, width={width}, height={height}")
|
||||
|
||||
resp, maybe_keys = await client.upload(
|
||||
bytesio,
|
||||
|
|
|
@ -1,28 +1,37 @@
|
|||
import logging
|
||||
import os.path
|
||||
from asyncio import create_subprocess_exec
|
||||
from asyncio.subprocess import PIPE
|
||||
from html import escape
|
||||
from tempfile import mkstemp
|
||||
|
||||
from wand.drawing import Drawing
|
||||
from wand.image import Image
|
||||
from wand.color import Color
|
||||
import os.path
|
||||
|
||||
import nyx_bot
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
TEXTBOX_PADDING_PIX = 8
|
||||
TEXTBOX_INNER_MARGIN = 4
|
||||
TEXTBOX_INNER_MARGIN = 2
|
||||
AVATAR_SIZE = 48
|
||||
AVATAR_RIGHT_PADDING = 6
|
||||
BORDER_MARGIN = 8
|
||||
MIN_TEXTBOX_WIDTH = 256
|
||||
|
||||
FONT_FILE = os.path.join(nyx_bot.__path__[0], "DroidSansFallback.ttf")
|
||||
MASK_FILE = os.path.join(nyx_bot.__path__[0], "mask.png")
|
||||
|
||||
def make_quote_image(sender: str, text: str, avatar: Image):
|
||||
PANGO_MARKUP_TEMPLATE = """\
|
||||
<span size="larger" foreground="orange" weight="bold">{}</span>
|
||||
{}
|
||||
"""
|
||||
|
||||
|
||||
async def make_quote_image(sender: str, text: str, avatar: Image):
|
||||
draw = Drawing()
|
||||
draw.font = FONT_FILE
|
||||
draw.font_size = 15
|
||||
with Image(width=2000, height=2000) as i:
|
||||
bbox = draw.get_font_metrics(i, text, True)
|
||||
sender_bbox = draw.get_font_metrics(i, sender, False)
|
||||
text_width = max(bbox.text_width, sender_bbox.text_width)
|
||||
textbox_height = (TEXTBOX_PADDING_PIX * 2) + bbox.text_height + sender_bbox.text_height + TEXTBOX_INNER_MARGIN
|
||||
imagefile = await render_text(PANGO_MARKUP_TEMPLATE.format(sender, escape(text)))
|
||||
image = Image(filename=imagefile)
|
||||
text_width = image.width
|
||||
text_height = image.height
|
||||
textbox_height = (TEXTBOX_PADDING_PIX * 2) + text_height + TEXTBOX_INNER_MARGIN - 8
|
||||
# Original textbox width
|
||||
textbox_width_orig = (TEXTBOX_PADDING_PIX * 2) + text_width
|
||||
# Final textbox width
|
||||
|
@ -41,21 +50,49 @@ def make_quote_image(sender: str, text: str, avatar: Image):
|
|||
img.resize(AVATAR_SIZE, AVATAR_SIZE)
|
||||
img.alpha_channel = True
|
||||
img.composite_channel("default", mask, "copy_alpha", 0, 0)
|
||||
draw.composite("overlay", BORDER_MARGIN, BORDER_MARGIN, AVATAR_SIZE, AVATAR_SIZE, img)
|
||||
draw.composite(
|
||||
"overlay", BORDER_MARGIN, BORDER_MARGIN, AVATAR_SIZE, AVATAR_SIZE, img
|
||||
)
|
||||
|
||||
# Make image
|
||||
draw.fill_color = "#111111"
|
||||
draw.fill_color = "#000000"
|
||||
draw.stroke_width = 0
|
||||
draw.rectangle(textbox_x, textbox_y, width=textbox_width, height=textbox_height, radius=8)
|
||||
draw.rectangle(
|
||||
textbox_x, textbox_y, width=textbox_width, height=textbox_height, radius=8
|
||||
)
|
||||
|
||||
# Draw text
|
||||
draw.fill_color = "#FFFFFF"
|
||||
name_x = textbox_x + TEXTBOX_PADDING_PIX
|
||||
name_y = textbox_y + TEXTBOX_PADDING_PIX + 14
|
||||
draw.text(int(name_x), int(name_y), sender)
|
||||
text_x = name_x
|
||||
text_y = name_y + TEXTBOX_INNER_MARGIN + sender_bbox.text_height
|
||||
draw.text(int(text_x), int(text_y), text)
|
||||
text_x = textbox_x + TEXTBOX_PADDING_PIX
|
||||
text_y = textbox_y + TEXTBOX_PADDING_PIX - 4
|
||||
with image:
|
||||
draw.composite("src_over", text_x, text_y, text_width, text_height, image)
|
||||
ret = Image(width=int(width), height=int(height))
|
||||
draw(ret)
|
||||
return ret
|
||||
|
||||
|
||||
async def render_text(text: str) -> str:
|
||||
_, path = mkstemp(".png")
|
||||
logger.debug(f"File path: {path}")
|
||||
proc = await create_subprocess_exec(
|
||||
"pango-view",
|
||||
"--background=black",
|
||||
"--foreground=white",
|
||||
"--font=Noto Sans CJK SC 16",
|
||||
"--antialias=gray",
|
||||
"--margin=0",
|
||||
"--hinting=full",
|
||||
"--subpixel-order=bgr",
|
||||
"--markup",
|
||||
"-q",
|
||||
"-o",
|
||||
path,
|
||||
f"--text={text}",
|
||||
stdin=PIPE,
|
||||
)
|
||||
stdout, stderr = await proc.communicate(input=text.encode("utf-8"))
|
||||
if stdout:
|
||||
print(f"[stdout]\n{stdout}")
|
||||
if stderr:
|
||||
print(f"[stderr]\n{stderr}")
|
||||
return path
|
||||
|
|
Loading…
Reference in a new issue