Add support for high resolution and proportional fonts to signs.

This also gets rid of useless constructs, and optimizes others.
This commit is contained in:
kaeza 2013-10-18 02:16:40 -02:00
parent e97ee8256e
commit 424a374d83
97 changed files with 221 additions and 382 deletions

View File

@ -1,283 +0,0 @@
A
_a_
7
B
_b_
5
C
_c_
6
D
_d_
6
E
_e_
5
F
_f_
5
G
_g_
6
H
_h_
6
I
_i_
1
J
_j_
4
K
_k_
5
L
_l_
4
M
_m_
7
N
_n_
6
O
_o_
6
P
_p_
5
Q
_q_
7
R
_r_
5
S
_s_
5
T
_t_
5
U
_u_
6
V
_v_
7
W
_w_
9
X
_x_
5
Y
_y_
7
Z
_z_
5
a
_a
5
b
_b
5
c
_c
4
d
_d
5
e
_e
4
f
_f
4
g
_g
5
h
_h
5
i
_i
1
j
_j
1
k
_k
4
l
_l
1
m
_m
7
n
_n
5
o
_o
5
p
_p
5
q
_q
5
r
_r
3
s
_s
4
t
_t
3
u
_u
4
v
_v
5
w
_w
7
x
_x
5
y
_y
4
z
_z
4
_sp
2
0
_0
4
1
_1
2
2
_2
4
3
_3
4
4
_4
4
5
_5
4
6
_6
4
7
_7
4
8
_8
4
9
_9
4
(
_bl
2
)
_br
2
{
_cl
3
}
_cr
3
[
_sl
2
]
_sr
2
'
_ap
1
!
_ex
1
?
_qu
4
@
_at
5
#
_hs
5
$
_dl
4
%
_pr
5
^
_ca
3
&
_am
5
*
_as
3
_
_un
3
+
_ps
3
-
_mn
3
=
_eq
3
:
_co
1
;
_sm
1
,
_cm
2
"
_qo
3
/
_dv
5
~
_tl
4
<
_lt
3
>
_gt
3
\
_re
5
|
_vb
1
.
_dt
1

View File

