Skip to content

Instantly share code, notes, and snippets.

@pablomayobre
Created January 20, 2015 03:52
Show Gist options
  • Save pablomayobre/2eccf6aff9b135982c75 to your computer and use it in GitHub Desktop.
Save pablomayobre/2eccf6aff9b135982c75 to your computer and use it in GitHub Desktop.
A custom prinft for LÖVE which wraps words in the right way while long words get character wrapped
local sub,len,find = string.sub, string.len, string.find
local function getLine(line,text,lBeg,lEnd)
line[#line + 1] = sub(text,lBeg, lEnd)
return lEnd + 1
end
local function wordwrapping(text,limit,f)
local st = "Width of letter '%s' is %dpx, greater than the wrapping width of %dpx.\nIncrease the wrapping width!"
local line, lBeg, lEnd = {}, 0, 0
repeat
local testEnd = (find(text,"%s", lEnd + 1) or len(text))
if f:getWidth(sub(text, lEnd, testEnd)) > limit then
if lEnd > 0 or #line > 0 then
lBeg = getLine(line,text,lBeg,lEnd)
end
local wEnd = testEnd
while f:getWidth(sub(text, lBeg, wEnd)) > limit do
local p = sub(text, lEnd, lEnd + 1)
local q = f:getWidth(sub(text, lEnd, lEnd + 1))
if wEnd == lBeg then error(string.format(st,p,q,limit)) end
wEnd = wEnd - 1
end
lEnd = wEnd
elseif f:getWidth(sub(text, lBeg, testEnd)) > limit then
lBeg = getLine(line,text,lBeg,lEnd)
else
lEnd = testEnd
end
until lEnd == len(text)
line[#line + 1] = sub(text, lBeg, len(text))
return line
end
local function printf(text, x, y, limit, align, r, sx, sy, ox, oy, kx, ky, scale)
local scale = scale or "box"
if scale == "text" then
scale = true
elseif scale == "box" then
scale = false
end
if not (scale == true or scale == false) then
error("Argument #13 to printf is not a valid ScaleMode")
end
--NIL ASSIGNMENT
local align = align == nil and "left" or align
local limit = limit == nil and 0 or limit
local r, sx = r or 0, sx or 1
local sy, ox = sx or sy, ox or 0
local oy, kx = oy or 0, kx or 0
local ky = ky or 0
--TYPES CHECK
local types = {
"string","number","number",
"number","string","number",
"number","number","number",
"number","number","number"
}
local t = {text, x, y, limit, align, r, sx, sy, ox, oy, kx, ky}
local st = "Bad argument #%d to printf (%s expected got %s)"
for i = 1, #types do
if not type(t[i]) == types[i] then
error(string.format(st,i,types[i],type(t[i])))
end
end
--ALIGN MODE CHECK
if not (align == "left" or align == "center" or align == "right") then
error("The argument #4 to printf, is not a valid AlignMode")
end
--THE REAL DEAL
if w == 0 then --No limit acts as the simpler print
love.graphics.print(text,x,y,r,sx,sy,ox,oy,kx,ky)
else
f = love.graphics.getFont()
--WORD/TEXT WRAPPING
--Neads some kind of memoizing to be more eficient
local line = wordwrapping(text,limit,f)
--PRINTING THE LINES
--Breaks the center and right alignment
--[[
line = table.concat(line, "\n")
if align == "center" then
love.graphics.print(line, x + (limit - f:getWidth(line)) / 2, y)
elseif align == "right" then
love.graphics.print(line, x + limit - f:getWidth(line), y)
else
love.graphics.print(line, x, y)
end
]]
--Non-breaking method
local lh = f:getLineHeight() * f:getHeight() * sy
for i=1, #line do
local offsety = lh * (i - 1)
local offsetx = 0
if align == "center" then
offsetx = (((limit / (scale and sx or 1)) - f:getWidth(line[i]))/2) * sx
elseif align == "right" then
offsetx = ((limit / (scale and sx or 1)) - f:getWidth(line[i])) * sx
end
love.graphics.print(line[i], x + offsetx, y + offsety, r, sx, sy, ox, oy, kx, ky)
end
end
end
return printf
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment