Merge pull request #1042 from thibautbus/fix/android-ttf-dpi

Fix custom TTF rendering on Android
This commit is contained in:
bryanthaboi
2026-08-10 14:09:07 -04:00
committed by GitHub
2 changed files with 25 additions and 2 deletions
+4 -2
View File
@@ -137,8 +137,10 @@ function Font.load(data)
-- typo'd path degrades exactly like a missing page image does above. -- typo'd path degrades exactly like a missing page image does above.
if type(def.ttf) == "table" then if type(def.ttf) == "table" then
local file = def.ttf.file or Font.PLAINPIXEL local file = def.ttf.file or Font.PLAINPIXEL
local ok, obj = pcall(love.graphics.newFont, file, local size = def.ttf.size or Font.PLAINPIXEL_SIZE
def.ttf.size or Font.PLAINPIXEL_SIZE, "mono") -- The game renders into a pixel-exact canvas, so keep the TTF rasterizer
-- on that same 1x grid instead of inheriting the window DPI on mobile.
local ok, obj = pcall(love.graphics.newFont, file, size, "mono", 1)
if ok and obj then if ok and obj then
-- nearest keeps the pixel font crisp under the integer UI scale -- nearest keeps the pixel font crisp under the integer UI scale
if obj.setFilter then pcall(obj.setFilter, obj, "nearest", "nearest") end if obj.setFilter then pcall(obj.setFilter, obj, "nearest", "nearest") end
+21
View File
@@ -40,6 +40,27 @@ T.eq(Font.advanceOf(0x80), 8, "and the pen stays 8px monospace")
-- ------------------------------------------------- the ttf takes over -- ------------------------------------------------- the ttf takes over
-- Font rasterizers must use the same 1x pixel grid as PixelCanvas, rather
-- than inheriting Android's window density. Keep this local fake so the
-- contract is testable without requiring a real LÖVE window.
do
local g, oldNewFont = love.graphics, love.graphics.newFont
local args
g.newFont = function(...)
args = { ... }
return oldNewFont(Font.PLAINPIXEL, Font.PLAINPIXEL_SIZE)
end
local loaded, err = pcall(Font.load, {
font = { charmap = CHARMAP, ttf = { file = "custom.ttf", size = 13 } },
})
g.newFont = oldNewFont
if not loaded then error(err, 0) end
T.eq(args[1], "custom.ttf", "rasterizer uses the configured file")
T.eq(args[2], 13, "rasterizer uses the configured size")
T.eq(args[3], "mono", "rasterizer keeps the pixel hinting mode")
T.eq(args[4], 1, "rasterizer stays on the pixel canvas scale")
end
Font.load({ font = { charmap = CHARMAP, ttf = {} } }) Font.load({ font = { charmap = CHARMAP, ttf = {} } })
T.check(Font.ttfActive(), "an empty ttf table loads the bundled font") T.check(Font.ttfActive(), "an empty ttf table loads the bundled font")