diff options
Diffstat (limited to 'font_api')
-rw-r--r-- | font_api/depends.txt | 1 | ||||
-rw-r--r-- | font_api/display_api.lua | 77 | ||||
-rw-r--r-- | font_api/font.lua | 15 | ||||
-rw-r--r-- | font_api/init.lua | 54 |
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 |