-
Notifications
You must be signed in to change notification settings - Fork 24
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement wrapWord parameter (#268) #345
base: dev
Are you sure you want to change the base?
Changes from all commits
da89c2e
98b45c9
8a939ad
4f47680
c7f8c9c
856cc7c
3c98b21
dab52d2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -323,6 +323,7 @@ export class LightningTextTextureRenderer { | |
wordWrapWidth, | ||
letterSpacing, | ||
textIndent, | ||
this._settings.wordBreak, | ||
); | ||
} else { | ||
linesInfo = { l: this._settings.text.split(/(?:\r\n|\r|\n)/), n: [] }; | ||
|
@@ -347,6 +348,7 @@ export class LightningTextTextureRenderer { | |
wordWrapWidth - w, | ||
letterSpacing, | ||
textIndent, | ||
this._settings.wordBreak, | ||
); | ||
usedLines[usedLines.length - 1] = `${al.l[0]!}${ | ||
this._settings.overflowSuffix | ||
|
@@ -681,6 +683,7 @@ export class LightningTextTextureRenderer { | |
wordWrapWidth: number, | ||
letterSpacing: number, | ||
indent = 0, | ||
wordBreak: boolean, | ||
) { | ||
// Greedy wrapping algorithm that will wrap words as the line grows longer. | ||
// than its horizontal bounds. | ||
|
@@ -691,11 +694,21 @@ export class LightningTextTextureRenderer { | |
const resultLines = []; | ||
let result = ''; | ||
let spaceLeft = wordWrapWidth - indent; | ||
const words = lines[i]!.split(' '); | ||
const words = wordBreak ? [lines[i]!] : lines[i]!.split(' '); | ||
for (let j = 0; j < words.length; j++) { | ||
const wordWidth = this.measureText(words[j]!, letterSpacing); | ||
const wordWidthWithSpace = | ||
wordWidth + this.measureText(' ', letterSpacing); | ||
if (wordBreak && wordWidthWithSpace > wordWrapWidth) { | ||
let remainder = ''; | ||
while (this.measureText(words[j]!) > wordWrapWidth) { | ||
remainder = words[j]!.slice(-1) + remainder; | ||
words[j] = words[j]!.slice(0, -1); | ||
} | ||
if (remainder.length > 0) { | ||
words.splice(j + 1, 0, remainder); | ||
} | ||
} | ||
if (j === 0 || wordWidthWithSpace > spaceLeft) { | ||
// Skip printing the newline if it's the first word of the line that is. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this is where you cut the word to fix within the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, but what remains is cut in next iteration of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ok it can work here There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. BTW I know that this project tends to use mostly visual regression tests, but this is a case where some unit tests would be greatly beneficial @wouterlucas There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
theres a vitest infrastructure as well, just add |
||
// greater than the word wrap width. | ||
|
@@ -720,7 +733,6 @@ export class LightningTextTextureRenderer { | |
realNewlines.push(allLines.length); | ||
} | ||
} | ||
|
||
return { l: allLines, n: realNewlines }; | ||
} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok that's kind of right and wrong - very interesting.
The good:
The bad:
Suggestion:
Performant approach:
wrapWord(word, wordWrapWidth, suffix)
method which has an optimized algorithm to cut a string at a max width. It will return the part that fits, from which you can figure the remainder and repeat until everything has fit.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point. I tried the wrapWord, but the line break points are a bit different between sdf and canvas.
I'll push the commit if this is ok.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm ok curious. Why is
sit
on the next line for SDF? And also why did it keep the space character when wrappingex magna
? Generally you want the wrapping logic to avoid wrapping one space to the next line.Aside from the the canvas wrapping looks alright, if the definition is to fit as many characters per line as possible.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I got stuck a little bit on this issue. To prevent
sit
from being carried to the next line additionalwrapWord=='normal'
condition is needed in line 213:Then to break at the correct point
charEndX + glyph.width >= lineVertexW
(line 299)should be changed to
charEndX + glyph.width + glyph.xOffset + 4 >= lineVertexW
The value of 4 was concluded experimentally and I'm not even sure why it is needed there. Here you can see the how breaking looks without it:
and with:
Finally - I have no idea about additional space before "ex".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
About
sit
, I guess we should either wrap or break works, no?Adding +4 isn't worth it - it's just the subtle differences in how text layout happens.
For the space before
ex
it's probably because when you cut the line, it cuts just at the space characters, so line starts with a space. We shouldn't carry over a space character to next line when we break, so probably we can remove a starting space character at the beginning of a wrapped line.