diff --git a/src/battle/BattleState.lua b/src/battle/BattleState.lua index 0b61ea3c..81a7a1f9 100644 --- a/src/battle/BattleState.lua +++ b/src/battle/BattleState.lua @@ -6964,8 +6964,12 @@ function BattleState:drawTextArea() local ys = { 112, 128 } for li, line in ipairs(self.shown or {}) do local y = (ys[li] or 128) + off + -- pen by each glyph's own advance, like TextBox: a TTF font is not on + -- the 8px tile grid + local pen = 8 for i = 1, #line do - drawGlyph(line[i], 8 + (i - 1) * 8, y) + drawGlyph(line[i], pen, y) + pen = pen + Font.advanceOf(line[i]) end end -- the blinking down arrow ('▼', glyph $EE) while a \v CONT wait diff --git a/src/battle/WideBattle.lua b/src/battle/WideBattle.lua index 14332147..323fe8e9 100644 --- a/src/battle/WideBattle.lua +++ b/src/battle/WideBattle.lua @@ -189,8 +189,11 @@ local function drawMessageBox(battle) local ys = { 112, 128 } for li, line in ipairs(battle.shown or {}) do local y = (ys[li] or 128) + off + -- same pen as BattleState:drawTextArea: per-glyph advance, not 8px cells + local pen = 8 for i = 1, #line do - Font.drawCode(line[i], 8 + (i - 1) * 8, y) + Font.drawCode(line[i], pen, y) + pen = pen + Font.advanceOf(line[i]) end end if (battle.msgWaiting or battle.msgPrompt) and battle.frame % 60 < 30 then diff --git a/tests/engine/ttf_font_mode.lua b/tests/engine/ttf_font_mode.lua index 351f9a89..f4c9427c 100644 --- a/tests/engine/ttf_font_mode.lua +++ b/tests/engine/ttf_font_mode.lua @@ -208,6 +208,44 @@ do T.eq(pens[3].x, 8 + latin * 2, "the ligature tile sits after the TTF pair") end +-- ------------------------------------------------- so does the battle box + +-- the battle message box keeps its own draw loop (classic and wide layout); +-- both have to move the pen the way TextBox does, or a TTF line is spread +-- over the 8px grid and clipped at the box edge +do + local BattleState = require("src.battle.BattleState") + local WideBattle = require("src.battle.WideBattle") + local function battle() + return setmetatable({ + phase = "messages", current = {}, frame = 0, fieldCleared = true, + shown = { Font.encode("AB'd") }, + bottomUIVisible = function() return true end, + extendedHUD = function() return false end, + drawPicsLayer = function() end, + }, BattleState) + end + local function pensOf(draw) + local pens = {} + local oldDraw = Font.drawCode + Font.drawCode = function(code, x) + if code >= BASE or code == 0xD0 then pens[#pens + 1] = x end + end + local ok, err = pcall(draw) + Font.drawCode = oldDraw + if not ok then error(err, 0) end + return pens + end + local classic = pensOf(function() battle():drawTextArea() end) + T.eq(#classic, 3, "the battle box draws three glyphs for AB'd") + T.eq(classic[2], 8 + latin, "its pen moves by the TTF advance, not 8px") + T.eq(classic[3], 8 + latin * 2, "and the ligature tile follows the pair") + local wide = pensOf(function() WideBattle.draw(battle()) end) + T.eq(#wide, 3, "the wide battle box draws the same three glyphs") + T.eq(wide[2], 8 + latin, "with the same per-glyph pen") + T.eq(wide[3], 8 + latin * 2, "up to the ligature tile") +end + -- ------------------------------------------------- the registry entry do