Add fallback logic for TMP auto font.

This commit is contained in:
2023-02-05 15:55:53 +08:00
parent 84b7a6d183
commit 1711fbadf7

View File

@@ -1,17 +1,18 @@
using Cryville.Common.Font; using Cryville.Common.Font;
using System; using System;
using System.Collections.Generic;
using System.Reflection; using System.Reflection;
using TMPro; using TMPro;
using UnityEngine; using UnityEngine;
using UnityEngine.TextCore.LowLevel; using UnityEngine.TextCore.LowLevel;
using UnityEngine.TextCore.Text; using UnityEngine.TextCore.Text;
using IFont = UnityEngine.Font;
namespace Cryville.Common.Unity.UI { namespace Cryville.Common.Unity.UI {
[RequireComponent(typeof(TextMeshProUGUI))] [RequireComponent(typeof(TextMeshProUGUI))]
public class TMPAutoFont : MonoBehaviour { public class TMPAutoFont : MonoBehaviour {
public static Shader DefaultShader; public static Shader DefaultShader;
public static FontMatcher FontMatcher; public static FontMatcher FontMatcher;
public static int MaxFallbackCount = 4;
static FontAsset _font; static FontAsset _font;
TextMeshProUGUI _text; TextMeshProUGUI _text;
@@ -23,17 +24,43 @@ namespace Cryville.Common.Unity.UI {
if (_font == null) { if (_font == null) {
foreach (var typeface in FontMatcher.MatchScript(null, true)) { foreach (var typeface in FontMatcher.MatchScript(null, true)) {
try { try {
var _ifont = new IFont(typeface.File.FullName); var ifont = CreateFontAsset(typeface.File.FullName, typeface.IndexInFile);
_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) }, if (m_shader) ifont.material.shader = m_shader;
null).Invoke(null, new object[] { _ifont, typeface.IndexInFile, 90, 9, GlyphRenderMode.SDFAA, 1024, 1024, Type.Missing, Type.Missing }); else if (DefaultShader) ifont.material.shader = DefaultShader;
break; if (_font == null) {
_font = ifont;
if (MaxFallbackCount <= 0) break;
}
else {
if (_font.fallbackFontAssetTable == null)
_font.fallbackFontAssetTable = new List<FontAsset>();
_font.fallbackFontAssetTable.Add(ifont);
if (_font.fallbackFontAssetTable.Count >= MaxFallbackCount) break;
}
} }
catch (Exception) { } catch (Exception) { }
} }
} }
_text.font = _font; _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);
} }
} }
} }