Import Cryville.Culture in favor of ScriptUtils.
This commit is contained in:
@@ -1,8 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 520554ce9a8205b4b91e0ff2b8011673
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
File diff suppressed because one or more lines are too long
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ae9dab8f520fadc4194032f523ca87c1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,4 +1,5 @@
|
||||
using Cryville.Common.Culture;
|
||||
using Cryville.Common.Logging;
|
||||
using Cryville.Culture;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
@@ -7,13 +8,15 @@ namespace Cryville.Common.Font {
|
||||
public abstract class FontMatcher {
|
||||
protected FontManager Manager { get; private set; }
|
||||
public FontMatcher(FontManager manager) { Manager = manager; }
|
||||
public abstract IEnumerable<Typeface> MatchScript(string script = null, bool distinctFamily = false);
|
||||
public abstract IEnumerable<Typeface> MatchLanguage(LanguageId lang, bool distinctFamily = false);
|
||||
}
|
||||
public class FallbackListFontMatcher : FontMatcher {
|
||||
readonly LanguageMatching _matcher;
|
||||
static readonly string UltimateFallbackScript = "zyyy";
|
||||
public Dictionary<string, List<string>> MapScriptToTypefaces = new Dictionary<string, List<string>>();
|
||||
public static Dictionary<string, List<string>> GetDefaultWindowsFallbackMap() {
|
||||
var map = new Dictionary<string, List<string>>();
|
||||
ScriptUtils.FillKeysWithScripts(map, () => new List<string>());
|
||||
var map = new Dictionary<string, List<string>>(StringComparer.OrdinalIgnoreCase);
|
||||
FillKeysWithScripts(map, () => new List<string>());
|
||||
// Reference: https://github.com/chromium/chromium/blob/main/third_party/blink/renderer/platform/fonts/win/font_fallback_win.cc
|
||||
map["zyyy"].Insert(0, "SimSun"); // Custom
|
||||
map["zyyy"].Insert(0, "SimHei"); // Custom
|
||||
@@ -158,8 +161,8 @@ namespace Cryville.Common.Font {
|
||||
return map;
|
||||
}
|
||||
public static Dictionary<string, List<string>> GetDefaultAndroidFallbackMap() {
|
||||
var map = new Dictionary<string, List<string>>();
|
||||
ScriptUtils.FillKeysWithScripts(map, () => new List<string>());
|
||||
var map = new Dictionary<string, List<string>>(StringComparer.OrdinalIgnoreCase);
|
||||
FillKeysWithScripts(map, () => new List<string>());
|
||||
map["zyyy"].Insert(0, "Noto Sans CJK TC"); // TODO Modify default fallback
|
||||
map["zyyy"].Insert(0, "Noto Sans CJK JP");
|
||||
map["zyyy"].Insert(0, "Noto Sans CJK SC");
|
||||
@@ -275,9 +278,9 @@ namespace Cryville.Common.Font {
|
||||
map["sund"].Insert(0, "Noto Sans Sundanese");
|
||||
map["sylo"].Insert(0, "Noto Sans Syloti Nagri");
|
||||
map["zsym"].Insert(0, "Noto Sans Symbols");
|
||||
map["syrn"].Insert(0, "Noto Sans Syriac Eastern");
|
||||
map["syre"].Insert(0, "Noto Sans Syriac Estrangela");
|
||||
map["syrj"].Insert(0, "Noto Sans Syriac Western");
|
||||
map["syrc"].Add("Noto Sans Syriac Eastern");
|
||||
map["syrc"].Add("Noto Sans Syriac Western");
|
||||
map["syrc"].Add("Noto Sans Syriac Estrangela");
|
||||
map["tglg"].Insert(0, "Noto Sans Tagalog");
|
||||
map["tagb"].Insert(0, "Noto Sans Tagbanwa");
|
||||
map["tale"].Insert(0, "Noto Sans Tai Le");
|
||||
@@ -296,33 +299,45 @@ namespace Cryville.Common.Font {
|
||||
map["yiii"].Insert(0, "Noto Sans Yi");
|
||||
return map;
|
||||
}
|
||||
public FallbackListFontMatcher(FontManager manager) : base(manager) { }
|
||||
public override IEnumerable<Typeface> MatchScript(string script = null, bool distinctFamily = false) {
|
||||
if (string.IsNullOrEmpty(script)) script = ScriptUtils.UltimateFallbackScript;
|
||||
List<string> candidates;
|
||||
IEnumerable<string> candidateScripts = new string[] { script };
|
||||
while (candidateScripts != null) {
|
||||
foreach (var candidateScript in candidateScripts) {
|
||||
if (MapScriptToTypefaces.TryGetValue(candidateScript, out candidates)) {
|
||||
foreach (var candidate in candidates) {
|
||||
IReadOnlyCollection<Typeface> typefaces1;
|
||||
if (Manager.MapFullNameToTypeface.TryGetValue(candidate, out typefaces1)) {
|
||||
foreach (var typeface in typefaces1) {
|
||||
yield return typeface;
|
||||
}
|
||||
}
|
||||
if (distinctFamily) continue;
|
||||
IReadOnlyCollection<Typeface> typefaces2;
|
||||
if (Manager.MapNameToTypefaces.TryGetValue(candidate, out typefaces2)) {
|
||||
foreach (var typeface in typefaces2) {
|
||||
if (typefaces1.Contains(typeface)) continue;
|
||||
yield return typeface;
|
||||
}
|
||||
}
|
||||
}
|
||||
static void FillKeysWithScripts<T>(IDictionary<string, T> map, Func<T> value) {
|
||||
foreach (var s in IdValidity.Enumerate("script")) map.Add(s, value());
|
||||
}
|
||||
|
||||
public FallbackListFontMatcher(LanguageMatching matcher, FontManager manager) : base(manager) {
|
||||
_matcher = matcher;
|
||||
}
|
||||
public override IEnumerable<Typeface> MatchLanguage(LanguageId lang, bool distinctFamily = false) {
|
||||
var supported = MapScriptToTypefaces.Keys.Select(i => new LanguageId(i)).ToList();
|
||||
while (_matcher.Match(lang, supported, out var match, out var distance)) {
|
||||
if (distance > 40) break;
|
||||
Logger.Log("main", 0, "UI", "Matching fonts for language {0}, distance = {1}", match, distance);
|
||||
var candidates = MapScriptToTypefaces[match.Script.ToLowerInvariant()];
|
||||
foreach (var typeface in EnumerateTypefaces(candidates, distinctFamily)) {
|
||||
yield return typeface;
|
||||
}
|
||||
supported.Remove(match);
|
||||
}
|
||||
Logger.Log("main", 0, "UI", "Matching fallback fonts");
|
||||
foreach (var typeface in EnumerateTypefaces(MapScriptToTypefaces[UltimateFallbackScript], distinctFamily)) {
|
||||
yield return typeface;
|
||||
}
|
||||
}
|
||||
IEnumerable<Typeface> EnumerateTypefaces(List<string> candidates, bool distinctFamily) {
|
||||
foreach (var candidate in candidates) {
|
||||
IReadOnlyCollection<Typeface> typefaces1;
|
||||
if (Manager.MapFullNameToTypeface.TryGetValue(candidate, out typefaces1)) {
|
||||
foreach (var typeface in typefaces1) {
|
||||
yield return typeface;
|
||||
}
|
||||
}
|
||||
if (distinctFamily) continue;
|
||||
IReadOnlyCollection<Typeface> typefaces2;
|
||||
if (Manager.MapNameToTypefaces.TryGetValue(candidate, out typefaces2)) {
|
||||
foreach (var typeface in typefaces2) {
|
||||
if (typefaces1.Contains(typeface)) continue;
|
||||
yield return typeface;
|
||||
}
|
||||
}
|
||||
candidateScripts = ScriptUtils.EnumerateFallbackScripts(script);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
using Cryville.Common.Font;
|
||||
using Cryville.Culture;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Reflection;
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
@@ -23,7 +25,7 @@ namespace Cryville.Common.Unity.UI {
|
||||
if (FontMatcher == null) return;
|
||||
_text = GetComponent<TextMeshProUGUI>();
|
||||
if (_font == null) {
|
||||
foreach (var typeface in FontMatcher.MatchScript(null, true)) {
|
||||
foreach (var typeface in FontMatcher.MatchLanguage(new LanguageId(CultureInfo.CurrentCulture.Name), true)) {
|
||||
try {
|
||||
var ifont = CreateFontAsset(typeface.File.FullName, typeface.IndexInFile);
|
||||
if (m_shader) ifont.material.shader = m_shader;
|
||||
|
||||
@@ -5,6 +5,7 @@ using Cryville.Common.Logging;
|
||||
using Cryville.Common.Unity;
|
||||
using Cryville.Common.Unity.UI;
|
||||
using Cryville.Crtr.UI;
|
||||
using Cryville.Culture;
|
||||
using Cryville.Input;
|
||||
using Cryville.Input.Unity;
|
||||
#if UNITY_ANDROID && !UNITY_EDITOR
|
||||
@@ -18,6 +19,9 @@ using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Xml;
|
||||
using System.Xml.Linq;
|
||||
using UnityEngine;
|
||||
using Logger = Cryville.Common.Logging.Logger;
|
||||
using unity = UnityEngine;
|
||||
@@ -61,7 +65,7 @@ namespace Cryville.Crtr {
|
||||
Logger.Log("main", 1, "Game", "Culture: {0}, UI = {1}, System = {2}, Unity = {3}", CultureInfo.CurrentCulture, CultureInfo.CurrentUICulture, CultureInfo.InstalledUICulture, Application.systemLanguage);
|
||||
|
||||
if (_bcflag) Logger.Log("main", 2, "Game", "Reset all settings");
|
||||
|
||||
|
||||
GameDataPath = Settings.Default.GameDataPath;
|
||||
UnityDataPath = Application.dataPath;
|
||||
|
||||
@@ -153,7 +157,13 @@ namespace Cryville.Crtr {
|
||||
Settings.Default.Save();
|
||||
|
||||
Logger.Log("main", 1, "UI", "Initializing font manager");
|
||||
TMPAutoFont.FontMatcher = new FallbackListFontMatcher(PlatformConfig.FontManager) {
|
||||
foreach (var res in Resources.LoadAll<TextAsset>("cldr/common/validity")) {
|
||||
IdValidity.Load(LoadXmlDocument(res));
|
||||
}
|
||||
var metadata = new SupplementalMetadata(LoadXmlDocument("cldr/common/supplemental/supplementalMetadata"));
|
||||
var subtags = new LikelySubtags(LoadXmlDocument("cldr/common/supplemental/likelySubtags"), metadata);
|
||||
var matcher = new LanguageMatching(LoadXmlDocument("cldr/common/supplemental/languageInfo"), subtags);
|
||||
TMPAutoFont.FontMatcher = new FallbackListFontMatcher(matcher, PlatformConfig.FontManager) {
|
||||
MapScriptToTypefaces = PlatformConfig.ScriptFontMap
|
||||
};
|
||||
TMPAutoFont.DefaultShader = Resources.Load<Shader>(PlatformConfig.TextShader);
|
||||
@@ -161,6 +171,21 @@ namespace Cryville.Crtr {
|
||||
Logger.Log("main", 1, "Game", "Initialized");
|
||||
}
|
||||
|
||||
static readonly Encoding _encoding = new UTF8Encoding(false, true);
|
||||
static readonly XmlReaderSettings _xmlSettings = new XmlReaderSettings {
|
||||
DtdProcessing = DtdProcessing.Ignore,
|
||||
};
|
||||
static XDocument LoadXmlDocument(string path) {
|
||||
return LoadXmlDocument(Resources.Load<TextAsset>(path));
|
||||
}
|
||||
static XDocument LoadXmlDocument(TextAsset asset) {
|
||||
using (var stream = new MemoryStream(_encoding.GetBytes(asset.text))) {
|
||||
using (var reader = XmlReader.Create(stream, _xmlSettings)) {
|
||||
return XDocument.Load(reader);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool _shutdown;
|
||||
public static void Shutdown() {
|
||||
if (_shutdown) return;
|
||||
|
||||
@@ -13,12 +13,12 @@ namespace Cryville.Crtr {
|
||||
#if UNITY_STANDALONE_WIN || UNITY_EDITOR_WIN
|
||||
public static readonly string FileProtocolPrefix = "file:///";
|
||||
public static readonly FontManager FontManager = new FontManagerWindows();
|
||||
public static readonly Dictionary<string, List<string>> ScriptFontMap = FallbackListFontMatcher.GetDefaultWindowsFallbackMap();
|
||||
public static Dictionary<string, List<string>> ScriptFontMap => FallbackListFontMatcher.GetDefaultWindowsFallbackMap();
|
||||
public static readonly string TextShader = "TextMesh Pro/Shaders/TMP_SDF SSD";
|
||||
#elif UNITY_ANDROID
|
||||
public static readonly string FileProtocolPrefix = "file://";
|
||||
public static readonly FontManager FontManager = new FontManagerAndroid();
|
||||
public static readonly Dictionary<string, List<string>> ScriptFontMap = FallbackListFontMatcher.GetDefaultAndroidFallbackMap();
|
||||
public static Dictionary<string, List<string>> ScriptFontMap => FallbackListFontMatcher.GetDefaultAndroidFallbackMap();
|
||||
public static readonly string TextShader = "TextMesh Pro/Shaders/TMP_SDF-Mobile SSD";
|
||||
#else
|
||||
#error Unknown platform.
|
||||
|
||||
Reference in New Issue
Block a user