Hi folks,
I’ve had a lot of fun recently with Lua and the Corona SDK but I noticed that the text support (whilst good) did appear lacking in terms of layout options and general “rich text” support - so instead of plumping for a Webview, I’ve put together a function that takes as input a table of data to render as text, but will also recognise certain “commands” so that you can change the font, size, colour, margins etc.
The code should be self explanatory (all the commands start with a “#” and are stored as separate table entries, any parameters to the commands (ie the colour RGB values) are stored in the table as separate entries (the commands should know how many parameters are required). Ultimately each “word” is rendered as a separate text object and added to a display group - the group is then returned and due to the excellent display hierarchy system can be manipulated as a single unit (for scrolling / panning etc)
Extending / personalising the command list should be trivial - as would be changing the font types etc.
Hopefully this code will be of use to someone, possibly for laying out help screens or in game text using multiple fonts / colours etc.
local gameGroup = display.newGroup()
local textGroup = display.newGroup()
-- --------------------------------------------------------------------------------------------------
-- ==================================================================================================
-- --------------------------------------------------------------------------------------------------
local displayList = {
"Hello world, this is some \"text\" that I want to display it's a very long line that should wrap over several lines",
"#brn",45, -- line break with a variable height
"#cl",255,128,0, -- set the colour
"Normal text",
"#bl", -- bold text
"Bold text",
"#nm", -- normal text
"#cl",255,0,0,
"more normal text",
"#lm",20,"#rm",280, -- set the left and right margins
"#br",
"The line feed character shouldn't be used to split lines",
"#cla",0,0,0,128, -- set the colour (and alpha)
"Or a paragraph marker would also work as well",
"#lm",0,"#rm",320,
"#br",
"#cl",0,0,0,
"The moving finger writes and having written moves on",
"and on and on and on...",
}
-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
local currentFont = "Verdana"
local currentSize = 20
local currentColR = 0
local currentColG = 0
local currentColB = 0
local currentColA = 255
local currentAlign = 0
local leading = 0
local spaceWidth = -3
local xLeft = 0
local xRight = 320
local lastX, lastY, lastHeight
-- --------------------------------------------------------------------------------------------------
function explode(div,str)
if (div=='') then return false end
local pos,arr = 0,{}
-- for each divider found
for st,sp in function() return string.find(str,div,pos,true) end do
-- Attach chars left of current divider
-- table.insert(arr,string.sub(str,pos,st-1))
arr[#arr+1] = string.sub(str,pos,st-1)
pos = sp + 1 -- Jump past current divider
end
-- Attach chars right of last divider
-- table.insert(arr,string.sub(str,pos))
arr[#arr+1] = string.sub(str,pos)
return arr
end
-- --------------------------------------------------------------------------------------------------
function makeLines(strings,group)
strings = explode(" ",strings)
local num = #strings
local tlx,w,word
for i=1,num do
word = display.newText(strings[i],0,0,currentFont,currentSize)
word:setReferencePoint(display.TopLeftReferencePoint)
word:setTextColor(currentColR,currentColG,currentColB,currentColA)
w = word.width
lastHeight = word.height
tlx = lastX + w
if tlx \> xRight then lastY = lastY + lastHeight; lastX = xLeft end
word.x = lastX; word.y = lastY; lastX = lastX + (w + spaceWidth)
group:insert(word)
end
end
-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- Generate a text group that contains several other text groups formatted as per the instructions
-- in the display list...
local function newTextLayout(list)
local index,data,t
local listLen = #list
local g = display.newGroup()
lastX, lastY = 0,0
-- print("Listlength = " .. listLen)
index = 1
while index \<= listLen do
data = list[index] index = index + 1
-- Check data to see if it's a valid command (add your own as required)
if data == "#br" then lastX = xLeft; lastY = lastY + lastHeight
elseif data == "#brn" then t = tonumber(list[index]) lastX = xLeft; lastY = lastY + t; index = index + 1
elseif data == "#lm" then xLeft = tonumber(list[index]); index = index + 1
elseif data == "#rm" then xRight = tonumber(list[index]); index = index + 1
elseif data == "#bl" then currentFont = "Helvetica"; currentSize = 25;
elseif data == "#nm" then currentFont = "Verdana"; currentSize = 20;
elseif data == "#cl" then currentColR = tonumber(list[index]); currentColG = tonumber(list[index+1]); currentColB = tonumber(list[index+2]); currentColA = 255; index = index + 3
elseif data == "#cla" then currentColR = tonumber(list[index]); currentColG = tonumber(list[index+1]); currentColB = tonumber(list[index+2]); currentColA = tonumber(list[index+3]); index = index + 4
else
-- Else it's a string to render into a block of text groups
makeLines(data,g)
end
end
return g
end
-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
local plat = display.newRect(0,0,320,480)
plat:setReferencePoint(display.TopLeftReferencePoint)
gameGroup:insert(plat)
gameGroup:insert(textGroup)
textGroup:insert(newTextLayout(displayList))
print("Text group ".. textGroup.width ..",".. textGroup.height)
Comments, suggestions and improvements welcome.
I’ve only just started with Lua so if anyone’s got any feedback on how to improve my Lua let’s hear 'em.
Apologies if this post is in the wrong section - hopefully a mod can move it and post a re-direction.
Jon… [import]uid: 7901 topic_id: 8406 reply_id: 308406[/import]
[import]uid: 7901 topic_id: 8406 reply_id: 30115[/import]