Created
January 20, 2015 03:52
-
-
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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