using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Serialization; using System.Runtime.Versioning; using Microsoft.CodeAnalysis; using TMPro; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("greycsont")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyDescription("font_no_tsubasa — A lib to load font into TMP_FontAsset and Font at Unity's runtime")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+a9ec3a53eb7807e0c8b326310f53a9d09061c7f9")] [assembly: AssemblyProduct("FNT")] [assembly: AssemblyTitle("FNT")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace FNT { public static class FontLoader { private static readonly Assembly s_fontEngineAssembly = AppDomain.CurrentDomain.GetAssemblies().Last((Assembly a) => a.GetName().Name == "UnityEngine.TextCoreFontEngineModule"); private static readonly Assembly s_tmpAssembly = AppDomain.CurrentDomain.GetAssemblies().Last((Assembly a) => a.GetName().Name == "Unity.TextMeshPro"); private static readonly Type s_fontEngineType = s_fontEngineAssembly.GetType("UnityEngine.TextCore.LowLevel.FontEngine"); private static readonly Type s_tmpFontAssetType = s_tmpAssembly.GetType("TMPro.TMP_FontAsset"); private static readonly MethodInfo s_initFontEngine = s_fontEngineType.GetMethod("InitializeFontEngine", BindingFlags.Static | BindingFlags.Public); private static readonly MethodInfo s_loadFontFacePath = Array.Find(s_fontEngineType.GetMethods(BindingFlags.Static | BindingFlags.Public), delegate(MethodInfo m) { int result; if (m.Name == "LoadFontFace") { ParameterInfo[] parameters = m.GetParameters(); if (parameters.Length == 1) { result = ((parameters[0].ParameterType == typeof(string)) ? 1 : 0); goto IL_0039; } } result = 0; goto IL_0039; IL_0039: return (byte)result != 0; }); private static readonly MethodInfo s_setFaceSize = s_fontEngineType.GetMethod("SetFaceSize", BindingFlags.Static | BindingFlags.Public); private static readonly MethodInfo s_getFaceInfo = s_fontEngineType.GetMethod("GetFaceInfo", BindingFlags.Static | BindingFlags.Public); private static readonly BindingFlags s_flags = BindingFlags.Instance | BindingFlags.NonPublic; private static readonly FieldInfo s_glyphTableField = s_tmpFontAssetType.GetField("m_GlyphTable", s_flags); private static readonly FieldInfo s_freeGlyphRectsField = s_tmpFontAssetType.GetField("m_FreeGlyphRects", s_flags); private static readonly Type s_glyphType = s_glyphTableField.FieldType.GetGenericArguments()[0]; private static readonly Type s_glyphRectType = s_freeGlyphRectsField.FieldType.GetGenericArguments()[0]; private static readonly Type s_glyphListType = typeof(List<>).MakeGenericType(s_glyphType); private static readonly Type s_glyphRectListType = typeof(List<>).MakeGenericType(s_glyphRectType); private static readonly MethodInfo s_initDictLookup = s_tmpFontAssetType.GetMethod("InitializeDictionaryLookupTables", s_flags); private static readonly MethodInfo s_addSynthesized = s_tmpFontAssetType.GetMethod("AddSynthesizedCharactersAndFaceMetrics", s_flags); public static TMP_FontAsset CreateFontAssetFromFile(string path, int samplingPointSize = 90, int atlasPadding = 9, int atlasWidth = 1024, int atlasHeight = 1024) { //IL_0439: Unknown result type (might be due to invalid IL or missing references) //IL_0440: Expected O, but got Unknown //IL_0493: Unknown result type (might be due to invalid IL or missing references) //IL_049a: Expected O, but got Unknown s_initFontEngine.Invoke(null, null); object obj = s_loadFontFacePath.Invoke(null, new object[1] { path }); if (obj is int num && num != 0) { Debug.LogError((object)$"LoadFontFace failed: {obj}"); return null; } s_setFaceSize.Invoke(null, new object[1] { samplingPointSize }); object obj2 = s_getFaceInfo.Invoke(null, null); object obj3 = obj2.GetType().GetProperty("familyName")?.GetValue(obj2); Debug.Log((object)$"FaceInfo familyName: {obj3}, pointSize: {samplingPointSize}"); TMP_FontAsset val = ScriptableObject.CreateInstance(); ((Object)val).name = (string)obj3; Type type = s_fontEngineAssembly.GetType("UnityEngine.TextCore.LowLevel.GlyphRenderMode"); object value = Enum.Parse(type, "SDFAA"); Type type2 = s_tmpAssembly.GetType("TMPro.AtlasPopulationMode"); object value2 = Enum.Parse(type2, "Dynamic"); object obj4 = Activator.CreateInstance(s_glyphRectType, 0, 0, atlasWidth - 1, atlasHeight - 1); object obj5 = Activator.CreateInstance(s_glyphRectListType); s_glyphRectListType.GetMethod("Add").Invoke(obj5, new object[1] { obj4 }); s_tmpFontAssetType.GetField("m_Version", s_flags).SetValue(val, "1.1.0"); s_tmpFontAssetType.GetField("m_FaceInfo", s_flags).SetValue(val, obj2); s_tmpFontAssetType.GetField("m_AtlasPopulationMode", s_flags).SetValue(val, value2); s_tmpFontAssetType.GetField("m_AtlasWidth", s_flags).SetValue(val, atlasWidth); s_tmpFontAssetType.GetField("m_AtlasHeight", s_flags).SetValue(val, atlasHeight); s_tmpFontAssetType.GetField("m_AtlasPadding", s_flags).SetValue(val, atlasPadding); s_tmpFontAssetType.GetField("m_AtlasRenderMode", s_flags).SetValue(val, value); s_tmpFontAssetType.GetField("m_IsMultiAtlasTexturesEnabled", s_flags).SetValue(val, true); s_tmpFontAssetType.GetField("m_GlyphTable", s_flags).SetValue(val, Activator.CreateInstance(s_glyphListType)); s_tmpFontAssetType.GetField("m_CharacterTable", s_flags).SetValue(val, new List()); s_tmpFontAssetType.GetField("m_UsedGlyphRects", s_flags).SetValue(val, Activator.CreateInstance(s_glyphRectListType)); s_tmpFontAssetType.GetField("m_FreeGlyphRects", s_flags).SetValue(val, obj5); s_tmpFontAssetType.GetField("m_GlyphsToRender", s_flags).SetValue(val, Activator.CreateInstance(s_glyphListType)); s_tmpFontAssetType.GetField("m_GlyphsRendered", s_flags).SetValue(val, Activator.CreateInstance(s_glyphListType)); s_tmpFontAssetType.GetField("m_GlyphIndexList", s_flags).SetValue(val, new List()); s_tmpFontAssetType.GetField("m_GlyphIndexListNewlyAdded", s_flags).SetValue(val, new List()); s_tmpFontAssetType.GetField("m_GlyphsToAdd", s_flags).SetValue(val, new List()); s_tmpFontAssetType.GetField("m_GlyphsToAddLookup", s_flags).SetValue(val, new HashSet()); s_tmpFontAssetType.GetField("m_CharactersToAdd", s_flags).SetValue(val, new List()); s_tmpFontAssetType.GetField("m_CharactersToAddLookup", s_flags).SetValue(val, new HashSet()); s_tmpFontAssetType.GetField("m_MissingUnicodesFromFontFile", s_flags).SetValue(val, new HashSet()); Texture2D val2 = new Texture2D(atlasWidth, atlasHeight, (TextureFormat)1, false); s_tmpFontAssetType.GetField("m_AtlasTexture", s_flags).SetValue(val, val2); s_tmpFontAssetType.GetField("m_AtlasTextures", s_flags).SetValue(val, new Texture2D[1] { val2 }); Shader val3 = Shader.Find("TextMeshPro/Distance Field"); Material val4 = new Material(val3); val4.SetTexture(ShaderUtilities.ID_MainTex, (Texture)(object)val2); val4.SetFloat(ShaderUtilities.ID_TextureWidth, (float)atlasWidth); val4.SetFloat(ShaderUtilities.ID_TextureHeight, (float)atlasHeight); val4.SetFloat(ShaderUtilities.ID_GradientScale, (float)(atlasPadding + 1)); val4.SetFloat(ShaderUtilities.ID_WeightNormal, val.normalStyle); val4.SetFloat(ShaderUtilities.ID_WeightBold, val.boldStyle); ((TMP_Asset)val).material = val4; s_initDictLookup?.Invoke(val, null); s_addSynthesized?.Invoke(val, null); Font value3 = CreateFontFromFile(path); s_tmpFontAssetType.GetField("m_SourceFontFile", s_flags).SetValue(val, value3); return val; } public static Font CreateFontFromFile(string path) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Expected O, but got Unknown MethodInfo method = typeof(Font).GetMethod("Internal_CreateFontFromPath", BindingFlags.Static | BindingFlags.NonPublic); Font val = (Font)FormatterServices.GetUninitializedObject(typeof(Font)); method.Invoke(null, new object[2] { val, path }); return val; } } }