forked from mtcontrib/signs_lib
		
	support for non-ascii characters
This commit is contained in:
		
							
								
								
									
										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")
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user