pixi.js
Version:
<p align="center"> <a href="https://pixijs.com" target="_blank" rel="noopener noreferrer"> <img height="150" src="https://files.pixijs.download/branding/pixijs-logo-transparent-dark.svg?v=1" alt="PixiJS logo"> </a> </p> <br/> <p align="center">
1 lines • 18.4 kB
Source Map (JSON)
{"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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"}