aboutsummaryrefslogtreecommitdiff
path: root/font_lib/init.lua
diff options
context:
space:
mode:
authorPierre-Yves Rollo <dev@pyrollo.com>2015-11-28 20:44:04 +0100
committerPierre-Yves Rollo <dev@pyrollo.com>2015-11-28 20:44:04 +0100
commit1b39bf7ae31f0781c65c0a8f9e1d94a37def5f56 (patch)
treeb1ca35fc4238e17eedf782c3b0f631e81d2f7558 /font_lib/init.lua
parent9b4513bf9ded0ec759431140b59382fea0bc6009 (diff)
downloaddisplay_modpack-1b39bf7ae31f0781c65c0a8f9e1d94a37def5f56.tar.gz
display_modpack-1b39bf7ae31f0781c65c0a8f9e1d94a37def5f56.tar.bz2
display_modpack-1b39bf7ae31f0781c65c0a8f9e1d94a37def5f56.zip
Added facedir node support to display_lib, created font_lib, updated mods accordingly
Diffstat (limited to 'font_lib/init.lua')
-rw-r--r--font_lib/init.lua139
1 files changed, 139 insertions, 0 deletions
diff --git a/font_lib/init.lua b/font_lib/init.lua
new file mode 100644
index 0000000..3e5b8c7
--- /dev/null
+++ b/font_lib/init.lua
@@ -0,0 +1,139 @@
+-- Font lib mod by P.Y. Rollo
+--
+-- License: WTFPL
+
+font_lib = {}
+font_lib.path = minetest.get_modpath("font_lib")
+font_lib.font_height = 10
+font_lib.font = {}
+
+-- Get png width, suposing png width is less than 256 (it is the case for all font textures)
+local function get_png_width(filename)
+ local file=assert(io.open(filename,"rb"))
+ -- All font png are smaller than 256x256 --> read only last byte
+ file:seek("set",19)
+ local w = file:read(1)
+ file:close()
+ return w:byte()
+end
+
+-- Computes line width for a given font height and text
+-- @param text Text to be rendered
+-- @return Rendered text width
+function font_lib.get_line_width(text)
+ local char
+ local width = 0
+
+ for p=1,#text
+ do
+ char = text:sub(p,p):byte()
+ if font_lib.font[char] then
+ width = width + font_lib.font[char].width
+ end
+ end
+
+ return width
+end
+
+--- Builds texture part for a text line
+-- @param text Text to be rendered
+-- @param texturew Width of the texture (extra text is not rendered)
+-- @param x Starting x position in texture
+-- @param y Vertical position of the line in texture
+-- @return Texture string
+function font_lib.make_line_texture(text, texturew, x, y)
+ local char
+
+ local texture = ""
+
+ for p=1,#text
+ do
+ char = text:sub(p,p):byte()
+ if font_lib.font[char] then
+ -- Add image only if it is visible (at least partly)
+ if x + font_lib.font[char].width >= 0 and x <= texturew then
+ texture = texture..string.format(":%d,%d=%s", x, y, font_lib.font[char].filename)
+ end
+ x = x + font_lib.font[char].width
+ end
+ end
+ return texture
+end
+
+local function split_lines(text, maxlines)
+ local splits = text:split("\n")
+ if maxlines then
+ local lines = {}
+ for num = 1,maxlines do
+ lines[num] = splits[num]
+ end
+ return lines
+ else
+ return splits
+ end
+end
+
+--- Builds texture for a multiline colored text
+-- @param text Text to be rendered
+-- @param texturew Width of the texture (extra text will be truncated)
+-- @param textureh Height of the texture
+-- @param maxlines Maximum number of lines
+-- @param valign Vertical text align ("top" or "center")
+-- @param color Color of the text
+-- @return Texture string
+function font_lib.make_multiline_texture(text, texturew, textureh, maxlines, valign, color)
+ local texture = ""
+ local lines = split_lines(text, maxlines)
+ local y
+
+ if valign == "top" then
+ y = font_lib.font_height / 2
+ else
+ y = (textureh - font_lib.font_height * #lines) / 2 + 1
+ end
+
+ for _, line in pairs(lines) do
+ texture = texture..font_lib.make_line_texture(line, texturew,
+ (texturew - font_lib.get_line_width(line)) / 2, y)
+ y = y + font_lib.font_height
+ end
+
+ texture = string.format("[combine:%dx%d", texturew, textureh)..texture
+ if color then texture = texture.."^[colorize:"..color end
+
+ return texture
+end
+
+--- Standard on_display_update entity callback.
+-- Node should have a corresponding display_entity with size, resolution and maxlines fields and
+-- optionally valign and color fields
+-- @param pos Node position
+-- @param objref Object reference of entity
+
+function font_lib.on_display_update(pos, objref)
+ local meta = minetest.get_meta(pos)
+ local text = meta:get_string("display_text")
+
+ local ndef = minetest.registered_nodes[minetest.get_node(pos).name]
+ local entity = objref:get_luaentity()
+
+ if entity and ndef.display_entities[entity.name] then
+ local def = ndef.display_entities[entity.name]
+
+ objref:set_properties({
+ textures={font_lib.make_multiline_texture(
+ text, def.size.x*def.resolution.x, def.size.y*def.resolution.y,
+ def.maxlines, def.valign, def.color)},
+ visual_size = def.size
+ })
+ end
+end
+
+-- Populate fonts table
+local w, filename
+for charnum=32,126 do
+ filename = string.format("font_lib_%02x.png", charnum)
+ w = get_png_width(font_lib.path.."/textures/"..filename)
+ font_lib.font[charnum] = {filename=filename, width=w}
+end
+