"use strict"; function getBitmapTextLayout(chars, style, font, trimEnd) { const layoutData = { width: 0, height: 0, offsetY: 0, scale: style.fontSize / font.baseMeasurementFontSize, lines: [{ width: 0, charPositions: [], spaceWidth: 0, spacesIndex: [], chars: [] }] }; layoutData.offsetY = font.baseLineOffset; let currentLine = layoutData.lines[0]; let previousChar = null; let firstWord = true; const currentWord = { spaceWord: false, width: 0, start: 0, index: 0, // use index to not modify the array as we use it a lot! positions: [], chars: [] }; const nextWord = (word) => { const start = currentLine.width; for (let j = 0; j < currentWord.index; j++) { const position = word.positions[j]; currentLine.chars.push(word.chars[j]); currentLine.charPositions.push(position + start); } currentLine.width += word.width; firstWord = false; currentWord.width = 0; currentWord.index = 0; currentWord.chars.length = 0; }; const nextLine = () => { let index = currentLine.chars.length - 1; if (trimEnd) { let lastChar = currentLine.chars[index]; while (lastChar === " ") { currentLine.width -= font.chars[lastChar].xAdvance; lastChar = currentLine.chars[--index]; } } layoutData.width = Math.max(layoutData.width, currentLine.width); currentLine = { width: 0, charPositions: [], chars: [], spaceWidth: 0, spacesIndex: [] }; firstWord = true; layoutData.lines.push(currentLine); layoutData.height += font.lineHeight; }; const scale = font.baseMeasurementFontSize / style.fontSize; const adjustedLetterSpacing = style.letterSpacing * scale; const adjustedWordWrapWidth = style.wordWrapWidth * scale; for (let i = 0; i < chars.length + 1; i++) { let char; const isEnd = i === chars.length; if (!isEnd) { char = chars[i]; } const charData = font.chars[char] || font.chars[" "]; const isSpace = /(?:\s)/.test(char); const isWordBreak = isSpace || char === "\r" || char === "\n" || isEnd; if (isWordBreak) { const addWordToNextLine = !firstWord && style.wordWrap && currentLine.width + currentWord.width - adjustedLetterSpacing > adjustedWordWrapWidth; if (addWordToNextLine) { nextLine(); nextWord(currentWord); if (!isEnd) { currentLine.charPositions.push(0); } } else { currentWord.start = currentLine.width; nextWord(currentWord); if (!isEnd) { currentLine.charPositions.push(0); } } if (char === "\r" || char === "\n") { if (currentLine.width !== 0) { nextLine(); } } else if (!isEnd) { const spaceWidth = charData.xAdvance + (charData.kerning[previousChar] || 0) + adjustedLetterSpacing; currentLine.width += spaceWidth; currentLine.spaceWidth = spaceWidth; currentLine.spacesIndex.push(currentLine.charPositions.length); currentLine.chars.push(char); } } else { const kerning = charData.kerning[previousChar] || 0; const nextCharWidth = charData.xAdvance + kerning + adjustedLetterSpacing; currentWord.positions[currentWord.index++] = currentWord.width + kerning; currentWord.chars.push(char); currentWord.width += nextCharWidth; } previousChar = char; } nextLine(); if (style.align === "center") { alignCenter(layoutData); } else if (style.align === "right") { alignRight(layoutData); } else if (style.align === "justify") { alignJustify(layoutData); } return layoutData; } function alignCenter(measurementData) { for (let i = 0; i < measurementData.lines.length; i++) { const line = measurementData.lines[i]; const offset = measurementData.width / 2 - line.width / 2; for (let j = 0; j < line.charPositions.length; j++) { line.charPositions[j] += offset; } } } function alignRight(measurementData) { for (let i = 0; i < measurementData.lines.length; i++) { const line = measurementData.lines[i]; const offset = measurementData.width - line.width; for (let j = 0; j < line.charPositions.length; j++) { line.charPositions[j] += offset; } } } function alignJustify(measurementData) { const width = measurementData.width; for (let i = 0; i < measurementData.lines.length; i++) { const line = measurementData.lines[i]; let indy = 0; let spaceIndex = line.spacesIndex[indy++]; let offset = 0; const totalSpaces = line.spacesIndex.length; const newSpaceWidth = (width - line.width) / totalSpaces; const spaceWidth = newSpaceWidth; for (let j = 0; j < line.charPositions.length; j++) { if (j === spaceIndex) { spaceIndex = line.spacesIndex[indy++]; offset += spaceWidth; } line.charPositions[j] += offset; } } } export { getBitmapTextLayout }; //# sourceMappingURL=getBitmapTextLayout.mjs.map