From f99886d1cd4a4b26aff6c4bfd500bd5b0eb9af68 Mon Sep 17 00:00:00 2001 From: GreenComfyTea Date: Wed, 20 Jul 2022 10:59:39 +0300 Subject: [PATCH] Fix Player Name Size Limit not working with UTF-8. --- reframework/autorun/MHR_Overlay.lua | 28 +++-- .../MHR_Overlay/Misc/table_helpers.lua | 4 +- .../MHR_Overlay/Misc/unicode_helpers.lua | 112 ++++++++++++++++++ .../UI/UI_Entities/damage_UI_entity.lua | 5 +- .../autorun/MHR_Overlay/UI/drawing.lua | 10 +- 5 files changed, 142 insertions(+), 17 deletions(-) create mode 100644 reframework/autorun/MHR_Overlay/Misc/unicode_helpers.lua diff --git a/reframework/autorun/MHR_Overlay.lua b/reframework/autorun/MHR_Overlay.lua index d47fe3e..88dedbc 100644 --- a/reframework/autorun/MHR_Overlay.lua +++ b/reframework/autorun/MHR_Overlay.lua @@ -10,6 +10,7 @@ local time = require("MHR_Overlay.Game_Handler.time"); local config = require("MHR_Overlay.Misc.config"); local language = require("MHR_Overlay.Misc.language"); local table_helpers = require("MHR_Overlay.Misc.table_helpers"); +local unicode_helpers = require("MHR_Overlay.Misc.unicode_helpers"); local part_names = require("MHR_Overlay.Misc.part_names"); @@ -49,6 +50,7 @@ local drawing = require("MHR_Overlay.UI.drawing"); screen.init_module(); singletons.init_module(); table_helpers.init_module(); +unicode_helpers.init_module(); time.init_module(); language.init_module(); @@ -459,13 +461,6 @@ re.on_frame(function() keyboard.update(); end); - -if debug then - re.on_frame(function() - draw.text("xy: " .. tostring(xy), 551, 11, 0xFF000000); - draw.text("xy: " .. tostring(xy), 550, 10, 0xFFFFFFFF); - end); -end -- #endregion --------------------------RE_IMGUI--------------------------- @@ -479,4 +474,21 @@ else re.on_frame(main_loop); end -- #endregion -----------------------------D2D------------------------------ \ No newline at end of file +----------------------------D2D------------------------------ + + + +if debug then + if d2d ~= nil then + d2d.register(function() + end, function() + d2d.text(drawing.font, "xy: " .. tostring(xy), 551, 11, 0xFF000000); + d2d.text(drawing.font, "xy: " .. tostring(xy), 550, 10, 0xFFFFFFFF); + end); + else + re.on_frame(function() + draw.text("xy: " .. tostring(xy), 551, 11, 0xFF000000); + draw.text("xy: " .. tostring(xy), 550, 10, 0xFFFFFFFF); + end); + end +end \ No newline at end of file diff --git a/reframework/autorun/MHR_Overlay/Misc/table_helpers.lua b/reframework/autorun/MHR_Overlay/Misc/table_helpers.lua index 448bf8b..bb75306 100644 --- a/reframework/autorun/MHR_Overlay/Misc/table_helpers.lua +++ b/reframework/autorun/MHR_Overlay/Misc/table_helpers.lua @@ -66,9 +66,9 @@ function table_helpers.tostring(table) local s = "{ \n"; for k,v in pairs(table) do if type(k) ~= "number" then - k = '"' .. k .. '"'; + k = "\"" .. k .. "\""; end - s = s .. "\t["..k.."] = " .. table_helpers.tostring(v) .. ",\n"; + s = s .. "\t[" .. k .."] = " .. table_helpers.tostring(v) .. ",\n"; end return s .. "} \n"; else diff --git a/reframework/autorun/MHR_Overlay/Misc/unicode_helpers.lua b/reframework/autorun/MHR_Overlay/Misc/unicode_helpers.lua new file mode 100644 index 0000000..26f9043 --- /dev/null +++ b/reframework/autorun/MHR_Overlay/Misc/unicode_helpers.lua @@ -0,0 +1,112 @@ +local unicode_helpers = {}; + +-- https://github.com/blitmap/lua-utf8-simple/blob/master/utf8_simple.lua + +-- ABNF from RFC 3629 +-- +-- UTF8-octets = *( UTF8-char ) +-- UTF8-char = UTF8-1 / UTF8-2 / UTF8-3 / UTF8-4 +-- UTF8-1 = %x00-7F +-- UTF8-2 = %xC2-DF UTF8-tail +-- UTF8-3 = %xE0 %xA0-BF UTF8-tail / %xE1-EC 2( UTF8-tail ) / +-- %xED %x80-9F UTF8-tail / %xEE-EF 2( UTF8-tail ) +-- UTF8-4 = %xF0 %x90-BF 2( UTF8-tail ) / %xF1-F3 3( UTF8-tail ) / +-- %xF4 %x80-8F 2( UTF8-tail ) +-- UTF8-tail = %x80-BF + +-- 0xxxxxxx | 007F (127) +-- 110xxxxx 10xxxxxx | 07FF (2047) +-- 1110xxxx 10xxxxxx 10xxxxxx | FFFF (65535) +-- 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx | 10FFFF (1114111) + +local pattern = '[%z\1-\127\194-\244][\128-\191]*'; + +-- helper function +function unicode_helpers.relative_position(position, length) + if position < 0 then + position = length + position + 1; + end + return position; +end + +-- THE MEAT + +-- maps f over s's utf8 characters f can accept args: (visual_index, utf8_character, byte_index) +function unicode_helpers.map(s, f, no_subs) + local i = 0; + + if no_subs then + for b, e in s:gmatch('()' .. pattern .. '()') do + i = i + 1; + local c = e - b; + f(i, c, b) + end + else + for b, c in s:gmatch('()(' .. pattern .. ')') do + i = i + 1; + f(i, c, b); + end + end +end + +-- THE REST + +-- generator for the above -- to iterate over all utf8 chars +function unicode_helpers.chars(s, no_subs) + return coroutine.wrap(function () + return unicode_helpers.map(s, coroutine.yield, no_subs); + end); +end + +-- like string.sub() but i, j are utf8 strings +-- a utf8-safe string.sub() +function unicode_helpers.sub(string, i, j) + local l = utf8.len(string); + + i = unicode_helpers.relative_position(i, l); + j = j and unicode_helpers.relative_position(j, l) or l; + + if i < 1 then + i = 1; + end + + if j > l then + j = l; + end + + if i > j then + return ''; + end + + local diff = j - i; + local iterator = unicode_helpers.chars(string, true); + + -- advance up to i + for _ = 1, i - 1 do + iterator(); + end + + local c, b = select(2, iterator()); + + -- i and j are the same, single-charaacter sub + if diff == 0 then + return string.sub(string, b, b + c - 1); + end + + i = b; + + -- advance up to j + for _ = 1, diff - 1 do + iterator(); + end + + c, b = select(2, iterator()); + + return string.sub(string, i, b + c - 1); + end + + +function unicode_helpers.init_module() +end + +return unicode_helpers; \ No newline at end of file diff --git a/reframework/autorun/MHR_Overlay/UI/UI_Entities/damage_UI_entity.lua b/reframework/autorun/MHR_Overlay/UI/UI_Entities/damage_UI_entity.lua index 5dcd76b..63f06f6 100644 --- a/reframework/autorun/MHR_Overlay/UI/UI_Entities/damage_UI_entity.lua +++ b/reframework/autorun/MHR_Overlay/UI/UI_Entities/damage_UI_entity.lua @@ -134,9 +134,8 @@ function damage_UI_entity.draw(_player, position_on_screen, opacity_scale, top_d end end - if _player.damage_UI.player_name_size_limit ~= 0 then - player_name_text = drawing.limit_text_size(player_name_text, _player.damage_UI.player_name_size_limit); - end + player_name_text = drawing.limit_text_size(player_name_text, _player.damage_UI.player_name_size_limit); + drawing.draw_label(_player.damage_UI.player_name_label, position_on_screen, opacity_scale, player_name_text); drawing.draw_label(_player.damage_UI.value_label, position_on_screen, opacity_scale, _player.display.total_damage); diff --git a/reframework/autorun/MHR_Overlay/UI/drawing.lua b/reframework/autorun/MHR_Overlay/UI/drawing.lua index 9b984b1..41f957c 100644 --- a/reframework/autorun/MHR_Overlay/UI/drawing.lua +++ b/reframework/autorun/MHR_Overlay/UI/drawing.lua @@ -1,5 +1,7 @@ local drawing = {}; local config; +local table_helpers; +local unicode_helpers; drawing.font = nil; @@ -33,12 +35,10 @@ function drawing.argb_to_color(alpha, red, green, blue) end function drawing.limit_text_size(text, size_limit) - if d2d == nil then + if d2d == nil or size_limit <= 0 then return text; end - --do return end; - local limited_text = text; while true do local text_width, text_height = drawing.font:measure(limited_text); @@ -46,7 +46,7 @@ function drawing.limit_text_size(text, size_limit) if text_width < size_limit then return limited_text; else - limited_text = limited_text:sub(1, -5) .. "..."; + limited_text = unicode_helpers.sub(limited_text, 1, -5) .. "..."; end end end @@ -197,6 +197,8 @@ end function drawing.init_module() config = require("MHR_Overlay.Misc.config"); + table_helpers = require("MHR_Overlay.Misc.table_helpers"); + unicode_helpers = require("MHR_Overlay.Misc.unicode_helpers"); end return drawing; \ No newline at end of file