How I scale text

I needed to scale up my font here:

to be 2x size, and wanted a easy to call function to do it, like so:

DrawText('Which elf are you?', Cx, Cy - 40, 'center', 2)

This is how I laid things out in my utils.lua file:

--- top of code
Gfx = playdate.graphics
Font = Gfx.font.new('fonts/robkohr-mono-5x8')
Gfx.setFont(Font)

-- down in util functions
DrawScaledTextImageCache = {}
DrawScaledTextImageCacheById = {}
-- Use id for something that has frequently changing content so not to fill memory
function DrawScaledText(text, x, y, alignment, scale, id)
    local key = text .. alignment .. scale
    local image = nil
    if (id and DrawScaledTextImageCacheById[id] and DrawScaledTextImageCacheById[id][key]) then
        image = DrawScaledTextImageCacheById[id][key]
    end
    if (image == nil and DrawScaledTextImageCache[key]) then
        image = DrawScaledTextImageCache[key]
    end
    if (image == nil) then
        local _, lineCount = string.gsub(text, "\n", "")
        lineCount = lineCount + 1
        local width = Font:getTextWidth(text) * scale;
        local height = Font:getHeight() * lineCount * scale;
        image = playdate.graphics.image.new(width, height);
        playdate.graphics.lockFocus(image)
        DrawText(text, width / 2, height / 2, alignment)
        playdate.graphics.unlockFocus()
        image = image:scaledImage(2)
        if (id) then
            DrawScaledTextImageCacheById[id] = {} -- only keep most recent unique image for id
            DrawScaledTextImageCacheById[id][key] = image
        else
            DrawScaledTextImageCache[key] = image
        end
    end
    image:drawAnchored(x, y, 0.5, 0.5)
end

function DrawText(text, x, y, alignment)
    if (alignment == nil) then
        alignment = 'left'
    end
    Gfx.drawTextAligned(text, x, y, kTextAlignment[alignment])
end

Not sure if it handles all cases (I only did centered for this case), and it might not be the most perfect code, but if you need to scale up some text, it should work well enough.

3 Likes

This all worked fine, but eventually I just created a double size font.

In caps, I created my normal size font, and when saving I used "Separate" instead of "all in one". This creates a png file and a .fnt file which is just plaintext.

I created a copy of both, and in the file names, doubled the numbers for the width and height. Then I opened the image and doubled the pixel width and height for it. Then I opened the fnt file in the editor, and next to each character I doubled the value representing the width. I also doubled x-height in the top of the file, though I think that is just a value used when editing in Caps.

Takes about 2 minutes, and probably has some great performance boost on the hardware compared to what I was doing with writing the text to an image, doubling it, and then painting it on the screen.

I might make a node.js script if it becomes something I need to do frequently (I love creating dingbat characters for simple things that need to show in line for menus and such).