From f46dd0a72ecf04937cef661a2e599ffb71417ba7 Mon Sep 17 00:00:00 2001 From: Pierre-Yves Rollo Date: Wed, 5 Dec 2018 15:41:56 +0100 Subject: [PATCH 01/10] New Font:render method --- display_api/init.lua | 2 +- font_api/API.md | 44 +++++++++----- font_api/font.lua | 142 +++++++++++++++++++------------------------ font_api/init.lua | 72 ++++++++++++---------- signs/nodes.lua | 5 +- 5 files changed, 135 insertions(+), 130 deletions(-) diff --git a/display_api/init.lua b/display_api/init.lua index bf95ded..d4f7dcd 100644 --- a/display_api/init.lua +++ b/display_api/init.lua @@ -120,7 +120,7 @@ function update_entity(entity) if not entity then return end - + if not entity.nodepos then entity.object:remove() -- Remove old/buggy entity return diff --git a/font_api/API.md b/font_api/API.md index 6c14ac4..f3f4437 100644 --- a/font_api/API.md +++ b/font_api/API.md @@ -37,7 +37,7 @@ minetest.register_node("mymod:test_text_node", { }) ``` -At this step, your node already displays text form "display_text" (hardcoded) node meta. +At this step, your node already displays text form "display_text" (by default) node meta. If you want to store your text into another meta data field, add a `meta_text` field to display entity definition. But it uses defaults (default font, default size, default color). Likely you need something more. @@ -59,6 +59,28 @@ Then specify the char width. Two methods available: * `halign`: Horizontal alignment: "left", "center" or "right" (default "center"). * `valign`: Vertical alignement: "top", "middle" or "bottom" (default "middle"). +### Example +Using blue //botic// font, three lines height, aligned top left. Text stored in "text" node meta. +``` +minetest.register_node("mymod:test_text_node", { + ... + ... + display_entities = { + ["mymod:text"] = { + depth = -0.5 - display_api.entity_spacing, + on_display_update = font_api.on_display_update + meta_text = "text", + font_name = "botic", + color = "#0000FF", + maxlines = 3, + aspect_ratio = 0.5, + halign = "left", + valign = "top", + }, + } + ... +}) +``` ## Provided methods ### font_api.get_default_font_name() Returns de default font name. @@ -159,19 +181,13 @@ Returns line(s) height. Takes care of top and bottom margins and line spacing. Returns the width of a text line. Beware, if line contains any new line char, they are ignored. * `line`: Line of text which the width will be computed. -### font:make_line_texture(line, texturew, x, y) -Create a texture for a text line. - * `line`: Line of text to be rendered in texture. - * `texturew`: Width of the texture (extra text is not rendered). - * `x`: Starting x position in texture. - * `y`: Vertical position of the line in texture. - -### font:make_text_texture(text, texturew, textureh, maxlines, halign, valign, color) +### font:renter(text, texturew, textureh, style) Builds texture for a multiline colored text. * `text`: Text to be rendered. * `texturew`: Width of the texture (extra text will be truncated). - * `textureh`: Height of the texture. - * `maxlines`: Maximum number of lines. - * `halign`: Horizontal text align ("left"/"center"/"right") (optional). - * `valign`: Vertical text align ("top"/"center"/"bottom") (optional). - * `color`: Color of the text (optional). + * `textureh`: Height of the texture (extra text will be truncated). + * `style`: A table with style indications: + - `lines` or `maxlines`: Maximum number of lines (default none). + - `halign`: Horizontal text align: "left"/"center"/"right" (default "center") + - `valign`: Vertical text align: "top"/"middle"/"bottom" (default "middle") + - `color`: Color of the text (default black) diff --git a/font_api/font.lua b/font_api/font.lua index a69e049..8eb43db 100644 --- a/font_api/font.lua +++ b/font_api/font.lua @@ -54,20 +54,6 @@ local function char_to_codepoint(str) end end --- Split multiline text into array of lines, with maximum lines. --- Can not use minetest string.split as it has bug if first line(s) empty -local function split_lines(text, maxlines) - local lines = {} - local pos = 1 - repeat - local found = string.find(text, "\n", pos) - found = found or #text + 1 - lines[#lines + 1] = string.sub(text, pos, found - 1) - pos = found + 1 - until (maxlines and (#lines >= maxlines)) or (pos > (#text + 1)) - return lines -end - -------------------------------------------------------------------------------- --- Font class @@ -195,88 +181,86 @@ function Font:get_width(line) return width end ---- Builds texture part for a text line --- @param line Text line 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:make_line_texture(line, texturew, x, y) - local codepoint - local texture = "" - line = line or '' - - while line ~= '' do - codepoint, line = self:get_next_char(line) - - -- Add image only if it is visible (at least partly) - if x + self:get_char_width(codepoint) >= 0 and x <= texturew then - texture = texture.. - string.format(":%d,%d=font_%s_%04x.png", - x, y, self.name, codepoint) - end - x = x + self:get_char_width(codepoint) - end - - return texture -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 halign Horizontal text align ("left"/"center"/"right") (optional) --- @param valign Vertical text align ("top"/"center"/"bottom") (optional) --- @param color Color of the text (optional) --- @return Texture string +--- Legacy make_text_texture method (replaced by "render" - Dec 2018) function Font:make_text_texture(text, texturew, textureh, maxlines, halign, valign, color) - local texture = "" - local lines = {} - local textheight = 0 - local y + return self:render(text, texturew, textureh, { + lines = maxlines, + valign = valign, + halign = halign, + color = color + }) +end - -- Split text into lines (limited to maxlines fist lines) - for num, line in pairs(split_lines(text, maxlines)) do - lines[num] = { text = line, width = self:get_width(line) } +--- Render text with the font in a view +-- @param text Text to be rendered +-- @param texturew Width (in pixels) of the texture (extra text will be truncated) +-- @param textureh Height (in pixels) of the texture (extra text will be truncated) +-- @param style Style of the rendering: +-- - lines: maximum number of text lines (if text is limited) +-- - halign: horizontal align ("left"/"center"/"right") +-- - valign: vertical align ("top"/"center"/"bottom") +-- - color: color of the text ("#rrggbb") +-- @return Texture string + +function Font:render(text, texturew, textureh, style) + local style = style or {} + + -- Split text into lines (and limit to style.lines # of lines) + local lines = {} + local pos = 1 + local found, line + repeat + found = string.find(text, "\n", pos) or (#text + 1) + line = string.sub(text, pos, found - 1) + lines[#lines + 1] = { text = line, width = self:get_width(line) } + pos = found + 1 + until (style.lines and (#lines >= style.lines)) or (pos > (#text + 1)) + + if not #lines then + return "" end - textheight = self:get_height(#lines) + local x, y, codepoint + local texture = "" + local textheight = self:get_height(#lines) - if #lines then - if valign == "top" then - y = 0 - elseif valign == "bottom" then - y = textureh - textheight - else - y = (textureh - textheight) / 2 - end + if style.valign == "top" then + y = 0 + elseif style.valign == "bottom" then + y = textureh - textheight + else + y = (textureh - textheight) / 2 end y = y + (self.margintop or 0) for _, line in pairs(lines) do - if halign == "left" then - texture = texture.. - self:make_line_texture(line.text, texturew, - 0, y) - elseif halign == "right" then - texture = texture.. - self:make_line_texture(line.text, texturew, - texturew - line.width, y) + if style.halign == "left" then + x = 0 + elseif style.halign == "right" then + x = texturew - line.width else - texture = texture.. - self:make_line_texture(line.text, texturew, - (texturew - line.width) / 2, y) + x = (texturew - line.width) / 2 + end + + while line.text ~= '' do + codepoint, line.text = self:get_next_char(line.text) + + -- Add image only if it is visible (at least partly) + if x + self.widths[codepoint] >= 0 and x <= texturew then + texture = texture.. + string.format(":%d,%d=font_%s_%04x.png", x, y, self.name, codepoint) + end + x = x + self.widths[codepoint] end y = y + self:get_height() + (self.linespacing or 0) end - texture = string.format("[combine:%dx%d", texturew, textureh)..texture - if color then texture = texture.."^[colorize:"..color end + if style.color then + texture = texture.."^[colorize:"..style.color + end return texture end diff --git a/font_api/init.lua b/font_api/init.lua index 57a3f44..307049b 100644 --- a/font_api/init.lua +++ b/font_api/init.lua @@ -39,43 +39,49 @@ dofile(font_api.path.."/fontform.lua") function font_api.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] - local font = font_api.get_font(meta:get_string("font") ~= "" - and meta:get_string("font") or def.font_name) - - -- 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:make_text_texture(text, texturew, textureh, - def.maxlines, def.halign, def.valign, def.color)}, - visual_size = def.size - }) + 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 -- Compatibility diff --git a/signs/nodes.lua b/signs/nodes.lua index 8e65e27..b04c463 100644 --- a/signs/nodes.lua +++ b/signs/nodes.lua @@ -33,9 +33,8 @@ local function display_poster(pos, node, player) node.name, minetest.pos_to_string(pos)) -- Title texture - local titletexture = font:make_text_texture( - meta:get_string("display_text"), font:get_height()*8.4, - font:get_height(), 1, "center") + local titletexture = font:render(meta:get_string("display_text"), + font:get_height()*8.4, font:get_height(), { lines = 1 }) fs = string.format([=[ size[7,9]bgcolor[#0000] From feb1b639ff9180af034f5d7993361ea19fef2778 Mon Sep 17 00:00:00 2001 From: Pierre-Yves Rollo Date: Tue, 11 Dec 2018 11:26:50 +0100 Subject: [PATCH 02/10] Better management of invalid UTF strings --- font_api/font.lua | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) 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 From 62c8de26b4a18ec226ea1e1f77030271dde16e98 Mon Sep 17 00:00:00 2001 From: Pierre-Yves Rollo Date: Tue, 11 Dec 2018 11:41:03 +0100 Subject: [PATCH 03/10] Better management of display_api integration --- font_api/depends.txt | 1 + font_api/display_api.lua | 77 ++++++++++++++++++++++++++++++++++++++++ font_api/init.lua | 54 ++-------------------------- 3 files changed, 80 insertions(+), 52 deletions(-) create mode 100644 font_api/display_api.lua 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 . +--]] + +-- 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/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 From 81e6dc89aecb06986908b48959751956d4be2e4d Mon Sep 17 00:00:00 2001 From: Pierre-Yves Rollo Date: Tue, 11 Dec 2018 11:52:55 +0100 Subject: [PATCH 04/10] Added font_lib deprecation and corresponding notices in READMEs --- display_api/README.md | 9 +++++++ font_api/README.md | 10 +++++++- font_api/deprecation.lua | 54 ++++++++++++++++++++++++++++++++++++++++ font_api/init.lua | 4 +-- 4 files changed, 73 insertions(+), 4 deletions(-) create mode 100644 font_api/deprecation.lua diff --git a/display_api/README.md b/display_api/README.md index 26b26f0..079ce6d 100644 --- a/display_api/README.md +++ b/display_api/README.md @@ -12,3 +12,12 @@ This library's purpose is to ease creation of nodes with one or more displays on For more information, see the [forum topic](https://forum.minetest.net/viewtopic.php?t=19365) at the Minetest forums. +## Deprecation notice (for modders) + +### December 2018 +Following objects are deprecated, shows a warning in log when used: +* `display_modpack_node` group (use `display_api` group instead); +* `display_lib_node` group (use `display_api` group instead); +* `display_lib` global table (use `display_api` global table instead); + +These objects will be removed in the future. diff --git a/font_api/README.md b/font_api/README.md index 33af92b..13d287f 100644 --- a/font_api/README.md +++ b/font_api/README.md @@ -16,8 +16,16 @@ For more information, see the [forum topic](https://forum.minetest.net/viewtopic You can add fonts by installing fonts mod. Be aware that each font comes with numerous textures. This can result in slowing media downloading and/or client display. -Font mods can be found here: +Font mods can be found here: * [Metro](https://github.com/pyrollo/display_modpack/tree/master/font_metro): A multipurpose font with many chars (uppercase, lowercase and accentuated latin letters, usual signs, cyrillic and greek letters). * [OldWizard](https://github.com/pyrollo/font_oldwizard): An old style gothic font. * [Botic](https://github.com/pyrollo/font_botic): A scifi style font. + + ## Deprecation notice (for modders) + + ### December 2018 + Following object is deprecate, shows a warning in log when used: + * `font_lib` global table (use `font_api` global table instead); + + This object will be removed in the future. diff --git a/font_api/deprecation.lua b/font_api/deprecation.lua new file mode 100644 index 0000000..5c0bed6 --- /dev/null +++ b/font_api/deprecation.lua @@ -0,0 +1,54 @@ +--[[ + 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 . +--]] + +-- Deprecation + +function deprecated_global_table(deprecated_global_name, replacement_global_name) + assert(type(deprecated_global_name) == 'string', "deprecated_global_name should be a string.") + assert(type(replacement_global_name) == 'string', "replacement_global_name should be a string.") + assert(deprecated_global_name ~= '', "deprecated_global_name should not be empty.") + assert(replacement_global_name ~= '', "replacement_global_name should not be empty.") + assert(rawget(_G, deprecated_global_name) == nil, "replacement global already exists.") + if _G[replacement_global_name] == nil then + print('warn_deprecated_functions: Warning, replacement global "'..replacement_global_name..'" does not exists.') + return + end + local meta = { + deprecated = deprecated_global_name, + replacement = replacement_global_name, + __index = function(table, key) + local meta = getmetatable(table) + local dbg = debug.getinfo(2, "lS") + minetest.log("warning", string.format('Warning: Accessing deprecated "%s" table, "%s" should be used instead (%s:%d).', + meta.deprecated, meta.replacement, (dbg.short_src or 'unknown'), (dbg.currentline or 0))) + return _G[meta.replacement][key] + end, + __newindex = function(table, key, value) + local meta = getmetatable(table) + local dbg = debug.getinfo(2, "lS") + minetest.log("warning", string.format('Warning: Accessing deprecated "%s" table, "%s" should be used instead (%s:%d).', + meta.deprecated, meta.replacement, (dbg.short_src or 'unknown'), (dbg.currentline or 0))) + _G[meta.replacement][key]=value + end, + } + rawset(_G, deprecated_global_name, {}) + setmetatable(_G[deprecated_global_name], meta) +end + +-- deprecated(2) -- December 2018 - Deprecation of font_lib +deprecated_global_table('font_lib', 'font_api') diff --git a/font_api/init.lua b/font_api/init.lua index 7fbedf9..80fc98a 100644 --- a/font_api/init.lua +++ b/font_api/init.lua @@ -33,6 +33,4 @@ dofile(font_api.path.."/fontform.lua") if minetest.get_modpath("display_api") then dofile(font_api.path.."/display_api.lua") end - --- Compatibility -font_lib = font_api +dofile(font_api.path.."/deprecation.lua") From 523485df2b38a4b34600b6acef12304bec5e86a9 Mon Sep 17 00:00:00 2001 From: Pierre-Yves Rollo Date: Tue, 11 Dec 2018 11:57:05 +0100 Subject: [PATCH 05/10] Add font_lib to deprecation notice --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index fdfcf28..36cb624 100644 --- a/README.md +++ b/README.md @@ -30,10 +30,10 @@ Extra font mods can be found here: ### December 2018 Following objects are deprecated, shows a warning in log when used: - * `display_modpack_node` group (use `display_api` group instead); * `display_lib_node` group (use `display_api` group instead); * `display_lib` global table (use `display_api` global table instead); +* `font_lib` global table (use `font_api` global table instead); These objects will be removed in the future. From 4604be9a8b76589e0ac24ffaad4b8306d03edbf4 Mon Sep 17 00:00:00 2001 From: Pierre-Yves Rollo Date: Tue, 11 Dec 2018 11:57:54 +0100 Subject: [PATCH 06/10] Updated font_api mod desctiption in headers --- font_api/deprecation.lua | 2 +- font_api/display_api.lua | 3 +-- font_api/fallbacks.lua | 25 ++++++++++++------------- font_api/fontform.lua | 25 ++++++++++++------------- font_api/init.lua | 25 ++++++++++++------------- font_api/registry.lua | 38 ++++++++++++++++++-------------------- 6 files changed, 56 insertions(+), 62 deletions(-) diff --git a/font_api/deprecation.lua b/font_api/deprecation.lua index 5c0bed6..b764d82 100644 --- a/font_api/deprecation.lua +++ b/font_api/deprecation.lua @@ -1,5 +1,5 @@ --[[ - font_api mod for Minetest - Library to create textures with fonts and text + font_api mod for Minetest - Library creating textures with fonts and text (c) Pierre-Yves Rollo This program is free software: you can redistribute it and/or modify diff --git a/font_api/display_api.lua b/font_api/display_api.lua index 2191dba..51a396d 100644 --- a/font_api/display_api.lua +++ b/font_api/display_api.lua @@ -1,5 +1,5 @@ --[[ - font_api mod for Minetest - Library to create textures with fonts and text + font_api mod for Minetest - Library creating textures with fonts and text (c) Pierre-Yves Rollo This program is free software: you can redistribute it and/or modify @@ -15,7 +15,6 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . --]] - -- Integration with display API if minetest.get_modpath("display_api") then diff --git a/font_api/fallbacks.lua b/font_api/fallbacks.lua index 480d865..da3ff03 100644 --- a/font_api/fallbacks.lua +++ b/font_api/fallbacks.lua @@ -1,20 +1,19 @@ --[[ - font_api mod for Minetest - Library to add font display capability - to display_api mod. - (c) Pierre-Yves Rollo + font_api mod for Minetest - Library creating 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 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. + 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 . + You should have received a copy of the GNU General Public License + along with this program. If not, see . --]] -- This is the unicode char fallback map. If a char is not present in diff --git a/font_api/fontform.lua b/font_api/fontform.lua index e4952ed..b7e6724 100644 --- a/font_api/fontform.lua +++ b/font_api/fontform.lua @@ -1,20 +1,19 @@ --[[ - font_api mod for Minetest - Library to add font display capability - to display_api mod. - (c) Pierre-Yves Rollo + font_api mod for Minetest - Library creating 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 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. + 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 . + You should have received a copy of the GNU General Public License + along with this program. If not, see . --]] local modname = minetest.get_current_modname() diff --git a/font_api/init.lua b/font_api/init.lua index 80fc98a..c5858f4 100644 --- a/font_api/init.lua +++ b/font_api/init.lua @@ -1,20 +1,19 @@ --[[ - font_api mod for Minetest - Library to add font display capability - to display_api mod. - (c) Pierre-Yves Rollo + font_api mod for Minetest - Library creating 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 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. + 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 . + You should have received a copy of the GNU General Public License + along with this program. If not, see . --]] -- Global variables diff --git a/font_api/registry.lua b/font_api/registry.lua index 4b49b1e..e183675 100644 --- a/font_api/registry.lua +++ b/font_api/registry.lua @@ -1,20 +1,19 @@ --[[ - font_api mod for Minetest - Library to add font display capability - to display_api mod. - (c) Pierre-Yves Rollo + font_api mod for Minetest - Library creating 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 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. + 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 . + You should have received a copy of the GNU General Public License + along with this program. If not, see . --]] -- Global variables @@ -124,9 +123,9 @@ end -- @param def font definition. A associative array with following keys : -- @key default True (by default) if this font may be used as default font -- @key height (mandatory) Height in pixels of all font textures --- @key widths (mandatory) Array of character widths in pixels, indexed by +-- @key widths (mandatory) Array of character widths in pixels, indexed by -- UTF codepoints --- @key margintop (optional) Margin (in texture pixels) added on top of each +-- @key margintop (optional) Margin (in texture pixels) added on top of each -- char texture. -- @key marginbottom (optional) dded at bottom of each char texture. -- @key linespacing (optional) Spacing (in texture pixels) between each lines. @@ -144,19 +143,18 @@ function font_api.register_font(font_name, font_def) local font = font_api.Font:new(font_def) - if font == nil then + if font == nil then minetest.log("error", "Unable to register font \""..font_name.."\".") return end - + font.name = font_name font_api.registered_fonts[font_name] = font font_api.registered_fonts_number = font_api.registered_fonts_number + 1 - + -- Force to choose again default font -- (allows use of fonts registered after start) default_font = false - + minetest.log("action", "New font registered in font_api: "..font_name..".") end - From e75d6bc5753ff1c395491d2f657a8b5b33d3d4b2 Mon Sep 17 00:00:00 2001 From: Pierre-Yves Rollo Date: Tue, 11 Dec 2018 12:00:32 +0100 Subject: [PATCH 07/10] Updated font_api mod desctiption in headers --- font_api/font.lua | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/font_api/font.lua b/font_api/font.lua index 2304cd9..5794867 100644 --- a/font_api/font.lua +++ b/font_api/font.lua @@ -1,20 +1,19 @@ --[[ - font_api mod for Minetest - Library to add font display capability - to display_api mod. - (c) Pierre-Yves Rollo + font_api mod for Minetest - Library creating 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 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. + 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 . + You should have received a copy of the GNU General Public License + along with this program. If not, see . --]] -- Fallback table From c9329d378976ee0fea0bd3486befcd3a1af551c1 Mon Sep 17 00:00:00 2001 From: Pierre-Yves Rollo Date: Tue, 11 Dec 2018 14:57:42 +0100 Subject: [PATCH 08/10] Added display entity yaw attribute --- display_api/display.lua | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/display_api/display.lua b/display_api/display.lua index a8cee66..3cc52b7 100644 --- a/display_api/display.lua +++ b/display_api/display.lua @@ -106,13 +106,12 @@ local function place_entities(pos) y = pos.y - top, z = pos.z - values.dz * depth + values.rz * right}) - objrefs[entity_name]:setyaw(values.yaw) + objrefs[entity_name]:setyaw(values.yaw + (props.yaw or 0)) end end return objrefs end - --- Entity update function update_entity(entity) if not entity then From fc40e54ed2227f29b4b4ddd4b42aafea2e47a791 Mon Sep 17 00:00:00 2001 From: Pierre-Yves Rollo Date: Tue, 11 Dec 2018 14:58:11 +0100 Subject: [PATCH 09/10] Update API documentation --- display_api/API.md | 35 +++++++++++++++++------------------ font_api/API.md | 14 +++++++++++--- 2 files changed, 28 insertions(+), 21 deletions(-) diff --git a/display_api/API.md b/display_api/API.md index b214585..e69ae60 100644 --- a/display_api/API.md +++ b/display_api/API.md @@ -1,38 +1,38 @@ -# Display Lib API -This document describes Display Lib API. Display Lib allows to add a dynamic display on a node. Display Lib limits node rotations. For wallmounted, only vertical positionning is available, and for facedir, only first four position are availabel (those with default axis). +# Display API +This document describes Display API. Display API allows to add a dynamic display on a node. Display API limits node rotations. For wallmounted, only vertical positionning is available. For facedir, only first four position are availabel (those with default axis). ## Provided methods ### update\_entities -**display\_lib.update\_entities(pos)** +**display\_api.update\_entities(pos)** This method triggers entities update for the display node at pos. Actual entity update is made by `on_display_update` callback associated to the entity. `pos`: Position of the node ### register\_display\_entity -**display\_lib.register\_display\_entity(entity_name)** +**display\_api.register\_display\_entity(entity_name)** This is a helper to register entities used for display. `entity_name`: Name of the entity to register. ## Provided callback implementations ### on_place -**display\_lib.on\_place(itemstack, placer, pointed\_thing)** +**display\_api.on\_place(itemstack, placer, pointed\_thing)** `on_place` node callback implementation. Display nodes should have this callback (avoid placement of horizontal display node). ### on_construct -**display\_lib.on\_construct(pos)** +**display\_api.on\_construct(pos)** `on_construct` node callback implementation. Display nodes should have this callback (creates, places and updates display entities on node construction). ### on_destruct -**display\_lib.on_destruct(pos)** +**display\_api.on_destruct(pos)** `on_destruct` node callback implementation. Display nodes should have this callback (removes display entities on node destruction). ### on_rotate -**display\_lib.on\_rotate(pos, node, user, mode, new_param2)** +**display\_api.on\_rotate(pos, node, user, mode, new_param2)** `on_rotate` node callback implementation. Display nodes should have this callback (restricts rotations and rotates display entities associated with node). ### on_activate -**display\_lib.on_activate(entity, staticdata)** +**display\_api.on_activate(entity, staticdata)** `On_activate` entity callback implementation for display entities. No need of this method if display entities have been registered using `register_display_entity` (callback is already set). @@ -40,17 +40,16 @@ This is a helper to register entities used for display. * Register display entities with `register_display_entity` * Register node with : - - `on_place`, `on_construct`, `on_destruct` and `on_rotate` callbacks using display_api callbacks. - - `display_api` group. This will make this node have their entities updated as soon as the mapblock is loaded (Useful after /clearobjects). - - a `display_entities` field in node definition containing a entity name indexed table. See below for description of each display_entities fields. + - `on_place`, `on_construct`, `on_destruct` and `on_rotate` callbacks using display_api callbacks.\ + - `display_api` group. This will make this node have their entities updated as soon as the mapblock is loaded (Useful after /clearobjects).\ + - a `display_entities` field in node definition containing a entity name indexed table. See below for description of each display_entities fields.\ ### Display_entities fields -`on_display_update` is a callback in charge of setting up entity texture. If not set, entity will have no texture and will be displayed as unknown item. - -`depth`, `right` and `height`: Entity position regarding to node facedir/wallmounted main axis. -Values for these fields can be any number between -1.5 and 1.5 (default value is 0). -Position 0,0,0 is the center of the node. -`depth` goes from front (-0.5) to rear (0.5), `height` goes from bottom (-0.5) to top (0.5) and `right` goes from left (-0.5) to right (0.5). +`on_display_update` is a callback in charge of setting up entity texture. If not set, entity will have no texture and will be displayed as unknown item.\ +`depth`, `right` and `height`: Entity position regarding to node facedir/wallmounted main axis.\ +Values for these fields can be any number between -1.5 and 1.5 (default value is 0). Position 0,0,0 is the center of the node.\ +`depth` goes from front (-0.5) to rear (0.5), `height` goes from bottom (-0.5) to top (0.5) and `right` goes from left (-0.5) to right (0.5).\ +`yaw`: Entity yaw in radians, regarding to main axis. Default is 0, aligned to node face. In order to avoid flickering text, it's better to have text a little behind node surface. A good spacing value is given by `display_api.entity_spacing` variable. diff --git a/font_api/API.md b/font_api/API.md index f3f4437..80b1121 100644 --- a/font_api/API.md +++ b/font_api/API.md @@ -1,5 +1,5 @@ -# Font Lib API -This document describes Font Lib API. Font Lib creates textures for font display on entities. +# Font API +This document describes Font API. Font API creates textures for font display on entities. ## Settings ### default_font @@ -97,7 +97,7 @@ 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. -### Font definition table +## Font definition table Font definition table used by **font_api.register_font** and **font\_api.Font:new** may/can contain following elements: * `height` (required): Font height in pixels (all font textures should have the same height) . @@ -108,6 +108,14 @@ Font definition table used by **font_api.register_font** and **font\_api.Font:ne `margintop`, `marginbottom` and `linespacing` can be negative numbers (default 0) and are to be used to adjust various font styles to each other. +Font attributes around a single char:\ +![Font attributes on a char](doc/font.svg) + +Font attributes effects on several lines:\ +![Font attributes on lines](doc/lines.svg) + +#### Additional requirements + Font must have a char 0 which will be used to display any unknown char. All textures corresponding to the indexes in widths array should be present in textures directory with a name matching the pattern : From 9194904b78b89efaf9361e4f02220c3deec476aa Mon Sep 17 00:00:00 2001 From: Pierre-Yves Rollo Date: Fri, 14 Dec 2018 11:13:24 +0100 Subject: [PATCH 10/10] Update README.md --- README.md | 44 +++++++++----------------------------------- 1 file changed, 9 insertions(+), 35 deletions(-) diff --git a/README.md b/README.md index 36cb624..253d2bd 100644 --- a/README.md +++ b/README.md @@ -39,95 +39,69 @@ These objects will be removed in the future. ## Changelog -### 2018-12-02 (Version 1.2.2) +### 2018-12-14 (Version 1.2.3) +- __display_api__: New `yaw` attributes, entities can now have different angles with node. +- __font_api__: New `Font:render` method for texture creation +- __font_api__: Specific management for fixed width font. Allows number of columns based texture width. +- __font_api__: Improve `display_api` integration into `font_api`. Display API fully optional. `font_api.on_display_update` defined only if `display_api` enabled. +- __font_api__: Improve management of invalid UTF strings (should not crash anymore) +- __font_api__: Deprecation of `font_lib` +- __signs__: Fixed craft recipe for labels +### 2018-12-02 (Version 1.2.2) - Fixed a bug that prevented Display API from working on some systems (Raspberry Pi) ### 2018-11-01 (Version 1.2.1) - - Now font can be chosen per sign / stele ### 2018-11-01 (Version 1.2) - - Labels and woodend signs added. - - Fallback mechanism for missing chars (For example: "é" --> "e" --> "E"). - - Several bug fixes by 12Me21 and naturefreshmilk. ### 2018-07-16 (Version 1.1.1) - - Boards mod added. - - Bug fix in default font chosing when multiple font registered. ### 2018-07-13 (Version 1.1.0) - - Font API rework introducing Font class. - - Replaced default Epilepsy Font by Metro Font for licensing purposes, - - Rework of all nodes displaying text accordingly to the Font API rework. As font_epilepsy mod has been replaced by font_metro mod, **don't forget to activate font_metro mod after updating** or you won't have any text displayed. ### 2018-05-30 (Version 1.0.1) - Mostly bug fixes : - - Fix steles orientation when placing - - Update entity on mapblock load - - Use default formspec style - - Fix ndef nill value in steles mod when technics not installed - - Seperate signs API from signs définitions - - Allow a greater offset between display and block ### 2018-01-13 (Version 1.0) - - Switch to Epilepsy font by KREATIVE SOFTWARE - - Add settings "default_font" - - Add horizontal alignment - - Add tool for creating font textures from .ttf font files - - Fix UTF 8 to Unicode decoding - - Updated forum thread link in README.md ### 2017-12-19 - This change is a preparation to merge Andrzej Pieńkowski fork (apienk) : new font and support of UTF chars. - - Font\_lib support for multiple fonts (nothing yet visible in mods) ; - - Font\_lib support for Unicode characters (limited to Unicode Plane 0: 0000-FFFF, see [Wikipedia](https://en.wikipedia.org/wiki/Unicode)) ; - - New "default" font with original textures from Vanessa Ezekowitz (VanessaE) ; ### 2017-12-10 - - Compatibility of signs mod with signs_lib (thanks to gpcf) ; - - Added large banner in road signs (thanks to gpcf) ; ### 2017-08-26 - - Changed signs from wallmounted to facedir to improve textures and make it possible to use screwdriver. **IMPORTANT** : Map will be updated to change to new nodes but inventory items will turn into "Unknown items" and have to be re-crafted. - - Intllib support added with french translation (whole modpack, thanks to fat115) ; - - Punch on nodes to update entity (signs, signs_road and steles). Usefull in case of /clearobjects ; - - Changed wooden direction sign textures (signs) ; - - Added back and side textures to all signs (road_signs) ; - - Added more sign types : White/yellow/green signs and direction signs (signs_road) ;