@@ -63,19 +63,34 @@ class LineWrapper extends EventEmitter
6363 while bk = breaker .nextBreak ()
6464 word = text .slice (last ? .position or 0 , bk .position )
6565 w = wordWidths[word] ?= @ wordWidth word
66-
66+
6767 # if the word is longer than the whole line, chop it up
6868 # TODO: break by grapheme clusters, not JS string characters
6969 if w > @lineWidth + @continuedX
7070 # make some fake break objects
7171 lbk = last
7272 fbk = {}
73-
73+
7474 while word .length
7575 # fit as much of the word as possible into the space we have
76- l = word .length
77- while w > @spaceLeft and l > 0
78- w = @ wordWidth word .slice (0 , -- l)
76+ if w > @spaceLeft
77+ # start our check at the end of our available space - this method is faster than a loop of each character and it resolves
78+ # an issue with long loops when processing massive words, such as a huge number of spaces
79+ l = Math .ceil (@spaceLeft / (w / word .length ))
80+ w = @ wordWidth word .slice (0 , l)
81+ mightGrow = w <= @spaceLeft and l < word .length
82+ else
83+ l = word .length
84+ mustShrink = w > @spaceLeft and l > 0
85+ # shrink or grow word as necessary after our near-guess above
86+ while mustShrink or mightGrow
87+ if mustShrink
88+ w = @ wordWidth word .slice (0 , -- l)
89+ mustShrink = w > @spaceLeft and l > 0
90+ else
91+ w = @ wordWidth word .slice (0 , ++ l)
92+ mustShrink = w > @spaceLeft and l > 0
93+ mightGrow = w <= @spaceLeft and l < word .length
7994
8095 # send a required break unless this is the last piece
8196 fbk .required = l < word .length
0 commit comments