Merge pull request #330 from frto027/master
add utf8 support for EID:fitTextToWidth
This commit is contained in:
7 files changed
+103
-27
No files matched your search
@@ -16,7 +16,7 @@ EID.descriptions[languageCode].custom = {} -- table for custom entity descriptio
|
||||
EID.descriptions[languageCode].languageName = "English"
|
||||
|
||||
-- Fonts to be used with this language pack
|
||||
EID.descriptions[languageCode].fonts = {{name="default", lineHeight=11}, {name="inverted", lineHeight=11}, {name="borderless", lineHeight=11}}
|
||||
EID.descriptions[languageCode].fonts = {{name="default", lineHeight=11, textboxWidth = 115}, {name="inverted", lineHeight=11, textboxWidth = 115}, {name="borderless", lineHeight=11, textboxWidth = 115}}
|
||||
|
||||
---------- Collectibles ----------
|
||||
EID.descriptions[languageCode].collectibles={
|
||||
|
||||
@@ -29,7 +29,7 @@ EID.descriptions[languageCode].languageName = "Korean"
|
||||
|
||||
korean_galmoori9, korean_galmoori11 is added for community request.
|
||||
]]
|
||||
EID.descriptions[languageCode].fonts = {{name="korean_hcrdotum", lineHeight=11}, {name="korean_lanapixel", lineHeight=12}, {name="korean_soyakkoma", lineHeight=13}, {name="korean_soyakkoma_borderless", lineHeight=13}, {name="korean_soyakkoma_inverted", lineHeight=13}, {name="korean_soyanon", lineHeight=12}, {name="korean_galmoori9", lineHeight=12}, {name="korean_galmoori11", lineHeight=14}}
|
||||
EID.descriptions[languageCode].fonts = {{name="korean_hcrdotum", lineHeight=11, textboxWidth = 115}, {name="korean_lanapixel", lineHeight=12, textboxWidth = 115}, {name="korean_soyakkoma", lineHeight=13, textboxWidth = 115}, {name="korean_soyakkoma_borderless", lineHeight=13, textboxWidth = 115}, {name="korean_soyakkoma_inverted", lineHeight=13, textboxWidth = 115}, {name="korean_soyanon", lineHeight=12, textboxWidth = 115}, {name="korean_galmoori9", lineHeight=12, textboxWidth = 115}, {name="korean_galmoori11", lineHeight=14, textboxWidth = 115}}
|
||||
|
||||
---------- Collectibles ----------
|
||||
EID.descriptions[languageCode].collectibles={
|
||||
|
||||
@@ -16,7 +16,7 @@ EID.descriptions[languageCode].custom = {} -- table for custom entity descriptio
|
||||
EID.descriptions[languageCode].languageName = "Chinese"
|
||||
|
||||
-- Fonts to be used with this languagepack
|
||||
EID.descriptions[languageCode].fonts = {{name = "default_cn", lineHeight = 14}}
|
||||
EID.descriptions[languageCode].fonts = {{name = "default_cn", lineHeight = 14, textboxWidth = 150}}
|
||||
|
||||
---------- Collectibles ----------
|
||||
EID.descriptions[languageCode].collectibles={
|
||||
|
||||
+94
-23
@@ -530,11 +530,7 @@ end
|
||||
-- Generates a string with the defined pixel-length using a custom 1px wide character
|
||||
-- This will only work for this specific custom font
|
||||
function EID:generatePlaceholderString(length)
|
||||
local placeholder = ""
|
||||
for i = 1, length do
|
||||
placeholder = placeholder .. "¤"
|
||||
end
|
||||
return placeholder
|
||||
return string.rep("¤", length)
|
||||
end
|
||||
|
||||
-- Returns the inlineIcon object of a given Iconstring
|
||||
@@ -720,29 +716,103 @@ end
|
||||
|
||||
-- Fits a given string to a specific width
|
||||
-- returns the string as a table of lines
|
||||
function EID:fitTextToWidth(str, textboxWidth)
|
||||
function EID:fitTextToWidth(str, textboxWidth, breakUtf8Chars)
|
||||
local formatedLines = {}
|
||||
local curLength = 0
|
||||
local text = ""
|
||||
for word in string.gmatch(str, "([^%s]+)") do
|
||||
local colorFiltered = EID:filterColorMarkup(word, EID:getTextColor())
|
||||
local filteredWord = ""
|
||||
for _, filtered in ipairs(colorFiltered) do
|
||||
filteredWord = filteredWord .. filtered[1]
|
||||
end
|
||||
local strFiltered, spriteTable = EID:filterIconMarkup(filteredWord, 0, 0)
|
||||
local wordLength = EID:getStrWidth(strFiltered)
|
||||
local text = {}
|
||||
|
||||
if curLength + wordLength <= textboxWidth or curLength < 12 then
|
||||
text = text .. word .. " "
|
||||
curLength = curLength + wordLength
|
||||
else
|
||||
table.insert(formatedLines, text)
|
||||
text = word .. " "
|
||||
curLength = wordLength
|
||||
local cursor = 1
|
||||
local word_begin_index = 1
|
||||
|
||||
local byte = string.byte -- for speed up
|
||||
local sub = string.sub
|
||||
local byte_space = string.byte(' ')
|
||||
|
||||
while cursor <= #str do
|
||||
-- ascii word: 0x0xxxxxxx
|
||||
-- utf8 word (sequence): 0x11xxxxxx 0x10xxxxxx 0x10xxxxxx ... 0x10xxxxxx
|
||||
-- see https://en.wikipedia.org/wiki/UTF-8
|
||||
-- we can only break after space, or before 0x11xxxxxx
|
||||
local can_break_after_cursor = false
|
||||
local cur, next = byte(str,cursor), byte(str,cursor+1)
|
||||
if
|
||||
-- cond#1: we can break at the end of string
|
||||
cursor == #str or
|
||||
-- cond#2: we can break after space
|
||||
cur == byte_space or
|
||||
-- handle utf8 characters
|
||||
(breakUtf8Chars and(
|
||||
-- cond#3: we can break if the next character is 0x11xxxxxx
|
||||
((next & 0xC0) == 0xC0) or
|
||||
-- cond#4: we can also break if the current is 0x10xxxxxx while the next is ascii but not space
|
||||
(((cur & 0xC0) == 0x80) and (next~= byte_space and (next & 0x80) == 0x00))
|
||||
))
|
||||
then
|
||||
--[[
|
||||
-------------------ascii only---------------
|
||||
word will be separated by spaces.
|
||||
wordA |wordB |wordC |^%@&Q%#^&#@!! |aksldj
|
||||
↑
|
||||
cond#2
|
||||
we may break after every space.
|
||||
spaces | | | | | |woops
|
||||
↑
|
||||
cond#2
|
||||
-------------------UTF8 only----------------
|
||||
word is 0x11xxxxxx followed by several 0x10xxxxxx until the next 0x11xxxxxx (not included)
|
||||
你|好|,|世|界|!|↑|↑|↑|↑
|
||||
↑
|
||||
cond#3
|
||||
byte data of a word:
|
||||
[0x11xxxxxx,0x10xxxxxx,0x10xxxxxx, (next is 0x11xxxxxx, cond#3)]
|
||||
--------------------ascii->utf8------------
|
||||
utf8 word must start with 0x11xxxxxx, so cond#3 split before it.
|
||||
word|世|界
|
||||
| ↑
|
||||
↑ cond#3
|
||||
cond#3
|
||||
|
||||
world |means |世|界
|
||||
↑
|
||||
cond#2
|
||||
-------------------utf8->ascii--------------
|
||||
世|界|是|world
|
||||
| ↑
|
||||
↑ cond#4
|
||||
cond#3
|
||||
世|界|是 |world
|
||||
| ↑
|
||||
↑ cond#2
|
||||
cond#3
|
||||
]]
|
||||
|
||||
-- we can break after str[cursor]
|
||||
local word = sub(str, word_begin_index, cursor)
|
||||
|
||||
local colorFiltered = EID:filterColorMarkup(word, EID:getTextColor())
|
||||
local filteredWord = {}
|
||||
for _, filtered in ipairs(colorFiltered) do
|
||||
table.insert(filteredWord, filtered[1])
|
||||
end
|
||||
local strFiltered, spriteTable = EID:filterIconMarkup(table.concat(filteredWord), 0, 0)
|
||||
local wordLength = EID:getStrWidth(strFiltered)
|
||||
|
||||
if curLength + wordLength <= textboxWidth or curLength < 12 then
|
||||
table.insert(text, word)
|
||||
curLength = curLength + wordLength
|
||||
else
|
||||
table.insert(formatedLines, table.concat(text))
|
||||
text = { word }
|
||||
curLength = wordLength
|
||||
end
|
||||
|
||||
-- next word starts here
|
||||
word_begin_index = cursor + 1
|
||||
end
|
||||
cursor = cursor + 1
|
||||
end
|
||||
table.insert(formatedLines, text)
|
||||
|
||||
table.insert(formatedLines, table.concat(text))
|
||||
return formatedLines
|
||||
end
|
||||
|
||||
@@ -1041,6 +1111,7 @@ function EID:fixDefinedFont()
|
||||
end
|
||||
EID.Config["FontType"] = EID.descriptions[curLang].fonts[1].name
|
||||
EID.lineHeight = EID.descriptions[curLang].fonts[1].lineHeight
|
||||
EID.Config["TextboxWidth"] = EID.descriptions[curLang].fonts[1].textboxWidth
|
||||
return true
|
||||
end
|
||||
|
||||
|
||||
@@ -498,3 +498,7 @@ EID.GoldenTrinketData = {
|
||||
-- Lil Clot, Swallowed M80, The Twins (default text), Cricket Leg (17%, 1 in 6), Apollyon's Best Friend, Broken Glasses
|
||||
[176] = 1, [178] = {t={50},mult=2}, [183] = 0, [185] = 17, [186] = 1, [187] = {t={50,50}, mult=2},
|
||||
}
|
||||
|
||||
EID.BreakUtf8CharsLanguage = {
|
||||
['zh_cn'] = true
|
||||
}
|
||||
@@ -517,7 +517,7 @@ function EID:printBulletPoints(description, renderPos)
|
||||
local textScale = Vector(EID.Scale, EID.Scale)
|
||||
description = EID:replaceShortMarkupStrings(description)
|
||||
for line in string.gmatch(description, "([^#]+)") do
|
||||
local formatedLines = EID:fitTextToWidth(line, textboxWidth)
|
||||
local formatedLines = EID:fitTextToWidth(line, textboxWidth, EID.BreakUtf8CharsLanguage[EID.Config["Language"]])
|
||||
local textColor = EID:getTextColor()
|
||||
for i, lineToPrint in ipairs(formatedLines) do
|
||||
-- render bulletpoint
|
||||
|
||||
@@ -1014,6 +1014,7 @@ if MCMLoaded then
|
||||
OnChange = function(currentNum)
|
||||
EID.Config["FontType"] = fontNames[currentNum]
|
||||
EID.lineHeight = fonts[currentNum].lineHeight
|
||||
EID.Config["TextboxWidth"] = fonts[currentNum].textboxWidth
|
||||
EID:fixDefinedFont()
|
||||
local fontFile = EID.Config["FontType"] or "default"
|
||||
EID:loadFont(EID.modPath .. "resources/font/eid_"..fontFile..".fnt")
|
||||
|
||||
Reference in new issue
Block a user