feat: Initial commit
This commit is contained in:
80
Assets/Cryville.Common/Unity/UI/TMPLocalizedText.cs
Normal file
80
Assets/Cryville.Common/Unity/UI/TMPLocalizedText.cs
Normal file
@@ -0,0 +1,80 @@
|
||||
using Cryville.Common.Font;
|
||||
using Cryville.Culture;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Reflection;
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
using UnityEngine.TextCore.LowLevel;
|
||||
using UnityEngine.TextCore.Text;
|
||||
|
||||
namespace Cryville.Common.Unity.UI {
|
||||
[RequireComponent(typeof(TMP_Text))]
|
||||
public class TMPLocalizedText : MonoBehaviour {
|
||||
public static Shader DefaultShader;
|
||||
public static FontMatcher FontMatcher;
|
||||
public static int MaxFallbackCount = 4;
|
||||
|
||||
static readonly Dictionary<CultureInfo, FontAsset> _cachedFonts = new();
|
||||
|
||||
[SerializeField]
|
||||
Shader m_shader;
|
||||
|
||||
public TMP_Text Text { get; private set; }
|
||||
void Awake() {
|
||||
Text = GetComponent<TMP_Text>();
|
||||
}
|
||||
|
||||
public void SetText(string text, CultureInfo culture = null) {
|
||||
Text.text = text;
|
||||
SetCulture(culture ?? CultureInfo.CurrentCulture);
|
||||
}
|
||||
|
||||
void SetCulture(CultureInfo culture) {
|
||||
if (FontMatcher == null) return;
|
||||
string cultureName = culture.Name;
|
||||
if (string.IsNullOrEmpty(cultureName)) cultureName = CultureInfo.CurrentCulture.Name;
|
||||
if (!_cachedFonts.TryGetValue(culture, out var font)) {
|
||||
foreach (var typeface in FontMatcher.MatchLanguage(new LanguageId(cultureName), true)) {
|
||||
try {
|
||||
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 {
|
||||
font.fallbackFontAssetTable ??= new List<FontAsset>();
|
||||
font.fallbackFontAssetTable.Add(ifont);
|
||||
if (font.fallbackFontAssetTable.Count >= MaxFallbackCount) break;
|
||||
}
|
||||
}
|
||||
catch (Exception) { }
|
||||
}
|
||||
_cachedFonts.Add(culture, font);
|
||||
}
|
||||
Text.font = font;
|
||||
}
|
||||
|
||||
static MethodInfo _methodCreateFontAsset;
|
||||
static readonly 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);
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user