Font rotation & anchor point

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
Post Reply
Altostratus
Prole
Posts: 4
Joined: Sun Jan 05, 2025 9:07 am

Font rotation & anchor point

Post by Altostratus »

Hello,

I'm new to Love2D but have prior experience in other languages and frameworks. I'm trying to draw the individual characters of a string around a circle, with the baseline of each character pointing to the circle's center, at a specified radius (imagine a clock face with roman numerals).

After reading about Canvas transformations and pulling my hair out a bit, I've come up with this, which works fine:

Code: Select all

function DrawString(letters, x, y, r)
    love.graphics.push()
    love.graphics.translate(x, y)
    for i = 1, (#letters) do
        local l = string.sub(letters, i, i)
        local w = Font:getWidth(l) / 2 -- Font is defined globally
        love.graphics.print(l, -w, -r * Screen.s) -- Screen.s adjusts for resolution scaling
        love.graphics.rotate(math.pi * 2 / #letters)
    end
    love.graphics.pop()
end
I'm wondering if it's the best way to do it. Most of the time it'll be a background object, and calculating and redrawing it on every frame seems expensive. I don't have any issues yet since I'm just starting, but I'm curious about best practices.

Thanks for your help.
kov_serg
Prole
Posts: 12
Joined: Wed Dec 18, 2024 4:38 pm

Re: Font rotation & anchor point

Post by kov_serg »

Code: Select all

if not love then os.execute "love ." os.exit() end
local gr=love.graphics
local app={t=0}

function ctext(text,xo,yo,r,a0,shift)
	shift=shift or 0
	gr.setColor{0,0.3,0} gr.circle('line',xo,yo,r)
	if shift~=0 then gr.setColor{0.4,0,0} gr.circle('line',xo,yo,r+shift) end
	local font=gr.getFont()
	local n,a=#text, a0 or 0
	for i=1,n do
		local ch=text:sub(i,i)
		local w,h=font:getWidth(ch), font:getHeight(ch)
		a=a+0.5*w/(r+shift)
		gr.push()
		gr.translate(xo+r*math.sin(a), yo+r*math.cos(a))
		gr.rotate(-a) gr.translate(-w*0.5,shift)
		gr.setColor{0.2,0.2,0.2} gr.rectangle('line',0,0,w,h) gr.setColor{1,1,1}
		gr.print(ch)
		gr.pop()
		a=a+0.5*w/(r+shift)
	end
end

function love.load() gr.setNewFont(24) end
function love.update(dt) app.t=app.t+dt end
function love.keypressed(key)
	if key=='escape' then love.event.quit() end
end
function love.draw()
	ctext("The quick brown fox jumps over the lazy dog 0123456789.",200,200,125,app.t*0.3-1.7,-10)
end
Image
dad
Prole
Posts: 3
Joined: Thu Jul 25, 2024 6:02 pm

Re: Font rotation & anchor point

Post by dad »

I think what you're asking for is something like this:

Code: Select all

local canvas = love.graphics.newCanvas(r* 2, r * 2)
function love.load()
	love.graphics.setCanvas(canvas)
	DrawString("Hello, World!", r, r, r)
	love.graphics.setCanvas()
end

function love.draw()
	love.graphics.draw(canvas, 0, 0)
end
So that you only call DrawString once (in this example), or just whenever this circle needs to be updated, rather than each draw call. No canvas transformations should be needed.
BurrickSlayer
Prole
Posts: 16
Joined: Sat Dec 21, 2013 4:28 pm

Re: Font rotation & anchor point

Post by BurrickSlayer »

Another option would be to use a Text object: https://love2d.org/wiki/Text

The name "Text" might be a bit misleading here, because actually this is a text batch object (that's why it will be renamed to TextBatch in LÖVE 12). In other words, you can add several strings to this object, each with a different transformation. And then you can draw them all together with one draw call.
Post Reply

Who is online

Users browsing this forum: Ahrefs [Bot], Google [Bot] and 13 guests