@ -1,46 +1,3 @@
-- Font: 04.jp.org
-- CONSTANTS
local SIGN_WIDTH = 110
local SIGN_PADDING = 8
local LINE_LENGTH = 16
local NUMBER_OF_LINES = 4
local LINE_HEIGHT = 14
local CHAR_WIDTH = 5
local signs = {
{delta = {x = -0.06, y = 0, z = 0.399}, yaw = 0},
{delta = {x = 0.399, y = 0, z = 0.06}, yaw = math.pi / -2},
{delta = {x = 0.06, y = 0, z = -0.399}, yaw = math.pi},
{delta = {x = -0.399, y = 0, z = -0.06}, yaw = math.pi / 2},
}
local signs_yard = {
{delta = {x = -0.06, y = 0, z = -0.05}, yaw = 0},
{delta = {x = -0.05, y = 0, z = 0.06}, yaw = math.pi / -2},
{delta = {x = 0.06, y = 0, z = 0.05}, yaw = math.pi},
{delta = {x = 0.05, y = 0, z = -0.06}, yaw = math.pi / 2},
}
local signs_post = {
{delta = {x = -0.06, y = 0, z = -0.226}, yaw = 0},
{delta = {x = -0.226, y = 0, z = 0.06}, yaw = math.pi / -2},
{delta = {x = 0.06, y = 0, z = 0.226}, yaw = math.pi},
{delta = {x = 0.226, y = 0, z = -0.06}, yaw = math.pi / 2},
}
local sign_groups = {choppy=2, dig_immediate=2}
local fences_with_sign = { }
-- Misc variables
local chars_file = io.open(minetest.get_modpath("homedecor").."/characters", "r")
local charmap = {}
local max_chars = 16
-- Boilerplate to support localized strings if intllib mod is installed. -- Boilerplate to support localized strings if intllib mod is installed.
local S local S
@ -51,6 +8,174 @@ else
S = function ( s ) return s end S = function ( s ) return s end
end end
-- CONSTANTS
local NUMBER_OF_LINES = 6
local MP = minetest.get_modpath("homedecor")
-- Used by `build_char_db' to locate the file.
local FONT_FMT = "%s/hdf_%02x.png"
-- Simple texture name for building text texture.
local FONT_FMT_SIMPLE = "hdf_%02x.png"
-- Path to the textures.
local TP = MP.."/textures"
local TEXT_SCALE = {x=0.9, y=0.7}
-- Lots of overkill here. KISS advocates, go away, shoo! ;) -- kaeza
local PNG_HDR = string.char(0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A)
-- Read the image size from a PNG file.
-- Returns image_w, image_h.
-- Only the LSB is read from each field!
local function read_png_size(f)
f:seek("set", 0x0)
local hdr = f:read(8)
if hdr ~= PNG_HDR then return end
f:seek("set", 0x13)
local ws = f:read(1)
f:seek("set", 0x17)
local hs = f:read(1)
return ws:byte(), hs:byte()
end
-- Set by build_char_db()
local LINE_HEIGHT
local SIGN_WIDTH
local SIGN_PADDING
-- This holds the individual character widths.
-- Indexed by the actual character (e.g. charwidth["A"])
local charwidth = { }
-- File to cache the font size to.
local CHARDB_FILE = minetest.get_worldpath().."/homedecor_chardb"
local function build_char_db()
LINE_HEIGHT = nil
SIGN_WIDTH = nil
SIGN_PADDING = nil
-- To calculate average char width.
local total_width = 0
local char_count = 0
-- Try to load cached data to avoid heavy disk I/O.
local cdbf = io.open(CHARDB_FILE, "rt")
if cdbf then
minetest.log("info", "[homedecor] Reading cached character database.")
for line in cdbf:lines() do
local ch, w = line:match("(0x[0-9A-Fa-f]+)%s+([0-9][0-9]+)")
if ch and w then
local c = tonumber(ch, 16)
w = tonumber(w)
if c and w then
if c == 0 then
LINE_HEIGHT = h
elseif (c >= 32) and (c < 127) then
charwidth[string.char(c)] = w
total_width = total_width + w
char_count = char_count + 1
end
end
end
end
cdbf:close()
if LINE_HEIGHT then
-- XXX: Is there a better way to calc this?
-- XXX: Remember to change similar lines below if this changes.
SIGN_WIDTH = math.floor((total_width / char_count) * 16)
SIGN_PADDING = SIGN_WIDTH / 14 -- Totally arbitrary.
return
else
minetest.log("warning", "[homedecor]"
.." Could not find font line height in cached DB."
.." Trying brute force."
)
end
end
-- OK, something went wrong... try brute force loading from texture files.
total_width = 0
char_count = 0
LINE_HEIGHT = nil
for c = 32, 126 do
local filename = FONT_FMT:format(TP, c)
local f = io.open(filename)
if f then
local ch = string.char(c)
local w, h = read_png_size(f)
f:close()
if w and h then
charwidth[ch] = w
total_width = total_width + w
char_count = char_count + 1
if not LINE_HEIGHT then LINE_HEIGHT = h end
end
end
end
if not LINE_HEIGHT then
error("Could not find font line height.")
end
SIGN_WIDTH = math.floor((total_width / char_count) * 16)
SIGN_PADDING = SIGN_WIDTH / 14 -- Totally arbitrary.
-- Try to save cached list back to disk.
local e -- Note: `cdbf' is already declared local above.
cdbf, e = io.open(CHARDB_FILE, "wt")
if not cdbf then
minetest.log("warning", "[homedecor] Could not save cached char DB: "..(e or ""))
return
end
cdbf:write(("0x00 %d\n"):format(LINE_HEIGHT))
for c = 32, 126 do
local w = charwidth[string.char(c)]
if w then
cdbf:write(("0x%02X %d\n"):format(c, w))
end
end
cdbf:close()
end
local signs = {
{delta = {x = 0, y = 0, z = 0.399}, yaw = 0},
{delta = {x = 0.399, y = 0, z = 0 }, yaw = math.pi / -2},
{delta = {x = 0, y = 0, z = -0.399}, yaw = math.pi},
{delta = {x = -0.399, y = 0, z = 0 }, yaw = math.pi / 2},
}
local signs_yard = {
{delta = {x = 0, y = 0.05, z = -0.05}, yaw = 0},
{delta = {x = -0.05, y = 0.05, z = 0}, yaw = math.pi / -2},
{delta = {x = 0, y = 0.05, z = 0.05}, yaw = math.pi},
{delta = {x = 0.05, y = 0.05, z = 0}, yaw = math.pi / 2},
}
local signs_post = {
{delta = {x = 0, y = 0, z = -0.226}, yaw = 0},
{delta = {x = -0.226, y = 0, z = 0}, yaw = math.pi / -2},
{delta = {x = 0, y = 0, z = 0.226}, yaw = math.pi},
{delta = {x = 0.226, y = 0, z = 0}, yaw = math.pi / 2},
}
local sign_groups = {choppy=2, dig_immediate=2}
local fences_with_sign = { }
-- some local helper functions -- some local helper functions
local homedecor_create_lines = function(text) local homedecor_create_lines = function(text)
@ -66,51 +191,55 @@ end
local math_max = math.max local math_max = math.max
local homedecor_generate_line = function(s, lineno) local homedecor_generate_line = function(s, lineno)
local i = 1
local parsed = {}
local width = 0 local width = 0
local maxw = 0 local maxw = 0
local chars = 0
while i <= #s do local chars = { }
local file = nil
if charmap[s:sub(i, i)] ~= nil then local max_line_w = SIGN_WIDTH - (SIGN_PADDING * 2)
file = charmap[s:sub(i, i)]
i = i + 1 -- We check which chars are available here.
elseif i < #s and charmap[s:sub(i, i + 1)] ~= nil then for i = 1, #s do
file = charmap[s:sub(i, i + 1)] local c = s:sub(i, i)
i = i + 2 local w = charwidth[c]
else if w then
print("[signs] W: unknown symbol in '"..s.."' at "..i.." (probably "..s:sub(i, i)..")") width = width + w + 1
i = i + 1
end
if file ~= nil then
width = width + CHAR_WIDTH
maxw = math_max(width, maxw) maxw = math_max(width, maxw)
chars = chars + 1 if width >= max_line_w then
if chars > max_chars then
width = 0 width = 0
end end
table.insert(parsed, file) table.insert(chars, c)
end end
end end
maxw = maxw - 1 maxw = maxw - 1
local texture = { } -- Okay, we actually build the "line texture" here.
local start_xpos = math.floor((SIGN_WIDTH - 2 * SIGN_PADDING - maxw) / 2 + SIGN_PADDING) local start_xpos = math.floor((SIGN_WIDTH - 2 * SIGN_PADDING - maxw) / 2 + SIGN_PADDING)
local xpos = start_xpos local xpos = start_xpos
local linepos = 0 local texture = { }
for i = 1, #parsed do local ypos = (LINE_HEIGHT * (lineno --[[+ 1]]))
if lineno >= NUMBER_OF_LINES then break end
local ypos = 12 + (LINE_HEIGHT * lineno) width = 0
table.insert(texture, (":%d,%d=%s.png"):format(xpos, ypos, parsed[i]))
xpos = xpos + CHAR_WIDTH + 1 for i = 1, #s do
linepos = linepos + 1 local c = s:sub(i, i)
if linepos > max_chars then local w = charwidth[c]
local tex = FONT_FMT_SIMPLE:format(c:byte())
table.insert(texture, (":%d,%d=%s"):format(xpos, ypos, tex))
xpos = xpos + w + 1
width = width + w + 1
if width > max_line_w then
xpos = start_xpos xpos = start_xpos
linepos = 0 ypos = ypos + LINE_HEIGHT
width = 0
lineno = lineno + 1 lineno = lineno + 1
end end
if lineno >= NUMBER_OF_LINES then break end
end end
return table.concat(texture, ""), lineno return table.concat(texture, ""), lineno
end end
@ -138,20 +267,11 @@ local homedecor_generate_texture = function(lines)
return table.concat(texture, "") return table.concat(texture, "")
end end
-- load characters map local function set_obj_text(obj, text)
obj:set_properties({
if not chars_file then textures={homedecor_generate_texture(homedecor_create_lines(text))},
print("[signs] "..S("E: character map file not found")) visual_size = TEXT_SCALE,
else })
while true do
local char = chars_file:read("*l")
if char == nil then
break
end
local img = chars_file:read("*l")
chars_file:read("*l")
charmap[char] = img
end
end end
homedecor.construct_sign = function(pos) homedecor.construct_sign = function(pos)
@ -179,7 +299,7 @@ homedecor.update_sign = function(pos, fields)
local objects = minetest.get_objects_inside_radius(pos, 0.5) local objects = minetest.get_objects_inside_radius(pos, 0.5)
for _, v in ipairs(objects) do for _, v in ipairs(objects) do
if v:get_entity_name() == "signs:text" then if v:get_entity_name() == "signs:text" then
v:set_properties({textures={homedecor_generate_texture(homedecor_create_lines(text))}}) set_obj_text(v, text)
return return
end end
end end
@ -392,7 +512,7 @@ if not homedecor.disable_signs then
signs_text_on_activate = function(self) signs_text_on_activate = function(self)
local meta = minetest.get_meta(self.object:getpos()) local meta = minetest.get_meta(self.object:getpos())
local text = meta:get_string("text") local text = meta:get_string("text")
self.object:set_properties({textures={homedecor_generate_texture(homedecor_create_lines(text))}}) set_obj_text(self.object, text)
end end
else else
signs_text_on_activate = function(self) signs_text_on_activate = function(self)
@ -479,6 +599,8 @@ function homedecor.register_fence_with_sign(fencename, fencewithsignname)
print("Registered "..fencename.." and "..fencewithsignname) print("Registered "..fencename.." and "..fencewithsignname)
end end
build_char_db()
if minetest.setting_get("log_mods") then if minetest.setting_get("log_mods") then
minetest.log("action", S("signs loaded")) minetest.log("action", S("signs loaded"))
end end

Binary file not shown.

Before

Width:  |  Height:  |  Size: 128 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 129 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 135 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 133 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 134 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 132 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 132 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 132 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 127 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 132 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 128 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 130 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 123 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 122 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 127 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 133 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 132 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 129 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 130 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 130 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 127 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 129 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 127 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 129 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 123 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 103 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 128 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 132 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 126 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 135 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 121 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 133 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 127 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 130 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 121 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 123 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 130 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 132 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 129 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 130 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 129 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 132 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 129 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 125 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 119 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 130 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 126 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 128 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 128 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 134 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 130 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 128 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 128 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 129 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 125 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 127 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 122 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 125 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 130 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 125 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 126 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 129 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 130 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 135 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 125 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 129 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 127 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 123 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 130 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 125 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 128 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 132 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 128 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 131 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 126 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 107 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 112 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 126 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 130 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 128 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 124 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 125 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 126 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 121 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 127 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 128 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 120 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 126 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 128 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 127 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 129 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 129 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 130 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 128 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 130 B