in src/wordBreaker.ts [130:188]
export function splitByWidth(
content: string,
properties: TextProperties,
textWidthMeasurer: ITextAsSVGMeasurer,
maxWidth: number,
maxNumLines: number,
truncator?: ITextTruncator): string[] {
// Default truncator returns string as-is
truncator = truncator ? truncator : (properties: TextProperties, maxWidth: number) => properties.text;
let result: string[] = [];
let words = split(content);
let usedWidth = 0;
let wordsInLine: string[] = [];
for (let word of words) {
// Last line? Just add whatever is left
if ((maxNumLines > 0) && (result.length >= maxNumLines - 1)) {
wordsInLine.push(word);
continue;
}
// Determine width if we add this word
// Account for SPACE we will add when joining...
let wordWidth = wordsInLine.length === 0
? getWidth(word, properties, textWidthMeasurer)
: getWidth(SPACE + word, properties, textWidthMeasurer);
// If width would exceed max width,
// then push used words and start new split result
if (usedWidth + wordWidth > maxWidth) {
// Word alone exceeds max width, just add it.
if (wordsInLine.length === 0) {
result.push(truncate(word, properties, truncator, maxWidth));
usedWidth = 0;
wordsInLine = [];
continue;
}
result.push(truncate(wordsInLine.join(SPACE), properties, truncator, maxWidth));
usedWidth = 0;
wordsInLine = [];
}
// ...otherwise, add word and continue
wordsInLine.push(word);
usedWidth += wordWidth;
}
// Push remaining words onto result (if any)
if (wordsInLine && wordsInLine.length) {
result.push(truncate(wordsInLine.join(SPACE), properties, truncator, maxWidth));
}
return result;
}