From ab49cad6b1e84db512c12d9b030c0d615c402b58 Mon Sep 17 00:00:00 2001 From: Aakansha Doshi Date: Tue, 14 Mar 2023 17:18:16 +0530 Subject: [PATCH] perf: break early if the line width <= max width of the container (#6347) * fix: break early if the line width <= max width of the container * Remove dead code * remove dead code * lint * remove --- src/element/textElement.test.ts | 13 ++++++-- src/element/textElement.ts | 54 ++++++++++++++++----------------- 2 files changed, 38 insertions(+), 29 deletions(-) diff --git a/src/element/textElement.test.ts b/src/element/textElement.test.ts index 7bc361b4..3de96037 100644 --- a/src/element/textElement.test.ts +++ b/src/element/textElement.test.ts @@ -16,7 +16,7 @@ describe("Test wrapText", () => { const text = "Hello whats up "; const maxWidth = 200 - BOUND_TEXT_PADDING * 2; const res = wrapText(text, font, maxWidth); - expect(res).toBe("Hello whats up "); + expect(res).toBe(text); }); it("should work with emojis", () => { @@ -26,7 +26,7 @@ describe("Test wrapText", () => { expect(res).toBe("๐Ÿ˜€"); }); - it("should show the text correctly when min width reached", () => { + it("should show the text correctly when max width reached", () => { const text = "Hello๐Ÿ˜€"; const maxWidth = 10; const res = wrapText(text, font, maxWidth); @@ -136,6 +136,7 @@ whats up`, }); }); }); + describe("When text is long", () => { const text = `hellolongtextthisiswhatsupwithyouIamtypingggggandtypinggg break it now`; [ @@ -175,6 +176,14 @@ break it now`, }); }); }); + + it("should wrap the text correctly when word length is exactly equal to max width", () => { + const text = "Hello Excalidraw"; + // Length of "Excalidraw" is 100 and exacty equal to max width + const res = wrapText(text, font, 100); + expect(res).toEqual(`Hello +Excalidraw`); + }); }); describe("Test measureText", () => { diff --git a/src/element/textElement.ts b/src/element/textElement.ts index bdb11c9a..068d4a82 100644 --- a/src/element/textElement.ts +++ b/src/element/textElement.ts @@ -327,25 +327,38 @@ export const wrapText = (text: string, font: FontString, maxWidth: number) => { const lines: Array = []; const originalLines = text.split("\n"); const spaceWidth = getLineWidth(" ", font); + + let currentLine = ""; + let currentLineWidthTillNow = 0; + const push = (str: string) => { if (str.trim()) { lines.push(str); } }; + + const resetParams = () => { + currentLine = ""; + currentLineWidthTillNow = 0; + }; + originalLines.forEach((originalLine) => { - const words = originalLine.split(" "); - // This means its newline so push it - if (words.length === 1 && words[0] === "") { - lines.push(words[0]); + const currentLineWidth = getTextWidth(originalLine, font); + + //Push the line if its <= maxWidth + if (currentLineWidth <= maxWidth) { + lines.push(originalLine); return; // continue } - let currentLine = ""; - let currentLineWidthTillNow = 0; + const words = originalLine.split(" "); + + resetParams(); let index = 0; while (index < words.length) { const currentWordWidth = getLineWidth(words[index], font); + // This will only happen when single word takes entire width if (currentWordWidth === maxWidth) { push(words[index]); @@ -357,8 +370,8 @@ export const wrapText = (text: string, font: FontString, maxWidth: number) => { // push current line since the current word exceeds the max width // so will be appended in next line push(currentLine); - currentLine = ""; - currentLineWidthTillNow = 0; + + resetParams(); while (words[index].length > 0) { const currentChar = String.fromCodePoint( @@ -369,10 +382,6 @@ export const wrapText = (text: string, font: FontString, maxWidth: number) => { words[index] = words[index].slice(currentChar.length); if (currentLineWidthTillNow >= maxWidth) { - // only remove last trailing space which we have added when joining words - if (currentLine.slice(-1) === " ") { - currentLine = currentLine.slice(0, -1); - } push(currentLine); currentLine = currentChar; currentLineWidthTillNow = width; @@ -380,11 +389,11 @@ export const wrapText = (text: string, font: FontString, maxWidth: number) => { currentLine += currentChar; } } + // push current line if appending space exceeds max width if (currentLineWidthTillNow + spaceWidth >= maxWidth) { push(currentLine); - currentLine = ""; - currentLineWidthTillNow = 0; + resetParams(); } else { // space needs to be appended before next word // as currentLine contains chars which couldn't be appended @@ -392,7 +401,6 @@ export const wrapText = (text: string, font: FontString, maxWidth: number) => { currentLine += " "; currentLineWidthTillNow += spaceWidth; } - index++; } else { // Start appending words in a line till max width reached @@ -402,8 +410,7 @@ export const wrapText = (text: string, font: FontString, maxWidth: number) => { if (currentLineWidthTillNow > maxWidth) { push(currentLine); - currentLineWidthTillNow = 0; - currentLine = ""; + resetParams(); break; } @@ -414,22 +421,15 @@ export const wrapText = (text: string, font: FontString, maxWidth: number) => { if (currentLineWidthTillNow + spaceWidth >= maxWidth) { const word = currentLine.slice(0, -1); push(word); - currentLine = ""; - currentLineWidthTillNow = 0; + resetParams(); break; } } - if (currentLineWidthTillNow === maxWidth) { - currentLine = ""; - currentLineWidthTillNow = 0; - } } } - if (currentLine) { + if (currentLine.slice(-1) === " ") { // only remove last trailing space which we have added when joining words - if (currentLine.slice(-1) === " ") { - currentLine = currentLine.slice(0, -1); - } + currentLine = currentLine.slice(0, -1); push(currentLine); } });