Spaces:
Sleeping
Sleeping
| import { BmFont } from "./types.js"; | |
| export function measureText(font: BmFont, text: string) { | |
| let x = 0; | |
| for (let i = 0; i < text.length; i++) { | |
| const char = text[i]!; | |
| const fontChar = font.chars[char]; | |
| if (fontChar) { | |
| const fontKerning = font.kernings[char]; | |
| const nextChar = text[i + 1]; | |
| const kerning = | |
| fontKerning && nextChar && fontKerning[nextChar] | |
| ? fontKerning[nextChar] || 0 | |
| : 0; | |
| x += (fontChar.xadvance || 0) + kerning; | |
| } | |
| } | |
| return x; | |
| } | |
| export function splitLines(font: BmFont, text: string, maxWidth: number) { | |
| const words = text.replace(/[\r\n]+/g, " \n").split(" "); | |
| const lines: string[][] = []; | |
| let currentLine: string[] = []; | |
| let longestLine = 0; | |
| words.forEach((word) => { | |
| const wordWidth = measureText(font, word + (words.length > 1 ? " " : "")); | |
| // If a word is longer than the allowable width we need to split it across lines. | |
| if (wordWidth > maxWidth) { | |
| const characterIterator = word[Symbol.iterator](); | |
| let current = ""; | |
| for (const char of characterIterator) { | |
| const nextLine = [...currentLine, current + char].join(" "); | |
| const length = measureText(font, nextLine); | |
| if (length < maxWidth) { | |
| current += char; | |
| } else if (length > maxWidth) { | |
| lines.push([...currentLine, current]); | |
| currentLine = []; | |
| current = char; | |
| } else { | |
| lines.push([...currentLine, current + char]); | |
| currentLine = []; | |
| current = ""; | |
| } | |
| } | |
| return; | |
| } | |
| const line = [...currentLine, word].join(" "); | |
| const length = measureText(font, line); | |
| if (length <= maxWidth && !word.includes("\n")) { | |
| if (length > longestLine) { | |
| longestLine = length; | |
| } | |
| currentLine.push(word); | |
| } else { | |
| lines.push(currentLine); | |
| currentLine = [word.replace("\n", "")]; | |
| } | |
| }); | |
| lines.push(currentLine); | |
| return { | |
| lines, | |
| longestLine, | |
| }; | |
| } | |
| export function measureTextHeight( | |
| font: BmFont, | |
| text: string, | |
| maxWidth: number, | |
| ) { | |
| const { lines } = splitLines(font, text, maxWidth); | |
| return lines.length * font.common.lineHeight; | |
| } | |