Skip to content

Commit

Permalink
Fix printing string when words are longer than max-width
Browse files Browse the repository at this point in the history
  • Loading branch information
hipstersmoothie committed Sep 2, 2024
1 parent 9828a2f commit 6165765
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 0 deletions.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
18 changes: 18 additions & 0 deletions plugins/plugin-print/src/index.node.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,24 @@ describe("Write text over image", function () {
expect(output).toMatchImageSnapshot();
});

test("Max width works without spaces", async () => {
const font = await loadFont(
"https://raw.githubusercontent.com/jimp-dev/jimp/main/plugins/plugin-print/fonts/open-sans/open-sans-16-black/open-sans-16-black.fnt"
);
const image = new Jimp({ width: 300, height: 100, color: 0xff8800ff });
const output = await image
.print({
font,
x: 150,
y: 50,
text: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
maxWidth: 100,
})
.getBuffer("image/png");

expect(output).toMatchImageSnapshot();
});

test("Jimp renders ? for unknown characters", async () => {
const font = await loadFont(fonts.SANS_16_BLACK);
const image = new Jimp({ width: 300, height: 100, color: 0xff8800ff });
Expand Down
28 changes: 28 additions & 0 deletions plugins/plugin-print/src/measure-text.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,34 @@ export function splitLines(font: BmFont, text: string, maxWidth: number) {
let longestLine = 0;

words.forEach((word) => {
const wordWidth = measureText(font, word + (words.length > 1 ? " " : ""));

// If a word is longer than the allowable width we need to split it across lines.
if (wordWidth > maxWidth) {
const characterIterator = word[Symbol.iterator]();

let current = "";

for (const char of characterIterator) {
const nextLine = [...currentLine, current + char].join(" ");
const length = measureText(font, nextLine);

if (length < maxWidth) {
current += char;
} else if (length > maxWidth) {
lines.push([...currentLine, current]);
currentLine = [];
current = char;
} else {
lines.push([...currentLine, current + char]);
currentLine = [];
current = "";
}
}

return;
}

const line = [...currentLine, word].join(" ");
const length = measureText(font, line);

Expand Down

0 comments on commit 6165765

Please sign in to comment.