mirror of
https://github.com/pyrollo/display_modpack.git
synced 2025-10-15 16:45:35 +02:00
wip
This commit is contained in:
@@ -58,6 +58,7 @@ end
|
|||||||
--- Font class
|
--- Font class
|
||||||
|
|
||||||
local Font = {}
|
local Font = {}
|
||||||
|
Font.__index = Font
|
||||||
font_api.Font = Font
|
font_api.Font = Font
|
||||||
|
|
||||||
function Font:new(def)
|
function Font:new(def)
|
||||||
@@ -70,31 +71,53 @@ function Font:new(def)
|
|||||||
|
|
||||||
local font = table.copy(def)
|
local font = table.copy(def)
|
||||||
|
|
||||||
if font.height == nil or font.height <= 0 then
|
-- Version 1 is with one texture per glyph
|
||||||
minetest.log("error",
|
if font.version == nil or font.version == 1 then
|
||||||
"[font_api] Font definition must have a positive height.")
|
if font.height == nil or font.height <= 0 then
|
||||||
return nil
|
minetest.log("error",
|
||||||
end
|
"[font_api] Font definition must have a positive height.")
|
||||||
|
return nil
|
||||||
if type(font.widths) == "table" then
|
|
||||||
if type(font.glyphs) == "table" then
|
|
||||||
minetest.log("warning",
|
|
||||||
"[font_api] Ingonring `widths` array in font definition as there is also a `glyphs` array.")
|
|
||||||
else
|
|
||||||
minetest.log("warning",
|
|
||||||
"[font_api] Use of `widths` array in font definition is deprecated, please upgrade to `glyphs`.")
|
|
||||||
font.glyphs = {}
|
|
||||||
for codepoint, width in pairs(font.widths) do
|
|
||||||
font.glyphs[codepoint] = { w = width, c = codepoint }
|
|
||||||
end
|
|
||||||
font.widths = nil
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if type(font.widths) ~= "table" then
|
||||||
|
minetest.log("error",
|
||||||
|
"[font_api] Font definition must have a `widths` array.")
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Kind of convert to version 2
|
||||||
|
|
||||||
|
font.glyphs = {}
|
||||||
|
for codepoint, width in pairs(font.widths) do
|
||||||
|
font.glyphs[codepoint] = { width, codepoint }
|
||||||
|
end
|
||||||
|
font.widths = nil
|
||||||
|
|
||||||
|
font.glyphs_height = font.height
|
||||||
|
font.height = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
if type(font.glyphs) ~= "table" then
|
-- Version 2 is with one only texture for all glyphs, using `[sheet` textures
|
||||||
minetest.log("error",
|
if font.version == 2 then
|
||||||
"[font_api] Font definition must have a `glyphs` array.")
|
if type(font.glyphs) ~= "table" then
|
||||||
return nil
|
minetest.log("error",
|
||||||
|
"[font_api] Font definition must have a `glyphs` array.")
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
if font.texture_height == nil or font.texture_height <= 0 then
|
||||||
|
minetest.log("error",
|
||||||
|
"[font_api] Font definition must have a positive `texture_height`.")
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
if font.glyphs_height == nil or font.glyphs_height <= 0 then
|
||||||
|
minetest.log("error",
|
||||||
|
"[font_api] Font definition must have a positive `glyphs_height`.")
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
font.vertical_number_of_tiles = math.floor(font.texture_height / font.glyphs_height)
|
||||||
end
|
end
|
||||||
|
|
||||||
if font.glyphs[0] == nil then
|
if font.glyphs[0] == nil then
|
||||||
@@ -103,8 +126,7 @@ function Font:new(def)
|
|||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
setmetatable(font, self)
|
setmetatable(font, self)
|
||||||
self.__index = self
|
|
||||||
|
|
||||||
return font
|
return font
|
||||||
end
|
end
|
||||||
@@ -149,7 +171,8 @@ end
|
|||||||
-- @return Char width
|
-- @return Char width
|
||||||
|
|
||||||
function Font:get_char_width(codepoint)
|
function Font:get_char_width(codepoint)
|
||||||
return (self.glyphs[codepoint] or self.glyphs[0]).w
|
-- [1] is char width
|
||||||
|
return (self.glyphs[codepoint] or self.glyphs[0])[1]
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Returns texture for a given glyph
|
--- Returns texture for a given glyph
|
||||||
@@ -157,22 +180,18 @@ end
|
|||||||
-- @return Texture
|
-- @return Texture
|
||||||
|
|
||||||
function Font:get_glyph_texture(glyph)
|
function Font:get_glyph_texture(glyph)
|
||||||
if glyph.c then
|
if #glyph == 4 then
|
||||||
|
-- Actual version with one texture for all glyphs
|
||||||
|
return string.format("font_%s.png^[sheet:%dx%d:%d,%d",
|
||||||
|
self.name, glyph[2], self.vertical_number_of_tiles, glyph[3], glyph[4])
|
||||||
|
end
|
||||||
|
if #glyph == 2 then
|
||||||
-- Former version with one texture per glyph
|
-- Former version with one texture per glyph
|
||||||
return string.format("font_%s_%04x.png",
|
return string.format("font_%s_%04x.png",
|
||||||
self.name, glyph.c)
|
self.name, glyph[2])
|
||||||
end
|
|
||||||
|
|
||||||
if glyph.x == nil or glyph.y == nil then
|
|
||||||
-- Case of invisible chars like space (no need to add any texture)
|
|
||||||
return ""
|
|
||||||
end
|
end
|
||||||
|
-- Case of invisible chars like space (no need to add any texture)
|
||||||
--le 5x15 est le nombre de tuiles, pas la taille des tuiles.
|
return ""
|
||||||
return string.format("font_%s.png^[sheet:40x5:%d,%d",
|
|
||||||
self.name, glyph.x, glyph.y)
|
|
||||||
-- return string.format("font_%s.png^[sheet:%dx%d:%d,%d",
|
|
||||||
-- self.name, glyph.w, self.height, glyph.x, glyph.y)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Text height for multiline text including margins and line spacing
|
--- Text height for multiline text including margins and line spacing
|
||||||
@@ -185,7 +204,7 @@ function Font:get_height(nb_of_lines)
|
|||||||
if nb_of_lines > 0 then
|
if nb_of_lines > 0 then
|
||||||
return
|
return
|
||||||
(
|
(
|
||||||
(self.height or 0) +
|
self.glyphs_height +
|
||||||
(self.margintop or 0) +
|
(self.margintop or 0) +
|
||||||
(self.marginbottom or 0)
|
(self.marginbottom or 0)
|
||||||
) * nb_of_lines +
|
) * nb_of_lines +
|
||||||
@@ -227,8 +246,8 @@ end
|
|||||||
|
|
||||||
--- Render text with the font in a view
|
--- Render text with the font in a view
|
||||||
-- @param text Text to be rendered
|
-- @param text Text to be rendered
|
||||||
-- @param texturew Width (in pixels) of the texture (extra text will be truncated)
|
-- @param width 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 height Height (in pixels) of the texture (extra text will be truncated)
|
||||||
-- @param style Style of the rendering:
|
-- @param style Style of the rendering:
|
||||||
-- - lines: maximum number of text lines (if text is limited)
|
-- - lines: maximum number of text lines (if text is limited)
|
||||||
-- - halign: horizontal align ("left"/"center"/"right")
|
-- - halign: horizontal align ("left"/"center"/"right")
|
||||||
@@ -236,7 +255,7 @@ end
|
|||||||
-- - color: color of the text ("#rrggbb")
|
-- - color: color of the text ("#rrggbb")
|
||||||
-- @return Texture string
|
-- @return Texture string
|
||||||
|
|
||||||
function Font:render(text, texturew, textureh, style)
|
function Font:render(text, width, height, style)
|
||||||
style = style or {}
|
style = style or {}
|
||||||
|
|
||||||
-- Split text into lines (and limit to style.lines # of lines)
|
-- Split text into lines (and limit to style.lines # of lines)
|
||||||
@@ -256,14 +275,14 @@ function Font:render(text, texturew, textureh, style)
|
|||||||
|
|
||||||
local x, y, codepoint
|
local x, y, codepoint
|
||||||
local texture = ""
|
local texture = ""
|
||||||
local textheight = self:get_height(#lines)
|
local text_height = self:get_height(#lines)
|
||||||
|
|
||||||
if style.valign == "top" then
|
if style.valign == "top" then
|
||||||
y = 0
|
y = 0
|
||||||
elseif style.valign == "bottom" then
|
elseif style.valign == "bottom" then
|
||||||
y = textureh - textheight
|
y = height - text_height
|
||||||
else
|
else
|
||||||
y = (textureh - textheight) / 2
|
y = (height - text_height) / 2
|
||||||
end
|
end
|
||||||
|
|
||||||
y = y + (self.margintop or 0)
|
y = y + (self.margintop or 0)
|
||||||
@@ -272,9 +291,9 @@ function Font:render(text, texturew, textureh, style)
|
|||||||
if style.halign == "left" then
|
if style.halign == "left" then
|
||||||
x = 0
|
x = 0
|
||||||
elseif style.halign == "right" then
|
elseif style.halign == "right" then
|
||||||
x = texturew - l.width
|
x = width - l.width
|
||||||
else
|
else
|
||||||
x = (texturew - l.width) / 2
|
x = (width - l.width) / 2
|
||||||
end
|
end
|
||||||
|
|
||||||
while l.text ~= '' do
|
while l.text ~= '' do
|
||||||
@@ -284,17 +303,19 @@ function Font:render(text, texturew, textureh, style)
|
|||||||
local glyph = self.glyphs[codepoint]
|
local glyph = self.glyphs[codepoint]
|
||||||
|
|
||||||
-- Add image only if it is visible (at least partly)
|
-- Add image only if it is visible (at least partly)
|
||||||
if x + glyph.w >= 0 and x <= texturew then
|
if x + glyph[1] >= 0 and x <= width then
|
||||||
texture = string.format("%s:%d,%d=%s",
|
local glyph_texture = self:get_glyph_texture(glyph):gsub("[\\^:]", "\\%0")
|
||||||
texture, x, y, self:get_glyph_texture(glyph):gsub("[\\^:]", "\\%0"))
|
if glyph_texture ~= '' then
|
||||||
|
texture = string.format("%s:%d,%d=%s", texture, x, y, glyph_texture)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
x = x + glyph.w
|
x = x + glyph[1]
|
||||||
end
|
end
|
||||||
|
|
||||||
y = y + self:get_height() + (self.linespacing or 0)
|
y = y + self:get_height() + (self.linespacing or 0)
|
||||||
end
|
end
|
||||||
|
|
||||||
texture = string.format("[combine:%dx%d%s", texturew, textureh, texture)
|
texture = string.format("[combine:%dx%d%s", width, height, texture)
|
||||||
if style.color then
|
if style.color then
|
||||||
texture = texture.."^[colorize:"..style.color
|
texture = texture.."^[colorize:"..style.color
|
||||||
end
|
end
|
||||||
|
@@ -103,11 +103,17 @@ local function show_font_formspec(playername)
|
|||||||
|
|
||||||
for line = 1, #fonts do
|
for line = 1, #fonts do
|
||||||
local font = font_api.get_font(fonts[line])
|
local font = font_api.get_font(fonts[line])
|
||||||
local texture = font:make_text_texture(font.name, font:get_height()*5,
|
local texture = font:render(font.name,
|
||||||
font:get_height()*1.2, 1, "center", "top", "#fff")
|
font:get_height()*5, font:get_height()*1.2, {
|
||||||
|
lines = 1,
|
||||||
|
valign = "middle",
|
||||||
|
halign = "center",
|
||||||
|
color = "#fff"
|
||||||
|
}
|
||||||
|
)
|
||||||
fs = string.format(
|
fs = string.format(
|
||||||
"%simage[0.1,%s;4.5,0.8;%s]button_exit[0,%s;4,1;font_%s;]",
|
"%simage[0.1,%s;4.5,0.8;%s]button_exit[0,%s;4,1;font_%s;]",
|
||||||
fs, line-0.9, texture, line-1, font.name)
|
fs, line - 0.9, texture, line - 1, font.name)
|
||||||
end
|
end
|
||||||
minetest.show_formspec(context.playername, modname..':font_list', fs)
|
minetest.show_formspec(context.playername, modname..':font_list', fs)
|
||||||
end
|
end
|
||||||
|
5
font_api/tools/README.md
Normal file
5
font_api/tools/README.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
# Debian installation
|
||||||
|
|
||||||
|
```shell
|
||||||
|
apt install lua5.4 imagemagick fonttools
|
||||||
|
```
|
@@ -79,8 +79,8 @@ local function compute_tile_sizes(texture_size)
|
|||||||
return results
|
return results
|
||||||
end
|
end
|
||||||
|
|
||||||
-- This will give enough combinations (720 is 2 * 2 * 2 * 2 * 3 * 3 * 5)
|
-- This will give enough combinations (360 is 2 * 2 * 2 * 3 * 3 * 5)
|
||||||
tile_widths = compute_tile_sizes(720)
|
tile_widths = compute_tile_sizes(360)
|
||||||
|
|
||||||
-- Table width has to be sorted
|
-- Table width has to be sorted
|
||||||
table.sort(tile_widths)
|
table.sort(tile_widths)
|
||||||
@@ -177,9 +177,11 @@ local glyph_xs = {} -- x for each glyph
|
|||||||
local glyph_ys = {} -- y for each glyph
|
local glyph_ys = {} -- y for each glyph
|
||||||
local glyph_ns = {} -- n of tiles in sheet for each glyph (=texturewidth / tilewidth)
|
local glyph_ns = {} -- n of tiles in sheet for each glyph (=texturewidth / tilewidth)
|
||||||
|
|
||||||
|
local texture_height
|
||||||
|
|
||||||
local function make_final_texture(filename)
|
local function make_final_texture(filename)
|
||||||
|
|
||||||
local texture_height = font_height
|
texture_height = font_height
|
||||||
|
|
||||||
local x = 0 -- cursor x
|
local x = 0 -- cursor x
|
||||||
local glyph_y = 0
|
local glyph_y = 0
|
||||||
@@ -209,7 +211,6 @@ local function make_final_texture(filename)
|
|||||||
"convert -channel alpha -colorspace gray -size %dx%d xc:transparent %s",
|
"convert -channel alpha -colorspace gray -size %dx%d xc:transparent %s",
|
||||||
texture_width, texture_height, filename
|
texture_width, texture_height, filename
|
||||||
))
|
))
|
||||||
print(texture_width, texture_height)
|
|
||||||
|
|
||||||
for codepoint, n in pairs(glyph_ns) do
|
for codepoint, n in pairs(glyph_ns) do
|
||||||
local w = texture_width // n
|
local w = texture_width // n
|
||||||
@@ -232,11 +233,10 @@ local function make_final_texture(filename)
|
|||||||
end
|
end
|
||||||
-- Place subtexure in texture
|
-- Place subtexure in texture
|
||||||
cmd = string.format("convert %s \\( %s -repage +%d+%d \\) -flatten %s", filename, cmd, x, y, filename)
|
cmd = string.format("convert %s \\( %s -repage +%d+%d \\) -flatten %s", filename, cmd, x, y, filename)
|
||||||
print (cmd)
|
|
||||||
command(cmd)
|
command(cmd)
|
||||||
end
|
end
|
||||||
|
|
||||||
command(string.format("convert %s -threshold 50%% %s", filename, filename))
|
command(string.format("convert %s -channel alpha -threshold 50%% %s", filename, filename))
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -307,22 +307,24 @@ file:write(string.format([[
|
|||||||
font_api.register_font(
|
font_api.register_font(
|
||||||
'%s',
|
'%s',
|
||||||
{
|
{
|
||||||
|
version = 2,
|
||||||
default = true,
|
default = true,
|
||||||
margintop = 3,
|
margintop = 3,
|
||||||
linespacing = -2,
|
linespacing = -2,
|
||||||
height = %d,
|
texture_height = %d,
|
||||||
|
glyphs_height = %d,
|
||||||
glyphs = {
|
glyphs = {
|
||||||
]],
|
]],
|
||||||
fontname, font_height)
|
fontname, texture_height, font_height)
|
||||||
)
|
)
|
||||||
for codepoint, w in pairs(glyph_widths) do
|
for codepoint, w in pairs(glyph_widths) do
|
||||||
local x = glyph_xs[codepoint]
|
local x = glyph_xs[codepoint]
|
||||||
local y = glyph_ys[codepoint]
|
local y = glyph_ys[codepoint]
|
||||||
local n = glyph_ns[codepoint]
|
local n = glyph_ns[codepoint]
|
||||||
if x ~= nil and y ~=nil and n ~= nil then
|
if x ~= nil and y ~=nil and n ~= nil then
|
||||||
file:write(string.format(" [%d] = { w = %d, n = %f, x = %d, y = %d },\n", codepoint, w, n, x, y))
|
file:write(string.format(" [%d] = { %d, %d, %d, %d },\n", codepoint, w, n, x, y))
|
||||||
else
|
else
|
||||||
file:write(string.format(" [%d] = { w = %d },\n", codepoint, w))
|
file:write(string.format(" [%d] = { %d },\n", codepoint, w))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
file:write([[
|
file:write([[
|
||||||
|
Reference in New Issue
Block a user