mirror of
https://github.com/pyrollo/display_modpack.git
synced 2025-10-15 08:35:35 +02:00
wip
This commit is contained in:
@@ -58,6 +58,7 @@ end
|
||||
--- Font class
|
||||
|
||||
local Font = {}
|
||||
Font.__index = Font
|
||||
font_api.Font = Font
|
||||
|
||||
function Font:new(def)
|
||||
@@ -70,31 +71,53 @@ function Font:new(def)
|
||||
|
||||
local font = table.copy(def)
|
||||
|
||||
if font.height == nil or font.height <= 0 then
|
||||
minetest.log("error",
|
||||
"[font_api] Font definition must have a positive height.")
|
||||
return nil
|
||||
end
|
||||
|
||||
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
|
||||
-- Version 1 is with one texture per glyph
|
||||
if font.version == nil or font.version == 1 then
|
||||
if font.height == nil or font.height <= 0 then
|
||||
minetest.log("error",
|
||||
"[font_api] Font definition must have a positive height.")
|
||||
return nil
|
||||
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
|
||||
|
||||
if type(font.glyphs) ~= "table" then
|
||||
minetest.log("error",
|
||||
"[font_api] Font definition must have a `glyphs` array.")
|
||||
return nil
|
||||
-- Version 2 is with one only texture for all glyphs, using `[sheet` textures
|
||||
if font.version == 2 then
|
||||
if type(font.glyphs) ~= "table" then
|
||||
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
|
||||
|
||||
if font.glyphs[0] == nil then
|
||||
@@ -103,8 +126,7 @@ function Font:new(def)
|
||||
return nil
|
||||
end
|
||||
|
||||
setmetatable(font, self)
|
||||
self.__index = self
|
||||
setmetatable(font, self)
|
||||
|
||||
return font
|
||||
end
|
||||
@@ -149,7 +171,8 @@ end
|
||||
-- @return Char width
|
||||
|
||||
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
|
||||
|
||||
--- Returns texture for a given glyph
|
||||
@@ -157,22 +180,18 @@ end
|
||||
-- @return Texture
|
||||
|
||||
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
|
||||
return string.format("font_%s_%04x.png",
|
||||
self.name, glyph.c)
|
||||
end
|
||||
|
||||
if glyph.x == nil or glyph.y == nil then
|
||||
-- Case of invisible chars like space (no need to add any texture)
|
||||
return ""
|
||||
self.name, glyph[2])
|
||||
end
|
||||
|
||||
--le 5x15 est le nombre de tuiles, pas la taille des tuiles.
|
||||
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)
|
||||
-- Case of invisible chars like space (no need to add any texture)
|
||||
return ""
|
||||
end
|
||||
|
||||
--- 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
|
||||
return
|
||||
(
|
||||
(self.height or 0) +
|
||||
self.glyphs_height +
|
||||
(self.margintop or 0) +
|
||||
(self.marginbottom or 0)
|
||||
) * nb_of_lines +
|
||||
@@ -227,8 +246,8 @@ end
|
||||
|
||||
--- 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 width Width (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:
|
||||
-- - lines: maximum number of text lines (if text is limited)
|
||||
-- - halign: horizontal align ("left"/"center"/"right")
|
||||
@@ -236,7 +255,7 @@ end
|
||||
-- - color: color of the text ("#rrggbb")
|
||||
-- @return Texture string
|
||||
|
||||
function Font:render(text, texturew, textureh, style)
|
||||
function Font:render(text, width, height, style)
|
||||
style = style or {}
|
||||
|
||||
-- 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 texture = ""
|
||||
local textheight = self:get_height(#lines)
|
||||
local text_height = self:get_height(#lines)
|
||||
|
||||
if style.valign == "top" then
|
||||
y = 0
|
||||
elseif style.valign == "bottom" then
|
||||
y = textureh - textheight
|
||||
y = height - text_height
|
||||
else
|
||||
y = (textureh - textheight) / 2
|
||||
y = (height - text_height) / 2
|
||||
end
|
||||
|
||||
y = y + (self.margintop or 0)
|
||||
@@ -272,9 +291,9 @@ function Font:render(text, texturew, textureh, style)
|
||||
if style.halign == "left" then
|
||||
x = 0
|
||||
elseif style.halign == "right" then
|
||||
x = texturew - l.width
|
||||
x = width - l.width
|
||||
else
|
||||
x = (texturew - l.width) / 2
|
||||
x = (width - l.width) / 2
|
||||
end
|
||||
|
||||
while l.text ~= '' do
|
||||
@@ -284,17 +303,19 @@ function Font:render(text, texturew, textureh, style)
|
||||
local glyph = self.glyphs[codepoint]
|
||||
|
||||
-- Add image only if it is visible (at least partly)
|
||||
if x + glyph.w >= 0 and x <= texturew then
|
||||
texture = string.format("%s:%d,%d=%s",
|
||||
texture, x, y, self:get_glyph_texture(glyph):gsub("[\\^:]", "\\%0"))
|
||||
if x + glyph[1] >= 0 and x <= width then
|
||||
local glyph_texture = 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
|
||||
x = x + glyph.w
|
||||
x = x + glyph[1]
|
||||
end
|
||||
|
||||
y = y + self:get_height() + (self.linespacing or 0)
|
||||
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
|
||||
texture = texture.."^[colorize:"..style.color
|
||||
end
|
||||
|
@@ -103,11 +103,17 @@ local function show_font_formspec(playername)
|
||||
|
||||
for line = 1, #fonts do
|
||||
local font = font_api.get_font(fonts[line])
|
||||
local texture = font:make_text_texture(font.name, font:get_height()*5,
|
||||
font:get_height()*1.2, 1, "center", "top", "#fff")
|
||||
local texture = font:render(font.name,
|
||||
font:get_height()*5, font:get_height()*1.2, {
|
||||
lines = 1,
|
||||
valign = "middle",
|
||||
halign = "center",
|
||||
color = "#fff"
|
||||
}
|
||||
)
|
||||
fs = string.format(
|
||||
"%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
|
||||
minetest.show_formspec(context.playername, modname..':font_list', fs)
|
||||
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
|
||||
end
|
||||
|
||||
-- This will give enough combinations (720 is 2 * 2 * 2 * 2 * 3 * 3 * 5)
|
||||
tile_widths = compute_tile_sizes(720)
|
||||
-- This will give enough combinations (360 is 2 * 2 * 2 * 3 * 3 * 5)
|
||||
tile_widths = compute_tile_sizes(360)
|
||||
|
||||
-- Table width has to be sorted
|
||||
table.sort(tile_widths)
|
||||
@@ -177,9 +177,11 @@ local glyph_xs = {} -- x for each glyph
|
||||
local glyph_ys = {} -- y for each glyph
|
||||
local glyph_ns = {} -- n of tiles in sheet for each glyph (=texturewidth / tilewidth)
|
||||
|
||||
local texture_height
|
||||
|
||||
local function make_final_texture(filename)
|
||||
|
||||
local texture_height = font_height
|
||||
texture_height = font_height
|
||||
|
||||
local x = 0 -- cursor x
|
||||
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",
|
||||
texture_width, texture_height, filename
|
||||
))
|
||||
print(texture_width, texture_height)
|
||||
|
||||
for codepoint, n in pairs(glyph_ns) do
|
||||
local w = texture_width // n
|
||||
@@ -232,11 +233,10 @@ local function make_final_texture(filename)
|
||||
end
|
||||
-- Place subtexure in texture
|
||||
cmd = string.format("convert %s \\( %s -repage +%d+%d \\) -flatten %s", filename, cmd, x, y, filename)
|
||||
print (cmd)
|
||||
command(cmd)
|
||||
end
|
||||
|
||||
command(string.format("convert %s -threshold 50%% %s", filename, filename))
|
||||
command(string.format("convert %s -channel alpha -threshold 50%% %s", filename, filename))
|
||||
|
||||
end
|
||||
|
||||
@@ -307,22 +307,24 @@ file:write(string.format([[
|
||||
font_api.register_font(
|
||||
'%s',
|
||||
{
|
||||
version = 2,
|
||||
default = true,
|
||||
margintop = 3,
|
||||
linespacing = -2,
|
||||
height = %d,
|
||||
texture_height = %d,
|
||||
glyphs_height = %d,
|
||||
glyphs = {
|
||||
]],
|
||||
fontname, font_height)
|
||||
fontname, texture_height, font_height)
|
||||
)
|
||||
for codepoint, w in pairs(glyph_widths) do
|
||||
local x = glyph_xs[codepoint]
|
||||
local y = glyph_ys[codepoint]
|
||||
local n = glyph_ns[codepoint]
|
||||
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
|
||||
file:write(string.format(" [%d] = { w = %d },\n", codepoint, w))
|
||||
file:write(string.format(" [%d] = { %d },\n", codepoint, w))
|
||||
end
|
||||
end
|
||||
file:write([[
|
||||
|
Reference in New Issue
Block a user