Unity 根據(jù)文本寬度自動(dòng)裁剪多余文本加后綴"...",包含富文本處理

image.png

下列均以Lua代碼編寫實(shí)現(xiàn)

主要思路:

  • 根據(jù)高度判斷是否需要裁剪多余行內(nèi)容
  • 存儲(chǔ)富文本
  • 移除富文本
  • 切割多余文本
  • 恢復(fù)富文本

根據(jù)高度判斷是否需要裁剪多余行內(nèi)容

txt:Unity - Text組件(UnityEngine.UI.Text)
height:計(jì)算當(dāng)前內(nèi)容占用總高度
one_height:一行內(nèi)容的高度

    local generator = CS.UnityEngine.TextGenerator()
    local settings = txt:GetGenerationSettings(size)
    local height = generator:GetPreferredHeight(content, settings)
    local one_height = generator:GetPreferredHeight(" ", settings)

存儲(chǔ)富文本

local matchs = {}  -- 存儲(chǔ)富文本匹配內(nèi)容
local last_start = 0
for str in string.gmatch(content, "<[^>]->") do
    local start_idx, end_idx = string.find(content, str, last_start)
    last_start = start_idx
    table.insert(matchs, {str = str, start_idx = start_idx, end_idx = end_idx})
end

移除富文本

-- 根據(jù)存儲(chǔ)的matchs匹配移除
for i, v in ipairs(matchs) do
    content = string.gsub(content, v.match_str or v.str, "")
end

切割多余文本

-- 判斷字符對(duì)應(yīng)byte長度
function UTF8LenWord(char)
    if not char then
        return 0
    elseif char > 240 then
        return 4
    elseif char > 225 then
        return 3
    elseif char > 192 then
        return 2
    end
    return 1
end
local len = string.len(content)
local char_lens = {}    -- 記錄每個(gè)文字的byte長度,后面一個(gè)一個(gè)切割掉
local idx = 1
while(idx <= len) do
    local c = UTF8LenWord(string.byte(content, idx, idx + 1))
    table.insert(char_lens, 1, c)
    idx = idx + c
end
-- 行數(shù)大于1行的根據(jù)長度記錄進(jìn)行剔除
while(height/one_height > 1) do
    local sub_count = table.remove(char_lens, 1)
    len = len - sub_count
    content = string.sub(content, 0, len)
    height = generator:GetPreferredHeight(content, settings)
end
-- 最后剔除掉3+個(gè)byte
local sub_count = 0
while(sub_count < 3) do
    sub_count = sub_count + table.remove(char_lens, 1)
end
content = string.sub(content, 0, len - sub_count) .. "..."

恢復(fù)富文本

-- 最后根據(jù)富文本記錄恢復(fù)富文本
for i, v in ipairs(matchs) do
    local len = string.len(content)
    local start_idx = v.start_idx - 1
    if start_idx > len then
        -- 一般富文本帶'/'的作為結(jié)尾,匹配不到'/'的且已經(jīng)超過文本長度時(shí),就不繼續(xù)執(zhí)行了
        if not string.match(v.str, "/") then
            break
        end
        start_idx = len
    end
    local left = string.sub(content, 1, start_idx)
    local right = string.sub(content, start_idx + 1, len)
    content = left .. v.str .. right
end

print(content)
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容