diff --git a/commands/edit-image-text/font.js b/commands/edit-image-text/font.js index 9589f63a..664441c3 100644 --- a/commands/edit-image-text/font.js +++ b/commands/edit-image-text/font.js @@ -1,6 +1,6 @@ const Command = require('../../framework/Command'); const { createCanvas } = require('@napi-rs/canvas'); -const { wrapText, fillTextWithBreaks } = require('../../util/Canvas'); +const { wrapText, fillTextWithBreaks, measureTextHeightWithBreaks } = require('../../util/Canvas'); module.exports = class FontCommand extends Command { constructor(client) { @@ -38,7 +38,7 @@ module.exports = class FontCommand extends Command { ctxPre.font = this.client.fonts.get(font.filename).toCanvasString(50); const len = ctxPre.measureText(text); const lines = wrapText(ctxPre, text, 950); - const height = len.emHeightAscent + len.emHeightDescent; + const height = measureTextHeightWithBreaks(ctx, text); const canvas = createCanvas(Math.min(len.width + 50, 1000), 50 + height); const ctx = canvas.getContext('2d'); ctx.font = this.client.fonts.get(font.filename).toCanvasString(50); diff --git a/commands/edit-image-text/spongebob-time-card.js b/commands/edit-image-text/spongebob-time-card.js index ef29f8b9..3ff52ba2 100644 --- a/commands/edit-image-text/spongebob-time-card.js +++ b/commands/edit-image-text/spongebob-time-card.js @@ -2,7 +2,7 @@ const Command = require('../../framework/Command'); const { PermissionFlagsBits } = require('discord.js'); const { createCanvas, loadImage } = require('@napi-rs/canvas'); const path = require('path'); -const { wrapText } = require('../../util/Canvas'); +const { wrapText, measureTextHeightWithBreaks } = require('../../util/Canvas'); module.exports = class SpongebobTimeCardCommand extends Command { constructor(client) { @@ -71,7 +71,8 @@ module.exports = class SpongebobTimeCardCommand extends Command { ctx.font = this.client.fonts.get('Spongeboytt1.ttf').toCanvasString(fontSize); let lines = wrapText(ctx, text.toUpperCase(), 1800); let metrics = ctx.measureText(lines.join('\n')); - while (metrics.width > 1800 || (metrics.actualBoundingBoxAscent + metrics.actualBoundingBoxDescent) > 1000) { + let heightMetric = measureTextHeightWithBreaks(ctx, lines.join('\n')); + while (metrics.width > 1800 || heightMetric > 1000) { fontSize -= 10; ctx.font = this.client.fonts.get('Spongeboytt1.ttf').toCanvasString(fontSize); metrics = ctx.measureText(lines.join('\n')); diff --git a/commands/edit-image-text/tweet.js b/commands/edit-image-text/tweet.js index 330fdcb9..9262427d 100644 --- a/commands/edit-image-text/tweet.js +++ b/commands/edit-image-text/tweet.js @@ -10,7 +10,7 @@ const request = require('node-superfetch'); const { readFile } = require('fs/promises'); const path = require('path'); const { formatNumberK, randomRange } = require('../../util/Util'); -const { wrapText, fillTextWithBreaks } = require('../../util/Canvas'); +const { wrapText, fillTextWithBreaks, measureTextHeightWithBreaks } = require('../../util/Canvas'); module.exports = class TweetCommand extends Command { constructor(client) { @@ -68,8 +68,8 @@ module.exports = class TweetCommand extends Command { const ctx = canvas.getContext('2d'); ctx.font = this.client.fonts.get('ChirpRegular.ttf').toCanvasString(23); const lines = wrapText(ctx, text, 710, true); - const metrics = ctx.measureText(lines.join('\n')); - const linesLen = metrics.actualBoundingBoxAscent + metrics.actualBoundingBoxDescent + 15; + const metrics = measureTextHeightWithBreaks(ctx, lines.join('\n'), true); + const linesLen = metrics + 15; canvas.height += linesLen; let imageHeight = 0; ctx.fillStyle = 'black'; @@ -224,13 +224,18 @@ module.exports = class TweetCommand extends Command { const wrapped = wrapText(ctx, text, maxLineLen, true); const emoji = text.match(emojiRegex()); if (!emoji) { - fillTextWithBreaks(ctx, wrapped.join('\n'), x, y); + fillTextWithBreaks(ctx, wrapped.join('\n'), x, y, true); this.fillHashtags(ctx, wrapped, x, y, emojiSize); return ctx; } let currentY = y; for (let currentLine = 0; currentLine < wrapped.length; currentLine++) { const line = wrapped[currentLine]; + if (line === '') { + const metrics = ctx.measureText('a'); + currentY += metrics.emHeightAscent + metrics.emHeightDescent; + continue; + } const lineEmoji = line.match(emojiRegex()); let currentX = x; const metrics = ctx.measureText(line); @@ -262,6 +267,11 @@ module.exports = class TweetCommand extends Command { fillHashtags(ctx, wrappedText, x, y, emojiSize) { let currentY = y; for (const line of wrappedText) { + if (line === '') { + const metrics = ctx.measureText('a'); + currentY += metrics.emHeightAscent + metrics.emHeightDescent; + continue; + } const words = line.split(' '); for (let i = 0; i < words.length; i++) { const word = words[i]; diff --git a/util/Canvas.js b/util/Canvas.js index 4c00b930..b1d27498 100644 --- a/util/Canvas.js +++ b/util/Canvas.js @@ -197,11 +197,11 @@ module.exports = class CanvasUtil { return ctx; } - static fillTextWithBreaks(ctx, text, x, y, maxLen) { + static fillTextWithBreaks(ctx, text, x, y, maxLen, drawMultiBreaks = false) { const lines = text.split('\n'); let currentY = y; for (const line of lines) { - if (line === '') { + if (line === '' && drawMultiBreaks) { const metrics = ctx.measureText('a'); currentY += metrics.emHeightAscent + metrics.emHeightDescent; } else { @@ -213,6 +213,21 @@ module.exports = class CanvasUtil { return ctx; } + measureTextHeightWithBreaks(ctx, text, parseMultiBreaks = false) { + const lines = text.split('\n'); + let result = 0; + for (const line of lines) { + if (line === '' && parseMultiBreaks) { + const metrics = ctx.measureText('a'); + result += metrics.emHeightAscent + metrics.emHeightDescent; + } else { + const metrics = ctx.measureText(line); + result += metrics.emHeightAscent + metrics.emHeightDescent; + } + } + return result; + } + static shortenText(ctx, text, maxWidth) { let shorten = false; while (ctx.measureText(`${text}...`).width > maxWidth) {