Разрабатывая
приложения очень часто встает вопрос с локализацией его. Кто-то делает только
английскую версию, кто-то добавляет русский язык, а кто-то делает сразу под
множество языков.
Рассказывать,
что нужно сразу все строковые данные выносить в файл ресурсов, если подразумевается
в дальнейшем локализация на другие языки, думаю не кому не нужно. А вот с
шрифтами в XNA возникает небольшая проблема. Стандартный файл шрифта, в XNA с
расширением .spritefont имеет
<Start> </Start>
<End>~</End>
</CharacterRegion>
и пока используются
только символы из английского языка и без вывода специальных символов все
хорошо, а дальше ждет сюрприз. В целом не чего сложного нет, как я уже писал в
статье «Рисование дополнительных символов XNA» делается все довольно просто. Но вот с добавлением в свое приложение
нескольких языков не все так просто, а по описанному выше способу это вообще
титанический труд, я решил немного упростить этот вопрос для себя.
Перевод
готов, файлы ресурсов готовы.
Пихать все
символы в файл шрифта не стоит, лично я гружу только необходимый файл шрифта в
зависимости от текущей культуры или культуры по умолчанию.
По мимо
этого, нужно отредактировать файл .spritefont для определенной культуры.
Для начала,
получаем строки из файла ресурсов и добавляем символы которых нету в ресурсах,
в моем случае это цифры и спец символы, также у меня в коде строки могут
принимать верхний и нижний регистр.
private IEnumerable<string> GetStringsValue(CultureInfo culture)
{
var resourceSet = AppResources.ResourceManager.GetResourceSet(culture, true, true);
var value = new List<string>();
foreach (DictionaryEntry entry in resourceSet)
{
var resource = (string) entry.Value;
value.Add(resource);
value.Add(resource.ToLower());
value.Add(resource.ToUpper());
}
value.Add("1234567890-=_+)(*&^%$#@!:;\"'/,.<>№[]{}~`");
return value;
}
private IEnumerable<string> GetStringsValue(CultureInfo culture)
{
var resourceSet = AppResources.ResourceManager.GetResourceSet(culture, true, true);
var value = new List<string>();
foreach (DictionaryEntry entry in resourceSet)
{
var resource = (string) entry.Value;
value.Add(resource);
value.Add(resource.ToLower());
value.Add(resource.ToUpper());
}
value.Add("1234567890-=_+)(*&^%$#@!:;\"'/,.<>№[]{}~`");
return value;
}
После чего, для
каждой поддерживаемой культуры формируем список символов и если возможно мы их объединяем.
public void CreateRangeCharacters()
{
Debug.WriteLine("Start create range characters:");
foreach (var cultureItem in _supportedCultures)
{
Debug.WriteLine("Culture start: " + (string.IsNullOrEmpty(cultureItem) ?
"default" : cultureItem));
var culture = new CultureInfo("en");
if (!string.IsNullOrEmpty(cultureItem))
{
culture = new CultureInfo(cultureItem);
}
var characters = new List<char>();
var resources = GetStringsValue(culture);
foreach (var resource in resources)
{
foreach (var item in resource)
{
if (!characters.Contains(item))
{
characters.Add(item);
}
}
}
characters = characters.OrderBy(s => s).ToList();
var array = string.Join(" ", characters.Select(PrintChar));
Debug.WriteLine("Characters: ");
Debug.WriteLine(array);
/*Объединение*/
Debug.WriteLine(" <CharacterRegions>");
var oldValue = characters[0];
var value = PrintChar(oldValue);
var isFurther = false;
for (var i = 1; i < characters.Count; i++)
{
if (characters[i] - oldValue <= 1)
{
if (!isFurther)
{
Debug.WriteLine(" <CharacterRegion>");
Debug.WriteLine(" <Start>&#" + PrintChar(oldValue) + ";</Start>");
isFurther = true;
}
}
else
{
if (isFurther)
{
isFurther = false;
Debug.WriteLine(" <End>&#" + PrintChar(oldValue) + ";</End>");
Debug.WriteLine(" </CharacterRegion>");
}
else
{
if (!string.IsNullOrEmpty(value))
{
Debug.WriteLine(" <CharacterRegion>");
Debug.WriteLine(" <Start>&#" + value + ";</Start>");
Debug.WriteLine(" <End>&#" + value + ";</End>");
Debug.WriteLine(" </CharacterRegion>");
}
}
value = PrintChar(characters[i]);
}
oldValue = characters[i];
}
if (!string.IsNullOrEmpty(value))
{
Debug.WriteLine(" <CharacterRegion>");
Debug.WriteLine(" <Start>&#" + value + ";</Start>");
Debug.WriteLine(" <End>&#" + value + ";</End>");
Debug.WriteLine(" </CharacterRegion>");
}
Debug.WriteLine(" </CharacterRegions>");
Debug.WriteLine("Culture end!");
}
Debug.WriteLine("End create range characters!");
}
private static string PrintChar(char c)
{
var value = (int)c;
return value.ToString(CultureInfo.InvariantCulture);
}
public void CreateRangeCharacters()
{
Debug.WriteLine("Start create range characters:");
foreach (var cultureItem in _supportedCultures)
{
Debug.WriteLine("Culture start: " + (string.IsNullOrEmpty(cultureItem) ?
"default" : cultureItem));
var culture = new CultureInfo("en");
if (!string.IsNullOrEmpty(cultureItem))
{
culture = new CultureInfo(cultureItem);
}
var characters = new List<char>();
var resources = GetStringsValue(culture);
foreach (var resource in resources)
{
foreach (var item in resource)
{
if (!characters.Contains(item))
{
characters.Add(item);
}
}
}
characters = characters.OrderBy(s => s).ToList();
var array = string.Join(" ", characters.Select(PrintChar));
Debug.WriteLine("Characters: ");
Debug.WriteLine(array);
/*Объединение*/
Debug.WriteLine(" <CharacterRegions>");
var oldValue = characters[0];
var value = PrintChar(oldValue);
var isFurther = false;
for (var i = 1; i < characters.Count; i++)
{
if (characters[i] - oldValue <= 1)
{
if (!isFurther)
{
Debug.WriteLine(" <CharacterRegion>");
Debug.WriteLine(" <Start>&#" + PrintChar(oldValue) + ";</Start>");
isFurther = true;
}
}
else
{
if (isFurther)
{
isFurther = false;
Debug.WriteLine(" <End>&#" + PrintChar(oldValue) + ";</End>");
Debug.WriteLine(" </CharacterRegion>");
}
else
{
if (!string.IsNullOrEmpty(value))
{
Debug.WriteLine(" <CharacterRegion>");
Debug.WriteLine(" <Start>&#" + value + ";</Start>");
Debug.WriteLine(" <End>&#" + value + ";</End>");
Debug.WriteLine(" </CharacterRegion>");
}
}
value = PrintChar(characters[i]);
}
oldValue = characters[i];
}
if (!string.IsNullOrEmpty(value))
{
Debug.WriteLine(" <CharacterRegion>");
Debug.WriteLine(" <Start>&#" + value + ";</Start>");
Debug.WriteLine(" <End>&#" + value + ";</End>");
Debug.WriteLine(" </CharacterRegion>");
}
Debug.WriteLine(" </CharacterRegions>");
Debug.WriteLine("Culture end!");
}
Debug.WriteLine("End create range characters!");
}
private static string PrintChar(char c)
{
var value = (int)c;
return value.ToString(CultureInfo.InvariantCulture);
}
А вот
проверка уже получившихся файлов шрифтов, её следует запускать если были
изменения.
public void TestAllFonts(ContentManager contentManager)
{
Debug.WriteLine("Start test fonts: ");
foreach (var cultureItem in _supportedCultures)
{
Debug.WriteLine("Culture start: " + (string.IsNullOrEmpty(cultureItem) ? "default" : cultureItem));
var count = 0;
foreach (var fontItem in _fonts)
{
var fontPath = "Fonts/" + fontItem;
var culture = new CultureInfo("en");
if (!string.IsNullOrEmpty(cultureItem))
{
fontPath += "." + cultureItem;
culture = new CultureInfo(cultureItem);
}
var font = contentManager.Load<SpriteFont>(fontPath);
var resources = GetStringsValue(culture);
foreach (var resource in resources)
{
foreach (var item in resource)
{
if (!font.Characters.Contains(item))
{
Debug.WriteLine("Error!!! " + PrintChar(item));
}
}
//var size = font.MeasureString(resource);
count++;
}
}
Debug.WriteLine("Culture end count font: " + _fonts.Count + " resource count: " + count/_fonts.Count);
}
Debug.WriteLine("End test fonts!");
}
public void TestAllFonts(ContentManager contentManager)
{
Debug.WriteLine("Start test fonts: ");
foreach (var cultureItem in _supportedCultures)
{
Debug.WriteLine("Culture start: " + (string.IsNullOrEmpty(cultureItem) ? "default" : cultureItem));
var count = 0;
foreach (var fontItem in _fonts)
{
var fontPath = "Fonts/" + fontItem;
var culture = new CultureInfo("en");
if (!string.IsNullOrEmpty(cultureItem))
{
fontPath += "." + cultureItem;
culture = new CultureInfo(cultureItem);
}
var font = contentManager.Load<SpriteFont>(fontPath);
var resources = GetStringsValue(culture);
foreach (var resource in resources)
{
foreach (var item in resource)
{
if (!font.Characters.Contains(item))
{
Debug.WriteLine("Error!!! " + PrintChar(item));
}
}
//var size = font.MeasureString(resource);
count++;
}
}
Debug.WriteLine("Culture end count font: " + _fonts.Count + " resource count: " + count/_fonts.Count);
}
Debug.WriteLine("End test fonts!");
}
Комментариев нет:
Отправить комментарий