diff --git a/Assets/Cryville/Common/Unity/UI/TMPAutoFont.cs b/Assets/Cryville/Common/Unity/UI/TMPAutoFont.cs index 12fd7f3..f3c9a47 100644 --- a/Assets/Cryville/Common/Unity/UI/TMPAutoFont.cs +++ b/Assets/Cryville/Common/Unity/UI/TMPAutoFont.cs @@ -1,17 +1,18 @@ using Cryville.Common.Font; using System; +using System.Collections.Generic; using System.Reflection; using TMPro; using UnityEngine; using UnityEngine.TextCore.LowLevel; using UnityEngine.TextCore.Text; -using IFont = UnityEngine.Font; namespace Cryville.Common.Unity.UI { [RequireComponent(typeof(TextMeshProUGUI))] public class TMPAutoFont : MonoBehaviour { public static Shader DefaultShader; public static FontMatcher FontMatcher; + public static int MaxFallbackCount = 4; static FontAsset _font; TextMeshProUGUI _text; @@ -23,17 +24,43 @@ namespace Cryville.Common.Unity.UI { if (_font == null) { foreach (var typeface in FontMatcher.MatchScript(null, true)) { try { - var _ifont = new IFont(typeface.File.FullName); - _font = (FontAsset)typeof(FontAsset).GetMethod("CreateFontAsset", BindingFlags.Static | BindingFlags.NonPublic, null, new Type[] { typeof(IFont), typeof(int), typeof(int), typeof(int), typeof(GlyphRenderMode), typeof(int), typeof(int), typeof(AtlasPopulationMode), typeof(bool) }, - null).Invoke(null, new object[] { _ifont, typeface.IndexInFile, 90, 9, GlyphRenderMode.SDFAA, 1024, 1024, Type.Missing, Type.Missing }); - break; + var ifont = CreateFontAsset(typeface.File.FullName, typeface.IndexInFile); + if (m_shader) ifont.material.shader = m_shader; + else if (DefaultShader) ifont.material.shader = DefaultShader; + if (_font == null) { + _font = ifont; + if (MaxFallbackCount <= 0) break; + } + else { + if (_font.fallbackFontAssetTable == null) + _font.fallbackFontAssetTable = new List(); + _font.fallbackFontAssetTable.Add(ifont); + if (_font.fallbackFontAssetTable.Count >= MaxFallbackCount) break; + } } catch (Exception) { } } } _text.font = _font; - if (m_shader) _font.material.shader = m_shader; - else if (DefaultShader) _font.material.shader = DefaultShader; + } + + static MethodInfo _methodCreateFontAsset; + static object[] _paramsCreateFontAsset = new object[] { null, null, 90, 9, GlyphRenderMode.SDFAA, 1024, 1024, Type.Missing, Type.Missing }; + static FontAsset CreateFontAsset(string path, int index) { + if (_methodCreateFontAsset == null) { + _methodCreateFontAsset = typeof(FontAsset).GetMethod( + "CreateFontAsset", BindingFlags.Static | BindingFlags.NonPublic, null, + new Type[] { + typeof(string), typeof(int), typeof(int), typeof(int), + typeof(GlyphRenderMode), typeof(int), typeof(int), + typeof(AtlasPopulationMode), typeof(bool) + }, + null + ); + } + _paramsCreateFontAsset[0] = path; + _paramsCreateFontAsset[1] = index; + return (FontAsset)_methodCreateFontAsset.Invoke(null, _paramsCreateFontAsset); } } }