Add proper word-wrapping.

Also cleaned up a bit code.
This commit is contained in:
kaeza 2013-10-24 23:32:37 -02:00
parent a963352793
commit 119f8fe494

View File

@ -209,65 +209,80 @@ local fences_with_sign = { }
-- some local helper functions -- some local helper functions
local homedecor_create_lines = function(text) local function split_lines_and_words(text)
local tab = {} local lines = { }
for line in text:gmatch("([^|]+)|?") do local line = { }
line = line:gsub("^%s*(.*)%s*$", "%1") -- Trim whitespace for word in text:gmatch("%S+") do
table.insert(tab, line) if word == "|" then
if #tab >= NUMBER_OF_LINES then break end table.insert(lines, line)
if #lines >= NUMBER_OF_LINES then break end
line = { }
elseif word == "\\|" then
table.insert(line, "|")
else
table.insert(line, word)
end
end end
return tab table.insert(lines, line)
return lines
end end
local math_max = math.max local math_max = math.max
local homedecor_generate_line = function(s, lineno) local function make_line_texture(line, lineno)
local width = 0 local width = 0
local maxw = 0 local maxw = 0
local chars = { } local words = { }
-- We check which chars are available here. -- We check which chars are available here.
for i = 1, #s do for word_i, word in ipairs(line) do
local c = s:sub(i, i) local chars = { }
local w = charwidth[c] local ch_offs = 0
if w then for i = 1, #word do
width = width + w + 1 local c = word:sub(i, i)
if width >= SIGN_WIDTH then local w = charwidth[c]
width = 0 if w then
else width = width + w + 1
maxw = math_max(width, maxw) if width >= SIGN_WIDTH then
width = 0
else
maxw = math_max(width, maxw)
end
table.insert(chars, {
off=ch_offs,
tex=FONT_FMT_SIMPLE:format(c:byte())
})
ch_offs = ch_offs + w + 1
end end
table.insert(chars, c)
end end
width = width + charwidth[" "] + 1
maxw = math_max(width, maxw)
table.insert(words, { chars=chars, w=ch_offs })
end end
maxw = maxw - 1
-- Okay, we actually build the "line texture" here. -- Okay, we actually build the "line texture" here.
local start_xpos = math.floor((SIGN_WIDTH - maxw) / 2)
local xpos = start_xpos
local texture = { } local texture = { }
local ypos = (LINE_HEIGHT * (lineno --[[+ 1]]))
width = 0 local start_xpos = math.floor((SIGN_WIDTH - maxw) / 2)
for i = 1, #s do local xpos = start_xpos
local c = s:sub(i, i) local ypos = (LINE_HEIGHT * lineno)
local w = charwidth[c]
local tex = FONT_FMT_SIMPLE:format(c:byte()) for word_i, word in ipairs(words) do
table.insert(texture, (":%d,%d=%s"):format(xpos, ypos, tex)) local xoffs = (xpos - start_xpos)
xpos = xpos + w + 1 if (xoffs > 0) and ((xoffs + word.w) > maxw) then
width = width + w + 1
if width > maxw then
xpos = start_xpos xpos = start_xpos
ypos = ypos + (LINE_HEIGHT * LINE_SEP) ypos = ypos + (LINE_HEIGHT * LINE_SEP)
width = 0
lineno = lineno + 1 lineno = lineno + 1
if lineno >= NUMBER_OF_LINES then break end
end end
if lineno >= NUMBER_OF_LINES then break end for ch_i, ch in ipairs(word.chars) do
table.insert(texture, (":%d,%d=%s"):format(xpos + ch.off, ypos, ch.tex))
end
xpos = xpos + word.w + charwidth[" "]
end end
return table.concat(texture, ""), lineno return table.concat(texture, ""), lineno
@ -285,21 +300,21 @@ local function copy ( t )
return nt return nt
end end
local homedecor_generate_texture = function(lines) local function make_sign_texture(lines)
local texture = { ("[combine:%dx%d"):format(SIGN_WIDTH, LINE_HEIGHT * NUMBER_OF_LINES * LINE_SEP) } local texture = { ("[combine:%dx%d"):format(SIGN_WIDTH, LINE_HEIGHT * NUMBER_OF_LINES * LINE_SEP) }
local lineno = 0 local lineno = 0
for i = 1, #lines do for i = 1, #lines do
if lineno >= NUMBER_OF_LINES then break end if lineno >= NUMBER_OF_LINES then break end
local linetex, ln = homedecor_generate_line(lines[i], lineno) local linetex, ln = make_line_texture(lines[i], lineno)
table.insert(texture, linetex) table.insert(texture, linetex)
lineno = ln + 1 lineno = ln + 1
end end
return table.concat(texture, "") return table.concat(texture, "")
end end
local function set_obj_text(obj, text) local function set_obj_text(obj, text)
obj:set_properties({ obj:set_properties({
textures={homedecor_generate_texture(homedecor_create_lines(text))}, textures={make_sign_texture(split_lines_and_words(text))},
visual_size = TEXT_SCALE, visual_size = TEXT_SCALE,
}) })
end end
@ -319,10 +334,19 @@ homedecor.destruct_sign = function(pos)
end end
end end
local function make_infotext(text)
local lines = split_lines_and_words(text)
local lines2 = { }
for _, line in ipairs(lines) do
table.insert(lines2, table.concat(line, " "))
end
return table.concat(lines2, "\n")
end
homedecor.update_sign = function(pos, fields) homedecor.update_sign = function(pos, fields)
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
if fields then if fields then
meta:set_string("infotext", table.concat(homedecor_create_lines(fields.text), "\n")) meta:set_string("infotext", make_infotext(fields.text))
meta:set_string("text", fields.text) meta:set_string("text", fields.text)
end end
local text = meta:get_string("text") local text = meta:get_string("text")