From 780def8cf90ca4bea821a4866a53d558786ad088 Mon Sep 17 00:00:00 2001 From: Zeke Chan Date: Tue, 3 Sep 2024 15:52:10 +0800 Subject: [PATCH] Fix #6860 BitmapText not wrapping lines in some cases --- .../bitmaptext/GetBitmapTextSize.js | 136 +++++++----------- 1 file changed, 52 insertions(+), 84 deletions(-) diff --git a/src/gameobjects/bitmaptext/GetBitmapTextSize.js b/src/gameobjects/bitmaptext/GetBitmapTextSize.js index aabf523c6..19889326b 100644 --- a/src/gameobjects/bitmaptext/GetBitmapTextSize.js +++ b/src/gameobjects/bitmaptext/GetBitmapTextSize.js @@ -99,108 +99,76 @@ var GetBitmapTextSize = function (src, round, updateOrigin, out) var currentLine = 0; var currentLineWidth = 0; - var i; + var i, j; var words = []; var characters = []; var current = null; + // Measure the width of the text + var measureTextWidth = function (text, fontData) + { + var width = 0; + for (var i = 0; i < text.length; i++) + { + var charCode = text.charCodeAt(i); + var glyph = fontData.chars[charCode]; + if (glyph) { + width += glyph.xAdvance; + } + } + return width * sx; + }; + // Scan for breach of maxWidth and insert carriage-returns if (maxWidth > 0) { - for (i = 0; i < textLength; i++) + // Split the text into lines + var lines = text.split('\n'); + var wrappedLines = []; + + // Loop through each line + for (i = 0; i < lines.length; i++) { - charCode = text.charCodeAt(i); + var line = lines[i]; + var word = ''; + var wrappedLine = ''; + var lineToCheck = ''; + var lineWithWord = ''; - if (charCode === 10) + // Loop through each character in a line + for (j = 0; j < line.length; j++) { - if (current !== null) + charCode = line.charCodeAt(j); + + word += line[j]; + + // White space or end of line? + if (charCode === wordWrapCharCode || j === line.length - 1) { - words.push({ - word: current.word, - i: current.i, - x: current.x * sx, - y: current.y * sy, - w: current.w * sx, - h: current.h * sy, - cr: true - }); + lineWithWord = lineToCheck + word; + + var textWidth = measureTextWidth(lineWithWord, src.fontData); - current = null; - } + if (textWidth <= maxWidth) + { + lineToCheck = lineWithWord; + } + else + { + // If the current word is too long to fit on a line, wrap it + wrappedLine += (wrappedLine ? '\n' : '') + lineToCheck; + lineToCheck = word; + } - xAdvance = 0; - yAdvance += lineHeight + lineSpacing; - - lastGlyph = null; - - continue; - } - - glyph = chars[charCode]; - - if (!glyph) - { - continue; - } - - if (lastGlyph !== null) - { - var glyphKerningOffset = glyph.kerning[lastCharCode]; - } - - if (charCode === wordWrapCharCode) - { - if (current !== null) - { - words.push({ - word: current.word, - i: current.i, - x: current.x * sx, - y: current.y * sy, - w: current.w * sx, - h: current.h * sy, - cr: false - }); - - current = null; + word = ''; } } - else - { - if (current === null) - { - // We're starting a new word, recording the starting index, etc - current = { word: '', i: i, x: xAdvance, y: yAdvance, w: 0, h: lineHeight, cr: false }; - } - current.word = current.word.concat(text[i]); - current.w += glyph.xOffset + glyph.xAdvance + ((glyphKerningOffset !== undefined) ? glyphKerningOffset : 0); - } - - xAdvance += glyph.xAdvance + letterSpacing; - lastGlyph = glyph; - lastCharCode = charCode; + wrappedLine += (wrappedLine ? '\n' : '') + lineToCheck; + wrappedLines.push(wrappedLine); } - // Last word - if (current !== null) - { - words.push({ - word: current.word, - i: current.i, - x: current.x * sx, - y: current.y * sy, - w: current.w * sx, - h: current.h * sy, - cr: false - }); - } - - // Reset for the next loop - xAdvance = 0; - yAdvance = 0; - lastGlyph = null; - lastCharCode = 0; + text = wrappedLines.join('\n'); // Loop through the words array and see if we've got any > maxWidth var prev;