From 7ed63a6b071cf2227973aac99e2ca81b9c6a200a Mon Sep 17 00:00:00 2001 From: George Kurelic Date: Fri, 19 Apr 2024 11:29:40 -0500 Subject: [PATCH] Fix wrap without reverting kerning (#3120) * Revert "Add kerning to bitmap fonts created from BMFont files (#3035)" This reverts commit 41a51c3af9be480ec55a0e0c68d9db1bdaa589ed. * re-add kerning to font * fix bitmap text * addGetRenderedText * add FlxBitmapTextField getRenderedText * doc --- flixel/graphics/frames/FlxBitmapFont.hx | 2 +- flixel/text/FlxBitmapText.hx | 67 +++++++++++++------ .../unit/src/flixel/text/FlxBitmapTextTest.hx | 56 +++++++++++++++- 3 files changed, 103 insertions(+), 22 deletions(-) diff --git a/flixel/graphics/frames/FlxBitmapFont.hx b/flixel/graphics/frames/FlxBitmapFont.hx index b9874e735e..ed06a3b71a 100644 --- a/flixel/graphics/frames/FlxBitmapFont.hx +++ b/flixel/graphics/frames/FlxBitmapFont.hx @@ -568,4 +568,4 @@ class FlxBitmapFont extends FlxFramesCollection font.updateSourceHeight(); return font; } -} +} \ No newline at end of file diff --git a/flixel/text/FlxBitmapText.hx b/flixel/text/FlxBitmapText.hx index 5fa4c7f949..b4b8aa86f1 100644 --- a/flixel/text/FlxBitmapText.hx +++ b/flixel/text/FlxBitmapText.hx @@ -596,11 +596,11 @@ class FlxBitmapText extends FlxSprite { if (wrap != NONE) { - autoWrap(); + _lines = autoWrap(_lines); } else { - cutLines(); + _lines = cutLines(_lines); } } @@ -712,29 +712,34 @@ class FlxBitmapText extends FlxSprite /** * Just cuts the lines which are too long to fit in the field. */ - function cutLines():Void + function cutLines(lines:Array) { - for (i in 0..._lines.length) + for (i in 0...lines.length) { + final line = lines[i]; var lineWidth = font.minOffsetX; var prevCode = -1; - for (c in 0..._lines[i].length) + for (c in 0...line.length) { - final charCode = _lines[i].charCodeAt(c); + // final char = line.charAt(c); + final charCode = line.charCodeAt(c); if (prevCode == -1) - lineWidth += getCharAdvance(charCode, font.spaceWidth); + { + lineWidth += getCharAdvance(charCode, font.spaceWidth) + letterSpacing; + } else - lineWidth += getCharPairAdvance(prevCode, charCode, font.spaceWidth); + lineWidth += getCharPairAdvance(prevCode, charCode, font.spaceWidth) + letterSpacing; if (lineWidth > _fieldWidth - 2 * padding) { // cut every character after this - _lines[i] = _lines[i].substr(0, c); + lines[i] = lines[i].substr(0, c); break; } } } + return lines; } function getCharAdvance(charCode:Int, spaceWidth:Int) @@ -742,11 +747,11 @@ class FlxBitmapText extends FlxSprite switch (charCode) { case FlxBitmapFont.SPACE_CODE: - return spaceWidth + letterSpacing; + return spaceWidth; case FlxBitmapFont.TAB_CODE: - return spaceWidth * numSpacesInTab + letterSpacing; + return spaceWidth * numSpacesInTab; case charCode: - final advance = font.getCharAdvance(charCode) + letterSpacing; + final advance = font.getCharAdvance(charCode); if (isUnicodeComboMark(charCode)) return -advance; return advance; @@ -757,18 +762,38 @@ class FlxBitmapText extends FlxSprite { return getCharAdvance(prevCode, spaceWidth) + font.getKerning(prevCode, nextCode); } - + + /** + * Adds soft wraps to the text and cuts lines based on how it would be displayed in this field, + * Also converts to upper-case, if `autoUpperCase` is `true` + */ + public function getRenderedText(text:UnicodeString) + { + text = (autoUpperCase) ? (text : UnicodeString).toUpperCase() : text; + + if (!autoSize) + { + var lines = text.split("\n"); + if (wrap != NONE) + return autoWrap(lines).join("\n"); + + return cutLines(lines).join("\n"); + } + + return text; + } + /** * Automatically wraps text by figuring out how many characters can fit on a * single line, and splitting the remainder onto a new line. */ - function autoWrap():Void + function autoWrap(lines:Array) { // subdivide lines var newLines:Array = []; var words:Array; // the array of words in the current line - for (line in _lines) + for (line in lines) { words = []; // split this line into words @@ -785,7 +810,7 @@ class FlxBitmapText extends FlxSprite } } - _lines = newLines; + return newLines; } /** @@ -1013,7 +1038,7 @@ class FlxBitmapText extends FlxSprite { var wordWidth = 0; for (c in 0...word.length) - getCharAdvance(word.charCodeAt(c), font.spaceWidth); + wordWidth += getCharAdvance(word.charCodeAt(c), font.spaceWidth); return wordWidth + (word.length - 1) * letterSpacing; } @@ -1155,7 +1180,7 @@ class FlxBitmapText extends FlxSprite var curX:Float = startX; var curY:Int = startY; - + final lineLength:Int = line.length; final textWidth:Int = this.textWidth; @@ -1187,10 +1212,12 @@ class FlxBitmapText extends FlxSprite if (i + 1 < lineLength) { final nextCode = line.charCodeAt(i + 1); - curX += getCharPairAdvance(charCode, nextCode, spaceWidth); + curX += getCharPairAdvance(charCode, nextCode, spaceWidth) + letterSpacing; } else - curX += getCharAdvance(charCode, spaceWidth); + { + curX += getCharAdvance(charCode, spaceWidth) + letterSpacing; + } } } } diff --git a/tests/unit/src/flixel/text/FlxBitmapTextTest.hx b/tests/unit/src/flixel/text/FlxBitmapTextTest.hx index b5a2d9abbc..36ba70be36 100644 --- a/tests/unit/src/flixel/text/FlxBitmapTextTest.hx +++ b/tests/unit/src/flixel/text/FlxBitmapTextTest.hx @@ -1,8 +1,10 @@ package flixel.text; -import flixel.text.FlxBitmapText; import flixel.graphics.frames.FlxBitmapFont; +import flixel.math.FlxPoint; +import flixel.text.FlxBitmapText; import massive.munit.Assert; +import openfl.display.BitmapData; class FlxBitmapTextTest extends FlxTest { @@ -29,4 +31,56 @@ class FlxBitmapTextTest extends FlxTest Assert.isNotNull(text1.text); Assert.areEqual(text1.font, text2.font); } + + @Test + function testWrapMono() + { + final image = new BitmapData(112, 60); + final monospaceLetters:String = " !\"#$%&'()*+,-.\\0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[/]^_`abcdefghijklmnopqrstuvwxyz{|}~"; + final charSize = FlxPoint.get(7, 10); + final font = FlxBitmapFont.fromMonospace(image, monospaceLetters, charSize); + + final field = new FlxBitmapText(0, 0, "", font); + field.autoSize = false; + field.fieldWidth = 100; + field.letterSpacing = -1; + field.multiLine = true; + + /* + Note: These tests were made quickly due to my current schedule, later on we may want + to simplify these, and also add tests for: kerning and unicode stuff + */ + + final msg = "The quick brown fox jumps over the lazy dog, "; + final msg1 = msg + "supercal-aphragalist-icexpiala-docious"; // long hyphenate4d word + final msg2 = msg + "supercal-aphragalist\nicexpiala-docious"; // hard wrap and hyphens + final msg3 = msg + "supercalaphragalisticexpialadocious"; // one long word + + assertRenderedText(field, msg1, NONE, "The quick brown "); + assertRenderedText(field, msg2, NONE, "The quick brown \nicexpiala-dociou"); + assertRenderedText(field, msg3, NONE, "The quick brown "); + + assertRenderedText(field, msg1, CHAR, "The quick brown \nfox jumps over t\nhe lazy dog, sup\nercal-aphragalis\nt-icexpiala-doci\nous"); + assertRenderedText(field, msg2, CHAR, "The quick brown \nfox jumps over t\nhe lazy dog, sup\nercal-aphragalis\nt\nicexpiala-dociou\ns"); + assertRenderedText(field, msg3, CHAR, "The quick brown \nfox jumps over t\nhe lazy dog, sup\nercalaphragalist\nicexpialadocious"); + + assertRenderedText(field, msg1, WORD(NEVER), "The quick brown \nfox jumps over \nthe lazy dog, \nsupercal-\naphragalist-\nicexpiala-\ndocious"); + assertRenderedText(field, msg2, WORD(NEVER), "The quick brown \nfox jumps over \nthe lazy dog, \nsupercal-\naphragalist\nicexpiala-\ndocious"); + assertRenderedText(field, msg3, WORD(NEVER), "The quick brown \nfox jumps over \nthe lazy dog, \nsupercalaphragalisticexpialadocious"); + + assertRenderedText(field, msg1, WORD(LINE_WIDTH), "The quick brown \nfox jumps over \nthe lazy dog, \nsupercal-\naphragalist-\nicexpiala-\ndocious"); + assertRenderedText(field, msg2, WORD(LINE_WIDTH), "The quick brown \nfox jumps over \nthe lazy dog, \nsupercal-\naphragalist\nicexpiala-\ndocious"); + assertRenderedText(field, msg3, WORD(LINE_WIDTH), "The quick brown \nfox jumps over \nthe lazy dog, su\npercalaphragalis\nticexpialadociou\ns"); + + assertRenderedText(field, msg1, WORD(LENGTH(10)), "The quick brown \nfox jumps over \nthe lazy dog, \nsupercal-aphraga\nlist-icexpiala-\ndocious"); + assertRenderedText(field, msg2, WORD(LENGTH(10)), "The quick brown \nfox jumps over \nthe lazy dog, \nsupercal-aphraga\nlist\nicexpiala-\ndocious"); + assertRenderedText(field, msg3, WORD(LENGTH(10)), "The quick brown \nfox jumps over \nthe lazy dog, su\npercalaphragalis\nticexpialadociou\ns"); + } + + function assertRenderedText(field:FlxBitmapText, text:UnicodeString, wrap:FlxBitmapText.Wrap, expected:UnicodeString, ?info:haxe.PosInfos) + { + field.wrap = wrap; + final actual = field.getRenderedText(text); + Assert.areEqual(expected, actual, info); + } }