{"version":3,"file":"getBitmapTextLayout.mjs","sources":["../../../../src/scene/text-bitmap/utils/getBitmapTextLayout.ts"],"sourcesContent":["import {\n    collapseNewlines,\n    collapseSpaces,\n    isBreakAfterChar,\n    isBreakingSpace,\n    isCollapsibleSpace,\n} from '../../text/canvas/utils/textTokenization';\n\nimport type { TextStyle } from '../../text/TextStyle';\nimport type { AbstractBitmapFont } from '../AbstractBitmapFont';\n\n/**\n * The layout data for a bitmap text.\n * This contains the width, height, scale, offsetY and lines of text.\n * Each line contains its width, character positions, characters, space width and spaces index.\n * @category text\n * @internal\n */\nexport interface BitmapTextLayoutData\n{\n    width: number;\n    height: number;\n    scale: number;\n    offsetY: number;\n    lines: {\n        width: number\n        charPositions: number[],\n        chars: string[],\n        // / spaces: number\n        spaceWidth: number\n        spacesIndex: number[]\n    }[];\n}\n\n/**\n * @param chars\n * @param style\n * @param font\n * @param trimEnd\n * @internal\n */\nexport function getBitmapTextLayout(\n    chars: string[],\n    style: TextStyle,\n    font: AbstractBitmapFont<any>,\n    trimEnd: boolean\n): BitmapTextLayoutData\n{\n    const layoutData: BitmapTextLayoutData = {\n        width: 0,\n        height: 0,\n        offsetY: 0,\n        scale: style.fontSize / font.baseMeasurementFontSize,\n        lines: [{\n            width: 0,\n            charPositions: [] as number[],\n            spaceWidth: 0,\n            spacesIndex: [],\n            chars: [],\n        }]\n    };\n\n    layoutData.offsetY = font.baseLineOffset;\n\n    let currentLine = layoutData.lines[0];\n\n    let previousChar: string = null;\n    let firstWord = true;\n    //    let spaceCount = 0;\n\n    const currentWord = {\n        spaceWord: false,\n        width: 0,\n        start: 0,\n        index: 0, // use index to not modify the array as we use it a lot!\n        positions: [] as number[],\n        chars: [] as string[],\n    };\n\n    const scale = font.baseMeasurementFontSize / style.fontSize;\n\n    const adjustedLetterSpacing = style.letterSpacing * scale;\n    const adjustedWordWrapWidth = style.wordWrapWidth * scale;\n    const adjustedLineHeight = style.lineHeight ? style.lineHeight * scale : font.lineHeight;\n\n    const breakWords = style.wordWrap && style.breakWords;\n\n    const shouldCollapseSpaces = collapseSpaces(style.whiteSpace);\n    const shouldCollapseNewlines = collapseNewlines(style.whiteSpace);\n\n    if (shouldCollapseSpaces || shouldCollapseNewlines)\n    {\n        const processed: string[] = [];\n        let prevWasBreakingSpace = shouldCollapseSpaces;\n\n        for (let c = 0; c < chars.length; c++)\n        {\n            let char = chars[c];\n\n            if (char === '\\r' || char === '\\n')\n            {\n                if (shouldCollapseNewlines)\n                {\n                    if (char === '\\r' && chars[c + 1] === '\\n') c++;\n                    char = ' ';\n                }\n                else\n                {\n                    if (shouldCollapseSpaces) prevWasBreakingSpace = true;\n                    processed.push(char);\n                    continue;\n                }\n            }\n\n            if (isBreakingSpace(char))\n            {\n                if (shouldCollapseSpaces && isCollapsibleSpace(char))\n                {\n                    if (prevWasBreakingSpace) continue;\n                    prevWasBreakingSpace = true;\n                    processed.push(' ');\n                }\n                else\n                {\n                    prevWasBreakingSpace = false;\n                    processed.push(char);\n                }\n            }\n            else\n            {\n                prevWasBreakingSpace = false;\n                processed.push(char);\n            }\n        }\n\n        chars = processed;\n    }\n\n    const nextWord = (word: typeof currentWord) =>\n    {\n        const start = currentLine.width;\n\n        for (let j = 0; j < currentWord.index; j++)\n        {\n            const position = word.positions[j];\n\n            currentLine.chars.push(word.chars[j]);\n            currentLine.charPositions.push(position + start);\n        }\n\n        currentLine.width += word.width;\n\n        if (currentWord.index > 0 || !shouldCollapseSpaces)\n        {\n            firstWord = false;\n        }\n\n        // reset the word..\n        currentWord.width = 0;\n        currentWord.index = 0;\n        currentWord.chars.length = 0;\n\n        // spaceCount = 0;\n    };\n\n    const nextLine = () =>\n    {\n        let index = currentLine.chars.length - 1;\n\n        if (trimEnd)\n        {\n            let lastChar = currentLine.chars[index];\n\n            while (isCollapsibleSpace(lastChar))\n            {\n                currentLine.width -= font.chars[lastChar].xAdvance;\n                currentLine.spacesIndex.pop();\n                lastChar = currentLine.chars[--index];\n            }\n        }\n\n        layoutData.width = Math.max(layoutData.width, currentLine.width);\n\n        currentLine = {\n            width: 0,\n            charPositions: [],\n            chars: [],\n            spaceWidth: 0,\n            spacesIndex: [],\n        };\n\n        firstWord = true;\n        layoutData.lines.push(currentLine);\n        layoutData.height += adjustedLineHeight;\n    };\n\n    const checkIsOverflow = (lineWidth: number) =>\n        lineWidth - adjustedLetterSpacing > adjustedWordWrapWidth;\n\n    // loop an extra time to force a line break..\n    for (let i = 0; i < chars.length + 1; i++)\n    {\n        let char: string;\n\n        const isEnd = i === chars.length;\n\n        if (!isEnd)\n        {\n            char = chars[i];\n        }\n\n        const charData = font.chars[char];\n\n        const isSpace = (/(?:\\s)/).test(char);\n        const isWordBreak = isSpace || char === '\\r' || char === '\\n' || isEnd;\n\n        // spaceCount++;\n        // wasSpace = isSpace;\n\n        if (isWordBreak)\n        {\n            const addWordToNextLine = !firstWord && style.wordWrap && checkIsOverflow(currentLine.width + currentWord.width);\n\n            if (addWordToNextLine)\n            {\n                nextLine();\n\n                nextWord(currentWord);\n\n                if (!isEnd)\n                {\n                    currentLine.charPositions.push(0);\n                }\n            }\n            else\n            {\n                currentWord.start = currentLine.width;\n\n                nextWord(currentWord);\n\n                if (!isEnd)\n                {\n                    currentLine.charPositions.push(0);\n                }\n            }\n\n            if (char === '\\r' || char === '\\n')\n            {\n                nextLine();\n            }\n            else if (!isEnd && charData)\n            {\n                const spaceWidth = charData.xAdvance + (charData.kerning?.[previousChar] || 0) + adjustedLetterSpacing;\n\n                currentLine.width += spaceWidth;\n\n                currentLine.spaceWidth = spaceWidth;\n                currentLine.spacesIndex.push(currentLine.charPositions.length);\n                currentLine.chars.push(char);\n            }\n        }\n        else if (charData)\n        {\n            const kerning = charData.kerning?.[previousChar] || 0;\n\n            const nextCharWidth = charData.xAdvance + kerning + adjustedLetterSpacing;\n\n            const wordExceedsWrapWidth = breakWords && checkIsOverflow(currentWord.width + nextCharWidth);\n\n            if (wordExceedsWrapWidth)\n            {\n                if (!firstWord)\n                {\n                    nextLine();\n                }\n\n                nextWord(currentWord);\n                nextLine();\n            }\n\n            currentWord.positions[currentWord.index++] = currentWord.width + kerning;\n            currentWord.chars.push(char);\n\n            currentWord.width += nextCharWidth;\n\n            if (isBreakAfterChar(char))\n            {\n                const addWordToNextLine = !firstWord && style.wordWrap\n                    && checkIsOverflow(currentLine.width + currentWord.width);\n\n                if (addWordToNextLine)\n                {\n                    nextLine();\n                }\n\n                nextWord(currentWord);\n            }\n        }\n\n        previousChar = char;\n        // lastChar = char;\n    }\n\n    nextLine();\n\n    if (style.wordWrap && style.align !== 'left')\n    {\n        layoutData.width = Math.max(layoutData.width, adjustedWordWrapWidth);\n    }\n\n    if (style.align === 'center')\n    {\n        alignCenter(layoutData);\n    }\n    else if (style.align === 'right')\n    {\n        alignRight(layoutData);\n    }\n    else if (style.align === 'justify')\n    {\n        alignJustify(layoutData);\n    }\n\n    return layoutData;\n}\n\nfunction alignCenter(measurementData: BitmapTextLayoutData)\n{\n    for (let i = 0; i < measurementData.lines.length; i++)\n    {\n        const line = measurementData.lines[i];\n        const offset = ((measurementData.width / 2) - (line.width / 2));\n\n        for (let j = 0; j < line.charPositions.length; j++)\n        {\n            line.charPositions[j] += offset;\n        }\n    }\n}\n\nfunction alignRight(measurementData: BitmapTextLayoutData)\n{\n    for (let i = 0; i < measurementData.lines.length; i++)\n    {\n        const line = measurementData.lines[i];\n        const offset = ((measurementData.width) - (line.width));\n\n        for (let j = 0; j < line.charPositions.length; j++)\n        {\n            line.charPositions[j] += offset;\n        }\n    }\n}\n\nfunction alignJustify(measurementData: BitmapTextLayoutData)\n{\n    const width = measurementData.width;\n\n    // Skip last content line (CSS justify behavior); -2 accounts for trailing empty line\n    for (let i = 0; i < measurementData.lines.length - 2; i++)\n    {\n        const line = measurementData.lines[i];\n\n        let indy = 0;\n        let spaceIndex = line.spacesIndex[indy++];\n\n        let offset = 0;\n\n        const totalSpaces = line.spacesIndex.length;\n\n        const newSpaceWidth = (width - line.width) / totalSpaces;\n\n        const spaceWidth = newSpaceWidth;\n\n        for (let j = 0; j < line.charPositions.length; j++)\n        {\n            if (j === spaceIndex)\n            {\n                spaceIndex = line.spacesIndex[indy++];\n\n                offset += spaceWidth;\n            }\n\n            line.charPositions[j] += offset;\n        }\n    }\n}\n"],"names":[],"mappings":"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"}