Browse Source

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
Aakansha Doshi 2 years ago
parent
commit
ab49cad6b1
2 changed files with 38 additions and 29 deletions
  1. 11 2
      src/element/textElement.test.ts
  2. 27 27
      src/element/textElement.ts

+ 11 - 2
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", () => {

+ 27 - 27
src/element/textElement.ts

@@ -327,25 +327,38 @@ export const wrapText = (text: string, font: FontString, maxWidth: number) => {
   const lines: Array<string> = [];
   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);
     }
   });