aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--font_api/depends.txt1
-rw-r--r--font_api/display_api.lua77
-rw-r--r--font_api/font.lua15
-rw-r--r--font_api/init.lua54
4 files changed, 92 insertions, 55 deletions
diff --git a/font_api/depends.txt b/font_api/depends.txt
index e69de29..88fa963 100644
--- a/font_api/depends.txt
+++ b/font_api/depends.txt
@@ -0,0 +1 @@
+display_api?
diff --git a/font_api/display_api.lua b/font_api/display_api.lua
new file mode 100644
index 0000000..2191dba
--- /dev/null
+++ b/font_api/display_api.lua
@@ -0,0 +1,77 @@
+--[[
+ font_api mod for Minetest - Library to create textures with fonts and text
+ (c) Pierre-Yves Rollo
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+--]]
+
+-- Integration with display API
+
+if minetest.get_modpath("display_api") then
+ --- Standard on_display_update entity callback.
+ -- Node should have properly configured display_entity.
+ -- @param pos Node position
+ -- @param objref Object reference of entity
+
+ font_api.on_display_update = function (pos, objref)
+ local meta = minetest.get_meta(pos)
+ local ndef = minetest.registered_nodes[minetest.get_node(pos).name]
+ local entity = objref:get_luaentity()
+
+ if not entity or not ndef.display_entities[entity.name] then
+ return
+ end
+
+ local def = ndef.display_entities[entity.name]
+ local font = font_api.get_font(meta:get_string("font") ~= ""
+ and meta:get_string("font") or def.font_name)
+
+ local text = meta:get_string(def.meta_text or "display_text")
+
+ -- Compute entity resolution accroding to given attributes
+ local texturew, textureh
+ textureh = font:get_height(def.lines or def.maxlines or 1)
+
+ if def.columns then
+ if font.fixedwidth then
+ texturew = def.columns * font.fixedwidth
+ if def.aspect_ratio then
+ minetest.log('warning', "[font_api] 'aspect_ratio' ignored because 'columns' is specified")
+ end
+ else
+ minetest.log('warning', "[font_api] 'columns' ignored because '"..font.name.."' is not a fixed width font.")
+ end
+ end
+
+ if not texturew then
+ if not def.aspect_ratio then
+ minetest.log('warning', "[font_api] No 'aspect_ratio' specified, using default 1.")
+ end
+ texturew = textureh * def.size.x / def.size.y / (def.aspect_ratio or 1)
+ end
+
+ objref:set_properties({
+ textures={ font:render(text, texturew, textureh, {
+ lines = def.maxlines or def.lines,
+ halign = def.halign,
+ valign = def.valign,
+ color = def.color} ) },
+ visual_size = def.size,
+ })
+ end
+else
+ font_api.on_display_update = function (pos, objref)
+ minetest.log('error', '[font_api] font_api.on_display_update called but display_api mod not enabled.')
+ end
+end
diff --git a/font_api/font.lua b/font_api/font.lua
index 8eb43db..2304cd9 100644
--- a/font_api/font.lua
+++ b/font_api/font.lua
@@ -39,14 +39,15 @@ local function char_to_codepoint(str)
local bytes = get_char_bytes(str)
if bytes == 1 then
return str:byte(1)
- elseif bytes == 2 then
+ elseif bytes == 2 and str:byte(2) ~= nil then
return (str:byte(1) - 0xC2) * 0x40
+ str:byte(2)
- elseif bytes == 3 then
+ elseif bytes == 3 and str:byte(2) ~= nil and str:byte(3) ~= nil then
return (str:byte(1) - 0xE0) * 0x1000
+ str:byte(2) % 0x40 * 0x40
+ str:byte(3) % 0x40
- elseif bytes == 4 then -- Not tested
+ elseif bytes == 4 and str:byte(2) ~= nil and str:byte(3) ~= nil
+ and str:byte(4) ~= nil then -- Not tested
return (str:byte(1) - 0xF0) * 0x40000
+ str:byte(2) % 0x40 * 0x1000
+ str:byte(3) % 0x40 * 0x40
@@ -117,6 +118,12 @@ function Font:get_next_char(text)
local codepoint = char_to_codepoint(text)
+ if codepoint == nil then
+ minetest.log("warning",
+ "[font_api] Encountered a non UTF char, not displaying text.")
+ return nil, ''
+ end
+
-- Fallback mechanism
if self.widths[codepoint] == nil then
local char = text:sub(1, bytes)
@@ -175,6 +182,7 @@ function Font:get_width(line)
while line ~= "" do
codepoint, line = self:get_next_char(line)
+ if codepoint == nil then return 0 end -- UTF Error
width = width + self:get_char_width(codepoint)
end
@@ -247,6 +255,7 @@ function Font:render(text, texturew, textureh, style)
while line.text ~= '' do
codepoint, line.text = self:get_next_char(line.text)
+ if codepoint == nil then return '' end -- UTF Error
-- Add image only if it is visible (at least partly)
if x + self.widths[codepoint] >= 0 and x <= texturew then
diff --git a/font_api/init.lua b/font_api/init.lua
index 307049b..7fbedf9 100644
--- a/font_api/init.lua
+++ b/font_api/init.lua
@@ -30,58 +30,8 @@ font_api.path = minetest.get_modpath(font_api.name)
dofile(font_api.path.."/font.lua")
dofile(font_api.path.."/registry.lua")
dofile(font_api.path.."/fontform.lua")
-
---- Standard on_display_update entity callback.
--- Node should have a corresponding display_entity with size, resolution and
--- maxlines fields and optionally halign, valign and color fields
--- @param pos Node position
--- @param objref Object reference of entity
-
-function font_api.on_display_update(pos, objref)
- local meta = minetest.get_meta(pos)
- local ndef = minetest.registered_nodes[minetest.get_node(pos).name]
- local entity = objref:get_luaentity()
-
- if not entity or not ndef.display_entities[entity.name] then
- return
- end
-
- local def = ndef.display_entities[entity.name]
- local font = font_api.get_font(meta:get_string("font") ~= ""
- and meta:get_string("font") or def.font_name)
-
- local text = meta:get_string(def.meta_text or "display_text")
-
- -- Compute entity resolution accroding to given attributes
- local texturew, textureh
- textureh = font:get_height(def.lines or def.maxlines or 1)
-
- if def.columns then
- if font.fixedwidth then
- texturew = def.columns * font.fixedwidth
- if def.aspect_ratio then
- minetest.log('warning', "[font_api] 'aspect_ratio' ignored because 'columns' is specified")
- end
- else
- minetest.log('warning', "[font_api] 'columns' ignored because '"..font.name.."' is not a fixed width font.")
- end
- end
-
- if not texturew then
- if not def.aspect_ratio then
- minetest.log('warning', "[font_api] No 'aspect_ratio' specified, using default 1.")
- end
- texturew = textureh * def.size.x / def.size.y / (def.aspect_ratio or 1)
- end
-
- objref:set_properties({
- textures={ font:render(text, texturew, textureh, {
- lines = def.maxlines or def.lines,
- halign = def.halign,
- valign = def.valign,
- color = def.color} ) },
- visual_size = def.size,
- })
+if minetest.get_modpath("display_api") then
+ dofile(font_api.path.."/display_api.lua")
end
-- Compatibility