From 8c7557e45d4744fe35ad058950062cf771640126 Mon Sep 17 00:00:00 2001 From: Pierre-Yves Rollo Date: Fri, 13 Jul 2018 20:41:53 +0200 Subject: [PATCH] Rework all nodes displaying text according to new font_api --- display_api/init.lua | 6 +- font_api/font.lua | 16 ++-- font_api/init.lua | 12 ++- signs/nodes.lua | 12 ++- signs_api/common.lua | 188 ----------------------------------------- signs_api/init.lua | 194 ++++++++++++++++++++++++++++++++++++++++++- signs_road/nodes.lua | 26 +++--- steles/nodes.lua | 13 +-- 8 files changed, 233 insertions(+), 234 deletions(-) delete mode 100644 signs_api/common.lua diff --git a/display_api/init.lua b/display_api/init.lua index 240ce21..2cd15a0 100644 --- a/display_api/init.lua +++ b/display_api/init.lua @@ -128,15 +128,15 @@ local function place_entities(pos) for entity_name, props in pairs(ndef.display_entities) do local depth = clip_pos_prop(props.depth) - local height = clip_pos_prop(props.height) local right = clip_pos_prop(props.right) + local top = clip_pos_prop(props.top) if not objrefs[entity_name] then objrefs[entity_name] = minetest.add_entity(pos, entity_name) end objrefs[entity_name]:setpos({ x = pos.x - values.dx * depth + values.rx * right, - y = pos.y + height, + y = pos.y - top, z = pos.z - values.dz * depth + values.rz * right}) objrefs[entity_name]:setyaw(values.yaw) @@ -268,4 +268,4 @@ minetest.register_lbm({ }) -- Compatibility -display_lib = display_api \ No newline at end of file +display_lib = display_api diff --git a/font_api/font.lua b/font_api/font.lua index 6c848f6..4619e7a 100644 --- a/font_api/font.lua +++ b/font_api/font.lua @@ -17,11 +17,6 @@ along with this program. If not, see . --]] - ---[[ - Margins, spacings, can be negative numbers -]]-- - -- Local functions ------------------ @@ -146,10 +141,10 @@ function font_api.Font:get_height(nb_of_lines) return ( (self.height or 0) + - (self.margin_top or 0) + - (self.margin_bottom or 0) + (self.margintop or 0) + + (self.marginbottom or 0) ) * nb_of_lines + - (self.line_spacing or 0) * (nb_of_lines -1) + (self.linespacing or 0) * (nb_of_lines -1) else return nb_of_lines == 0 and 0 or nil end @@ -192,6 +187,7 @@ function font_api.Font:make_line_texture(line, texturew, x, y) -- Replace chars with no texture by the NULL(0) char if self.widths[char] == nil +or char == 88 then print(string.format("["..font_api.name .."] Missing char %d (%04x)",char,char)) @@ -243,6 +239,8 @@ function font_api.Font:make_text_texture(text, texturew, textureh, maxlines, y = (textureh - textheight) / 2 end end + + y = y + (self.margintop or 0) for _, line in pairs(lines) do if halign == "left" then @@ -259,7 +257,7 @@ function font_api.Font:make_text_texture(text, texturew, textureh, maxlines, (texturew - line.width) / 2, y) end - y = y + self:get_height() + (self.line_spacing or 0) + y = y + self:get_height() + (self.linespacing or 0) end texture = string.format("[combine:%dx%d", texturew, textureh)..texture diff --git a/font_api/init.lua b/font_api/init.lua index 2dc38ec..06619be 100644 --- a/font_api/init.lua +++ b/font_api/init.lua @@ -45,10 +45,14 @@ function font_api.on_display_update(pos, objref) 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") or def.font_name) - objref:set_properties({ - textures={font:make_text_texture(text, - def.size.x * def.resolution.x * font.height, - def.size.y * def.resolution.y * font.height, + + local maxlines = def.maxlines or 1 -- TODO:How to do w/o maxlines ? + + objref:set_properties({ + textures={font:make_text_texture(text, + font:get_height(maxlines) * def.size.x / def.size.y + / (def.aspect_ratio or 1), + font:get_height(maxlines), def.maxlines, def.halign, def.valign, def.color)}, visual_size = def.size }) diff --git a/signs/nodes.lua b/signs/nodes.lua index d635f8f..7e2dbe8 100644 --- a/signs/nodes.lua +++ b/signs/nodes.lua @@ -30,12 +30,12 @@ local function display_poster(pos, node, player) -- Title texture local titletexture = font:make_text_texture( - meta:get_string("display_text"), 116, 12, 1, "center") + meta:get_string("display_text"), font:get_height()*8.4, font:get_height(), 1, "center") formspec = "size[7,9]".. "background[0,0;7,9;signs_poster_formspec.png]".. - "image[0,0;8.4,1.5;"..titletexture.."]".. + "image[0,-0.2;8.4,2;"..titletexture.."]".. "textarea[0.3,1.5;7,8;;"..minetest.colorize("#111", minetest.formspec_escape(meta:get_string("text")))..";]".. "bgcolor[#0000]" @@ -105,7 +105,6 @@ local models = { entity_fields = { right = -3/32, size = { x = 12/16, y = 6/16 }, - resolution = { x = 9, y = 5 }, maxlines = 2, color="#000", }, @@ -128,7 +127,6 @@ local models = { entity_fields = { right = 3/32, size = { x = 12/16, y = 6/16 }, - resolution = { x = 9, y = 5 }, maxlines = 2, color = "#000", }, @@ -150,10 +148,10 @@ local models = { width = 26/32, height = 30/32, entity_fields = { - resolution = { x = 11, y = 5 }, + top = -11/32, + size = { x = 26/32, y = 6/32 }, maxlines = 1, - color="#000", - valign="top", + color = "#000", }, node_fields = { description = S("Poster"), diff --git a/signs_api/common.lua b/signs_api/common.lua deleted file mode 100644 index 2528ff5..0000000 --- a/signs_api/common.lua +++ /dev/null @@ -1,188 +0,0 @@ ---[[ - signs mod for Minetest - Various signs with text displayed on - (c) Pierre-Yves Rollo - - This file is part of signs. - - signs 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. - - signs 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 signs. If not, see . ---]] - -local S = signs_api.intllib -local F = function(...) return minetest.formspec_escape(S(...)) end - -function signs_api.set_display_text(pos,text) - local meta = minetest.get_meta(pos) - meta:set_string("display_text", text) - meta:set_string("infotext", "\""..text.."\"") - display_api.update_entities(pos) -end - -function signs_api.set_formspec(pos) - local meta = minetest.get_meta(pos) - local ndef = minetest.registered_nodes[minetest.get_node(pos).name] - if ndef and ndef.display_entities and ndef.display_entities["signs:display_text"] then - local maxlines = ndef.display_entities["signs:display_text"].maxlines - local formspec - - if maxlines == 1 then - formspec = "size[6,3]".. - default.gui_bg .. default.gui_bg_img .. default.gui_slots .. - "field[0.5,0.7;5.5,1;display_text;"..F("Text")..";${display_text}]".. - "button_exit[2,2;2,1;ok;"..F("Write").."]" - else - local extralabel = "" - if maxlines then - extralabel = F(" (first %s lines only)"):format(maxlines) - end - - formspec = "size[6,4]".. - default.gui_bg .. default.gui_bg_img .. default.gui_slots .. - "textarea[0.5,0.7;5.5,2;display_text;"..F("Text")..""..extralabel..";${display_text}]".. - "button_exit[2,3;2,1;ok;"..F("Write").."]" - end - - meta:set_string("formspec", formspec) - end -end - -function signs_api.on_receive_fields(pos, formname, fields, player) - if not minetest.is_protected(pos, player:get_player_name()) then - if fields and (fields.ok or fields.key_enter) then - signs_api.set_display_text(pos, fields.display_text) - end - end -end - --- On place callback for direction signs --- (chooses which sign according to look direction) -function signs_api.on_place_direction(itemstack, placer, pointed_thing) - local name = itemstack:get_name() - local ndef = minetest.registered_nodes[name] - - local bdir = {x = pointed_thing.under.x - pointed_thing.above.x, - y = pointed_thing.under.y - pointed_thing.above.y, - z = pointed_thing.under.z - pointed_thing.above.z} - local pdir = placer:get_look_dir() - - local ndir, test - - if ndef.paramtype2 == "facedir" then - if bdir.x == 0 and bdir.z == 0 then - -- Ceiling or floor pointed (facedir chosen from player dir) - ndir = minetest.dir_to_facedir({x=pdir.x, y=0, z=pdir.z}) - else - -- Wall pointed - ndir = minetest.dir_to_facedir(bdir) - end - - test = {[0]=-pdir.x, pdir.z, pdir.x, -pdir.z} - end - - if ndef.paramtype2 == "wallmounted" then - ndir = minetest.dir_to_wallmounted(bdir) - if ndir == 0 or ndir == 1 then - -- Ceiling or floor - ndir = minetest.dir_to_wallmounted({x=pdir.x, y=0, z=pdir.z}) - end - - test = {0, pdir.z, -pdir.z, -pdir.x, pdir.x} - end - - -- Only for direction signs - if ndef.signs_other_dir then - if test[ndir] > 0 then - itemstack:set_name(ndef.signs_other_dir) - end - itemstack = minetest.item_place(itemstack, placer, pointed_thing, ndir) - itemstack:set_name(name) - - return itemstack - else - return minetest.item_place(itemstack, placer, pointed_thing, ndir) - end -end - --- Handles screwdriver rotation. Direction is affected for direction signs -function signs_api.on_rotate(pos, node, player, mode, new_param2) - if mode == 2 then - local ndef = minetest.registered_nodes[node.name] - if ndef.signs_other_dir then - minetest.swap_node(pos, {name = ndef.signs_other_dir, - param1 = node.param1, param2 = node.param2}) - display_api.update_entities(pos) - end - else - display_api.on_rotate(pos, node, user, mode, new_param2) - end - return false; -end - -function signs_api.register_sign(mod, name, model) - -- Default fields - local fields = { - sunlight_propagates = true, - paramtype = "light", - paramtype2 = "facedir", - drawtype = "nodebox", - node_box = { - type = "fixed", - fixed = {-model.width/2, -model.height/2, 0.5, - model.width/2, model.height/2, 0.5 - model.depth}, - }, - groups = {choppy=2, dig_immediate=2, not_blocking_trains = 1, display_modpack_node = 1}, - sounds = default.node_sound_defaults(), - display_entities = { - ["signs:display_text"] = { - on_display_update = font_api.on_display_update, - depth = 0.5 - display_api.entity_spacing - model.depth, - size = { x = model.width, y = model.height }, - resolution = { x = 64, y = 64 }, - maxlines = 1, - }, - - }, - on_place = display_api.on_place, - on_construct = function(pos) - signs_api.set_formspec(pos) - display_api.on_construct(pos) - end, - on_destruct = display_api.on_destruct, - on_rotate = signs_api.on_rotate, - on_receive_fields = signs_api.on_receive_fields, - on_punch = function(pos, node, player, pointed_thing) display_api.update_entities(pos) end, - } - - -- Node fields override - for key, value in pairs(model.node_fields) do - if key == "groups" then - for key2, value2 in pairs(value) do - fields[key][key2] = value2 - end - else - fields[key] = value - end - end - - if not fields.wield_image then fields.wield_image = fields.inventory_image end - - -- Entity fields override - for key, value in pairs(model.entity_fields) do - fields.display_entities["signs:display_text"][key] = value - end - - minetest.register_node(mod..":"..name, fields) -end - --- Text entity for all signs -display_api.register_display_entity("signs:display_text") diff --git a/signs_api/init.lua b/signs_api/init.lua index c13a253..e8a2b2b 100644 --- a/signs_api/init.lua +++ b/signs_api/init.lua @@ -25,8 +25,200 @@ signs_api.path = minetest.get_modpath(signs_api.name) -- Load support for intllib. local S, NS = dofile(signs_api.path.."/intllib.lua") signs_api.intllib = S +local F = function(...) return minetest.formspec_escape(S(...)) end -dofile(signs_api.path.."/common.lua") +local function update_font_index_meta(meta) + local font = meta:get_string("font") + local count = 0 + for key, def in pairs(font_api.registered_fonts) do + count = count + 1 + if font == key then + meta:set_string("font_idx", count) + end + end +end + +function signs_api.set_display_text(pos,text,font) + local meta = minetest.get_meta(pos) + meta:set_string("display_text", text) + meta:set_string("infotext", "\""..text.."\"") + meta:set_string("font", font) + update_font_index_meta(meta) + display_api.update_entities(pos) +end + +function signs_api.set_formspec(pos) + local meta = minetest.get_meta(pos) + local ndef = minetest.registered_nodes[minetest.get_node(pos).name] + if ndef and ndef.display_entities + and ndef.display_entities["signs:display_text"] then + local maxlines = ndef.display_entities["signs:display_text"].maxlines + local formspec, formheight + + if maxlines == 1 then + formspec = + "field[0.5,0.7;5.5,1;display_text;"..F("Text").. + ";${display_text}]" + formheight = 2 + else + local extralabel = "" + if maxlines then + extralabel = F(" (first %s lines only)"):format(maxlines) + end + + formspec = + "textarea[0.5,0.7;5.5,2;display_text;"..F("Text").."".. + extralabel..";${display_text}]" + formheight = 3 + end + + formspec = formspec.."button_exit[2,"..formheight..";2,1;ok;".. + F("Write").."]" + formheight = formheight + 1 + formspec = "size[6,"..formheight.."]"..default.gui_bg.. + default.gui_bg_img..default.gui_slots..formspec + + meta:set_string("formspec", formspec) + end +end + +function signs_api.on_receive_fields(pos, formname, fields, player) + if not minetest.is_protected(pos, player:get_player_name()) then + if fields and (fields.ok or fields.key_enter) then + signs_api.set_display_text(pos, fields.display_text, fields.font) + end + end +end + +-- On place callback for direction signs +-- (chooses which sign according to look direction) +function signs_api.on_place_direction(itemstack, placer, pointed_thing) + local name = itemstack:get_name() + local ndef = minetest.registered_nodes[name] + + local bdir = {x = pointed_thing.under.x - pointed_thing.above.x, + y = pointed_thing.under.y - pointed_thing.above.y, + z = pointed_thing.under.z - pointed_thing.above.z} + local pdir = placer:get_look_dir() + + local ndir, test + + if ndef.paramtype2 == "facedir" then + if bdir.x == 0 and bdir.z == 0 then + -- Ceiling or floor pointed (facedir chosen from player dir) + ndir = minetest.dir_to_facedir({x=pdir.x, y=0, z=pdir.z}) + else + -- Wall pointed + ndir = minetest.dir_to_facedir(bdir) + end + + test = {[0]=-pdir.x, pdir.z, pdir.x, -pdir.z} + end + + if ndef.paramtype2 == "wallmounted" then + ndir = minetest.dir_to_wallmounted(bdir) + if ndir == 0 or ndir == 1 then + -- Ceiling or floor + ndir = minetest.dir_to_wallmounted({x=pdir.x, y=0, z=pdir.z}) + end + + test = {0, pdir.z, -pdir.z, -pdir.x, pdir.x} + end + + -- Only for direction signs + if ndef.signs_other_dir then + if test[ndir] > 0 then + itemstack:set_name(ndef.signs_other_dir) + end + itemstack = minetest.item_place(itemstack, placer, pointed_thing, ndir) + itemstack:set_name(name) + + return itemstack + else + return minetest.item_place(itemstack, placer, pointed_thing, ndir) + end +end + +-- Handles screwdriver rotation. Direction is affected for direction signs +function signs_api.on_rotate(pos, node, player, mode, new_param2) + if mode == 2 then + local ndef = minetest.registered_nodes[node.name] + if ndef.signs_other_dir then + minetest.swap_node(pos, {name = ndef.signs_other_dir, + param1 = node.param1, param2 = node.param2}) + display_api.update_entities(pos) + end + else + display_api.on_rotate(pos, node, user, mode, new_param2) + end + return false; +end + +function signs_api.register_sign(mod, name, model) + -- Default fields + local fields = { + sunlight_propagates = true, + paramtype = "light", + paramtype2 = "facedir", + drawtype = "nodebox", + node_box = { + type = "fixed", + fixed = {-model.width/2, -model.height/2, 0.5, + model.width/2, model.height/2, 0.5 - model.depth}, + }, + groups = {choppy=2, dig_immediate=2, not_blocking_trains = 1, display_modpack_node = 1}, + sounds = default.node_sound_defaults(), + display_entities = { + ["signs:display_text"] = { + on_display_update = font_api.on_display_update, + depth = 0.5 - display_api.entity_spacing - model.depth, + size = { x = model.width, y = model.height }, + aspect_ratio = 1/2, + maxlines = 1, + }, + + }, + on_place = display_api.on_place, + on_construct = function(pos) + local ndef = minetest.registered_nodes[minetest.get_node(pos).name] + local meta = minetest.get_meta(pos) + meta:set_string("font", ndef.display_entities.font_name or + font_api.get_default_font_name()) + update_font_index_meta(meta) + signs_api.set_formspec(pos) + display_api.on_construct(pos) + end, + on_destruct = display_api.on_destruct, + on_rotate = signs_api.on_rotate, + on_receive_fields = signs_api.on_receive_fields, + on_punch = function(pos, node, player, pointed_thing) + display_api.update_entities(pos) + end, + } + + -- Node fields override + for key, value in pairs(model.node_fields) do + if key == "groups" then + for key2, value2 in pairs(value) do + fields[key][key2] = value2 + end + else + fields[key] = value + end + end + + if not fields.wield_image then fields.wield_image = fields.inventory_image end + + -- Entity fields override + for key, value in pairs(model.entity_fields) do + fields.display_entities["signs:display_text"][key] = value + end + + minetest.register_node(mod..":"..name, fields) +end + +-- Text entity for all signs +display_api.register_display_entity("signs:display_text") diff --git a/signs_road/nodes.lua b/signs_road/nodes.lua index c4c0b04..ab95b2b 100644 --- a/signs_road/nodes.lua +++ b/signs_road/nodes.lua @@ -27,7 +27,7 @@ local models = { width = 14/16, height = 12/16, entity_fields = { - resolution = { x = 11, y = 5.5 }, + size = { x = 14/16, y = 10/16 }, maxlines = 3, color = "#fff", }, @@ -44,7 +44,6 @@ local models = { width = 64/16, height = 12/16, entity_fields = { - resolution = { x = 2.5, y = 1.5 }, maxlines = 1, color = "#000", }, @@ -57,13 +56,12 @@ local models = { inventory_image = "signs_road_white.png", }, }, - red_street_sign = { depth = 1/16, width = 1, height = 7/16, entity_fields = { - resolution = { x = 8, y = 4 }, + size = { x = 1, y = 4/16 }, maxlines = 1, color = "#000", }, @@ -80,7 +78,7 @@ local models = { width = 1, height = 7/16, entity_fields = { - resolution = { x = 9, y = 5.5 }, + size = { x = 1, y = 6/16 }, maxlines = 2, color = "#000", }, @@ -97,7 +95,7 @@ local models = { width = 1, height = 7/16, entity_fields = { - resolution = { x = 9, y = 5.5 }, + size = { x = 1, y = 6/16 }, maxlines = 2, color = "#fff", }, @@ -114,7 +112,7 @@ local models = { width = 1, height = 7/16, entity_fields = { - resolution = { x = 9, y = 5.5 }, + size = { x = 1, y = 6/16 }, maxlines = 2, color = "#000", }, @@ -131,7 +129,8 @@ local models = { width = 1, height = 0.5, entity_fields = { - resolution = { x = 7, y = 5 }, + aspect_ratio = 3/4, + size = { x = 1, y = 3/16 }, maxlines = 1, color = "#000", }, @@ -151,7 +150,8 @@ local models = { width = 1, height = 0.5, entity_fields = { - resolution = { x = 7, y = 5 }, + aspect_ratio = 3/4, + size = { x = 1, y = 3/16 }, maxlines = 1, color = "#000", }, @@ -176,7 +176,6 @@ local models = { entity_fields = { right = -3/32, size = { x = 12/16, y = 6/16 }, - resolution = { x = 9, y = 5.5 }, maxlines = 2, color = "#fff", }, @@ -200,7 +199,6 @@ local models = { entity_fields = { right = 3/32, size = { x = 12/16, y = 6/16 }, - resolution = { x = 9, y = 5.5 }, maxlines = 2, color="#fff", }, @@ -226,7 +224,6 @@ local models = { entity_fields = { right = -3/32, size = { x = 12/16, y = 6/16 }, - resolution = { x = 9, y = 5.5 }, maxlines = 2, color = "#000", }, @@ -250,7 +247,6 @@ local models = { entity_fields = { right = 3/32, size = { x = 12/16, y = 6/16 }, - resolution = { x = 9, y = 5.5 }, maxlines = 2, color = "#000", }, @@ -266,7 +262,7 @@ local models = { selection_box = { type = "fixed", fixed = { -7/16, -7/32, 0.5, 0.5, 7/32, 7/16 } }, collision_box = { type = "fixed", fixed = { -7/16, -7/32, 0.5, 0.5, 7/32, 7/16 } }, groups = { not_in_creative_inventory = 1 }, - drop = "signs_road:yellow_left_sign", + drop = "signs_road:yellow_right_sign", }, }, white_right_sign = { @@ -276,7 +272,6 @@ local models = { entity_fields = { right = -3/32, size = { x = 12/16, y = 6/16 }, - resolution = { x = 9, y = 5.5 }, maxlines = 2, color = "#000", }, @@ -300,7 +295,6 @@ local models = { entity_fields = { right = 3/32, size = { x = 12/16, y = 6/16 }, - resolution = { x = 9, y = 5.5 }, maxlines = 2, color = "#000", }, diff --git a/steles/nodes.lua b/steles/nodes.lua index eabb096..9fb65dd 100644 --- a/steles/nodes.lua +++ b/steles/nodes.lua @@ -42,17 +42,18 @@ for i, material in ipairs(steles.materials) do node_box = { type = "fixed", fixed = { - {-5/16, -4/16, -2/16, 5/16, 0.5, 2/16}, - {-7/16, -0.5, -4/16, 7/16, -4/16, 4/16} - } + {-5/16, -5/16, -2/16, 5/16, 0.5, 2/16}, + {-7/16, -0.5, -4/16, 7/16, -5/16, 4/16} + }, }, groups = groups, display_entities = { ["steles:text"] = { on_display_update = font_api.on_display_update, - depth = -2/16 - display_api.entity_spacing, height = 2/16, - size = { x = 14/16, y = 12/16 }, - resolution = { x = 11, y = 5 }, + depth = -2/16 - display_api.entity_spacing, + top = -2/16, + aspect_ratio = 0.4, + size = { x = 10/16, y = 12/16 }, maxlines = 3, }, },