forked from mtcontrib/signs_lib
support for non-ascii characters
This commit is contained in:
parent
8b975d7fa1
commit
d956c87dbc
84
api.lua
84
api.lua
@ -153,6 +153,7 @@ signs_lib.flip_walldir = {
|
||||
|
||||
-- Initialize character texture cache
|
||||
local ctexcache = {}
|
||||
local ctexcache_wide = {}
|
||||
|
||||
-- entity handling
|
||||
|
||||
@ -328,8 +329,10 @@ end
|
||||
local TP = signs_lib.path .. "/textures"
|
||||
-- Font file formatter
|
||||
local CHAR_FILE = "%s_%02x.png"
|
||||
local CHAR_FILE_WIDE = "%s_%s.png"
|
||||
-- Fonts path
|
||||
local CHAR_PATH = TP .. "/" .. CHAR_FILE
|
||||
local CHAR_PATH_WIDE = TP .. "/" .. CHAR_FILE_WIDE
|
||||
|
||||
-- Lots of overkill here. KISS advocates, go away, shoo! ;) -- kaeza
|
||||
|
||||
@ -389,6 +392,7 @@ end
|
||||
local function build_char_db(font_size)
|
||||
|
||||
local cw = {}
|
||||
local cw_wide = {}
|
||||
|
||||
-- To calculate average char width.
|
||||
local total_width = 0
|
||||
@ -404,20 +408,32 @@ local function build_char_db(font_size)
|
||||
end
|
||||
end
|
||||
|
||||
for i = 1, #signs_lib.wide_character_codes do
|
||||
local ch = signs_lib.wide_character_codes[i]
|
||||
local w, h = signs_lib.read_image_size(CHAR_PATH_WIDE:format("signs_lib_font_"..font_size.."px", ch))
|
||||
if w and h then
|
||||
cw_wide[ch] = w
|
||||
total_width = total_width + w
|
||||
char_count = char_count + 1
|
||||
end
|
||||
end
|
||||
|
||||
local cbw, cbh = signs_lib.read_image_size(TP.."/signs_lib_color_"..font_size.."px_n.png")
|
||||
assert(cbw and cbh, "error reading bg dimensions")
|
||||
return cw, cbw, cbh, (total_width / char_count)
|
||||
return cw, cbw, cbh, (total_width / char_count), cw_wide
|
||||
end
|
||||
|
||||
signs_lib.charwidth15,
|
||||
signs_lib.colorbgw15,
|
||||
signs_lib.lineheight15,
|
||||
signs_lib.avgwidth15 = build_char_db(15)
|
||||
signs_lib.avgwidth15,
|
||||
signs_lib.charwidth_wide15 = build_char_db(15)
|
||||
|
||||
signs_lib.charwidth31,
|
||||
signs_lib.colorbgw31,
|
||||
signs_lib.lineheight31,
|
||||
signs_lib.avgwidth31 = build_char_db(31)
|
||||
signs_lib.avgwidth31,
|
||||
signs_lib.charwidth_wide31 = build_char_db(31)
|
||||
|
||||
local sign_groups = {choppy=2, dig_immediate=2}
|
||||
local fences_with_sign = { }
|
||||
@ -453,7 +469,22 @@ local function char_tex(font_name, ch)
|
||||
end
|
||||
end
|
||||
|
||||
local function make_line_texture(line, lineno, pos, line_width, line_height, cwidth_tab, font_size, colorbgw)
|
||||
local function char_tex_wide(font_name, ch)
|
||||
if ctexcache_wide[font_name..ch] then
|
||||
return ctexcache_wide[font_name..ch], true
|
||||
else
|
||||
local exists, tex = file_exists(CHAR_PATH_WIDE:format(font_name, ch))
|
||||
if exists then
|
||||
tex = CHAR_FILE_WIDE:format(font_name, ch)
|
||||
else
|
||||
tex = CHAR_FILE:format(font_name, 0x5f)
|
||||
end
|
||||
ctexcache_wide[font_name..ch] = tex
|
||||
return tex, exists
|
||||
end
|
||||
end
|
||||
|
||||
local function make_line_texture(line, lineno, pos, line_width, line_height, cwidth_tab, font_size, colorbgw, cwidth_tab_wide)
|
||||
local width = 0
|
||||
local maxw = 0
|
||||
local font_name = "signs_lib_font_"..font_size.."px"
|
||||
@ -490,6 +521,27 @@ local function make_line_texture(line, lineno, pos, line_width, line_height, cwi
|
||||
local word_l = #word
|
||||
local i = 1
|
||||
while i <= word_l do
|
||||
local wide_c
|
||||
if "&#x" == word:sub(i, i + 2) then
|
||||
local j = i + 3
|
||||
local collected = ""
|
||||
while j <= word_l do
|
||||
local c = word:sub(j, j)
|
||||
if c == ";" then
|
||||
wide_c = collected
|
||||
break
|
||||
elseif c < "0" then
|
||||
break
|
||||
elseif "f" < c then
|
||||
break
|
||||
elseif ("9" < c) and (c < "a") then
|
||||
break
|
||||
else
|
||||
collected = collected .. c
|
||||
j = j + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
local c = word:sub(i, i)
|
||||
if c == "#" then
|
||||
local cc = tonumber(word:sub(i+1, i+1), 16)
|
||||
@ -497,6 +549,25 @@ local function make_line_texture(line, lineno, pos, line_width, line_height, cwi
|
||||
i = i + 1
|
||||
cur_color = cc
|
||||
end
|
||||
elseif wide_c then
|
||||
local w = cwidth_tab_wide[wide_c]
|
||||
if w then
|
||||
width = width + w + 1
|
||||
if width >= (line_width - cwidth_tab[" "]) then
|
||||
width = 0
|
||||
else
|
||||
maxw = math_max(width, maxw)
|
||||
end
|
||||
if #chars < MAX_INPUT_CHARS then
|
||||
table.insert(chars, {
|
||||
off = ch_offs,
|
||||
tex = char_tex_wide(font_name, wide_c),
|
||||
col = ("%X"):format(cur_color),
|
||||
})
|
||||
end
|
||||
ch_offs = ch_offs + w
|
||||
end
|
||||
i = i + #wide_c + 3
|
||||
else
|
||||
local w = cwidth_tab[c]
|
||||
if w then
|
||||
@ -576,6 +647,7 @@ function signs_lib.make_sign_texture(lines, pos)
|
||||
local line_width
|
||||
local line_height
|
||||
local char_width
|
||||
local char_width_wide
|
||||
local colorbgw
|
||||
local widemult = 1
|
||||
|
||||
@ -588,12 +660,14 @@ function signs_lib.make_sign_texture(lines, pos)
|
||||
line_width = math.floor(signs_lib.avgwidth31 * def.chars_per_line) * (def.horiz_scaling * widemult)
|
||||
line_height = signs_lib.lineheight31
|
||||
char_width = signs_lib.charwidth31
|
||||
char_width_wide = signs_lib.charwidth_wide31
|
||||
colorbgw = signs_lib.colorbgw31
|
||||
else
|
||||
font_size = 15
|
||||
line_width = math.floor(signs_lib.avgwidth15 * def.chars_per_line) * (def.horiz_scaling * widemult)
|
||||
line_height = signs_lib.lineheight15
|
||||
char_width = signs_lib.charwidth15
|
||||
char_width_wide = signs_lib.charwidth_wide15
|
||||
colorbgw = signs_lib.colorbgw15
|
||||
end
|
||||
|
||||
@ -602,7 +676,7 @@ function signs_lib.make_sign_texture(lines, pos)
|
||||
local lineno = 0
|
||||
for i = 1, #lines do
|
||||
if lineno >= def.number_of_lines then break end
|
||||
local linetex, ln = make_line_texture(lines[i], lineno, pos, line_width, line_height, char_width, font_size, colorbgw)
|
||||
local linetex, ln = make_line_texture(lines[i], lineno, pos, line_width, line_height, char_width, font_size, colorbgw, char_width_wide)
|
||||
table.insert(texture, linetex)
|
||||
lineno = ln + 1
|
||||
end
|
||||
|
55
encoding.lua
55
encoding.lua
@ -203,6 +203,28 @@ local utf8_decode = {
|
||||
[210] = {[144] = "\165", [145] = "\180"}
|
||||
}
|
||||
|
||||
local wide_character_codes = {
|
||||
}
|
||||
|
||||
local unicode_install = function(
|
||||
numbers
|
||||
)
|
||||
local scope = utf8_decode
|
||||
for i = 1,#numbers-2 do
|
||||
if not scope[numbers[i]] then
|
||||
scope[numbers[i]] = {}
|
||||
end
|
||||
scope = scope[numbers[i]]
|
||||
end
|
||||
scope[numbers[#numbers-1]] = "&#x" .. numbers[#numbers] .. ";"
|
||||
table.insert(
|
||||
wide_character_codes,
|
||||
numbers[#numbers]
|
||||
)
|
||||
end
|
||||
|
||||
unicode_install({38,"26"})
|
||||
|
||||
local nmdc = {
|
||||
[36] = "$",
|
||||
[124] = "|"
|
||||
@ -230,36 +252,33 @@ function AnsiToUtf8(s)
|
||||
end
|
||||
|
||||
function Utf8ToAnsi(s)
|
||||
local a, j, r, b = 0, 0, ""
|
||||
local a, j, r, b, scope = 0, 0, ""
|
||||
for i = 1, s and s:len() or 0 do
|
||||
b = s:byte(i)
|
||||
if b < 128 then
|
||||
if b == 0x26 then
|
||||
r = r .. "&"
|
||||
elseif b < 128 then
|
||||
if nmdc[b] then
|
||||
r = r .. nmdc[b]
|
||||
else
|
||||
r = r .. string.char(b)
|
||||
end
|
||||
elseif a == 2 then
|
||||
a, j = a - 1, b
|
||||
elseif a == 1 then
|
||||
--if j == nil or b == nil then return r end
|
||||
--print(j)
|
||||
--print(b)
|
||||
--local ansi = utf8_decode[j]
|
||||
--if ansi == nil then return r end
|
||||
--if ansi[b] == nil then return r end
|
||||
if utf8_decode[j] then
|
||||
if utf8_decode[j][b] then
|
||||
a, r = a - 1, r .. utf8_decode[j][b]
|
||||
elseif scope then
|
||||
if scope[b] then
|
||||
scope = scope[b]
|
||||
if "string" == type(scope) then
|
||||
r, scope = r .. scope
|
||||
end
|
||||
else
|
||||
r, scope = r .. "_"
|
||||
end
|
||||
elseif b == 226 then
|
||||
a = 2
|
||||
elseif b == 194 or b == 208 or b == 209 or b == 210 then
|
||||
j, a = b, 1
|
||||
elseif utf8_decode[b] then
|
||||
scope = utf8_decode[b]
|
||||
else
|
||||
r = r .. "_"
|
||||
end
|
||||
end
|
||||
return r
|
||||
end
|
||||
|
||||
signs_lib.wide_character_codes = wide_character_codes
|
||||
|
2
init.lua
2
init.lua
@ -10,7 +10,7 @@ signs_lib.path = minetest.get_modpath(minetest.get_current_modname())
|
||||
local S, NS = dofile(signs_lib.path .. "/intllib.lua")
|
||||
signs_lib.gettext = S
|
||||
|
||||
dofile(signs_lib.path.."/api.lua")
|
||||
dofile(signs_lib.path.."/encoding.lua")
|
||||
dofile(signs_lib.path.."/api.lua")
|
||||
dofile(signs_lib.path.."/standard_signs.lua")
|
||||
dofile(signs_lib.path.."/compat.lua")
|
||||
|
Loading…
Reference in New Issue
Block a user