Decompiled source of CustomFont v0.2.0

plugins/CustomFont.dll

Decompiled 3 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Xml;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using TMProOld;
using TeamCherry.Localization;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.TextCore;
using UnityEngine.TextCore.LowLevel;
using UnityEngine.TextCore.Text;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("CustomFont")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.2.0.0")]
[assembly: AssemblyInformationalVersion("0.2.0+f6089d2ed9a1de5a5394c36872d95fe002da35ef")]
[assembly: AssemblyProduct("CustomFont")]
[assembly: AssemblyTitle("CustomFont")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/CarrieForle/CustomFontSilksong")]
[assembly: NeutralResourcesLanguage("EN")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.2.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[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]
	[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]
	[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 BepInEx
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	[Embedded]
	internal sealed class BepInAutoPluginAttribute : Attribute
	{
		public BepInAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
		{
		}
	}
}
namespace BepInEx.Preloader.Core.Patching
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	[Embedded]
	internal sealed class PatcherAutoPluginAttribute : Attribute
	{
		public PatcherAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
		{
		}
	}
}
namespace Microsoft.CodeAnalysis
{
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace CustomFont
{
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInPlugin("io.github.carrieforle.customfont", "CustomFont", "0.2.0")]
	internal class CustomFontPlugin : BaseUnityPlugin, IDisposable
	{
		internal static ConfigEntry<ReplaceFontMode> configReplaceFontMode;

		internal static ConfigEntry<float> configFontScale;

		private static ConfigEntry<bool> configAllCharsAtlas;

		internal static ManualLogSource logger;

		internal static TMP_FontAsset? fontAsset;

		internal static Dictionary<TextMeshPro, (float FontSize, TMP_FontAsset Font)> oldTMPros = new Dictionary<TextMeshPro, (float, TMP_FontAsset)>();

		internal static bool cfblCanPatch = true;

		private static string[] fontPaths = Array.Empty<string>();

		private static string? currentFontPath;

		private FileSystemWatcher fontWatcher;

		private Harmony harmony;

		public const string Id = "io.github.carrieforle.customfont";

		public static string Name => "CustomFont";

		public static string Version => "0.2.0";

		private void Awake()
		{
			harmony = Harmony.CreateAndPatchAll(typeof(Patch), "io.github.carrieforle.customfont");
			logger = ((BaseUnityPlugin)this).Logger;
			string directoryName = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location);
			fontPaths = new string[2]
			{
				Path.Combine(directoryName, "font.otf"),
				Path.Combine(directoryName, "font.ttf")
			};
			fontWatcher = new FileSystemWatcher(directoryName)
			{
				NotifyFilter = (NotifyFilters.FileName | NotifyFilters.Size | NotifyFilters.LastWrite | NotifyFilters.CreationTime)
			};
			fontWatcher.Changed += delegate(object s, FileSystemEventArgs e)
			{
				OnFileChanged(e.FullPath, e.FullPath);
			};
			fontWatcher.Created += delegate(object s, FileSystemEventArgs e)
			{
				OnFileChanged(null, e.FullPath);
			};
			fontWatcher.Deleted += delegate(object s, FileSystemEventArgs e)
			{
				OnFileChanged(e.FullPath, null);
			};
			fontWatcher.Renamed += delegate(object s, RenamedEventArgs e)
			{
				OnFileChanged(e.OldFullPath, e.FullPath);
			};
			fontWatcher.EnableRaisingEvents = true;
		}

		private void Start()
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			configReplaceFontMode = ((BaseUnityPlugin)this).Config.Bind<ReplaceFontMode>("General", "ReplaceFontMode", ReplaceFontMode.EffectedByLanguage, LocalisedString.op_Implicit(Localized("OPTION_DESCRIPTION_REPLACE_FONT_MODE")));
			configFontScale = ((BaseUnityPlugin)this).Config.Bind<float>("General", "FontScale", 1f, Localized("OPTION_DESCRIPTION_FONT_SCALE", 1));
			configAllCharsAtlas = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "AllCharsAtlas", false, LocalisedString.op_Implicit(Localized("OPTION_DESCRIPTION_ALL_CHARS_ATLAS")));
			configReplaceFontMode.SettingChanged += delegate
			{
				TryUpdateTMPros();
			};
			configFontScale.SettingChanged += delegate
			{
				if (configFontScale.Value <= 0f)
				{
					logger.LogWarning((object)"Invalid font scale. Resetted to 1.");
					configFontScale.Value = 1f;
				}
				TryUpdateTMPros();
			};
			configAllCharsAtlas.SettingChanged += delegate
			{
				currentFontPath = null;
			};
			TryLoadFont();
		}

		private void OnFileChanged(string? oldFilePath, string? newFilePath)
		{
			if (currentFontPath != null && ((oldFilePath != null && fontPaths.Contains<string>(oldFilePath)) || (newFilePath != null && fontPaths.Contains<string>(newFilePath))))
			{
				logger.LogInfo((object)"Detected font file changed. Prepare to reload font.");
				currentFontPath = null;
			}
		}

		public void Dispose()
		{
			fontWatcher.Dispose();
		}

		internal static void TryLoadFont()
		{
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Expected O, but got Unknown
			if (currentFontPath != null)
			{
				return;
			}
			currentFontPath = fontPaths.FirstOrDefault((string fontPath) => File.Exists(fontPath));
			if (currentFontPath == null)
			{
				logger.LogInfo((object)"No font found.");
				return;
			}
			logger.LogInfo((object)("Loading font at \"" + Path.GetFileName(currentFontPath) + "\"."));
			long length = new FileInfo(currentFontPath).Length;
			if ((double)length > 1000000.0 && configAllCharsAtlas.Value)
			{
				logger.LogWarning((object)$"Font file is large (> {(double)length * 1E-06:F1}MB)! It may take several minutes to to create font atlas.");
			}
			FontAssetBuilder fontAssetBuilder = new FontAssetBuilder(new Font(currentFontPath))
			{
				AtlasHeight = 8192,
				AtlasWidth = 8192
			};
			if (!configAllCharsAtlas.Value)
			{
				fontAssetBuilder.AddChars(32u, 126u).AddChars(128u, 254u);
				string[] sheetTitles = Language.Settings.sheetTitles;
				for (int num = 0; num < sheetTitles.Length; num++)
				{
					string languageFileContents = Language.GetLanguageFileContents(sheetTitles[num]);
					if (string.IsNullOrEmpty(languageFileContents))
					{
						continue;
					}
					using XmlReader xmlReader = XmlReader.Create(new StringReader(languageFileContents));
					while (xmlReader.ReadToFollowing("entry"))
					{
						xmlReader.MoveToFirstAttribute();
						_ = xmlReader.Value;
						xmlReader.MoveToElement();
						string text = xmlReader.ReadElementContentAsString().Trim();
						text = StringExtensions.UnescapeXml(text);
						fontAssetBuilder.AddChars(text);
					}
				}
			}
			fontAsset = fontAssetBuilder.Create();
		}

		internal static void PatchTMPro(TextMeshPro tmpro, float scale, Material sourceMaterial)
		{
			if ((Object)(object)tmpro == (Object)null)
			{
				oldTMPros.Remove(tmpro);
				return;
			}
			((TMP_Text)tmpro).fontSize = scale;
			if (!((Object)(object)((TMP_Text)tmpro).font == (Object)(object)fontAsset))
			{
				fontAsset.fallbackFontAssets = ((TMP_Text)tmpro).font.fallbackFontAssets;
				if (Extensions.IsNullOrEmpty<TMP_FontAsset>((ICollection<TMP_FontAsset>)fontAsset.fallbackFontAssets))
				{
					fontAsset.fallbackFontAssets = new List<TMP_FontAsset>(1) { ((TMP_Text)tmpro).font };
				}
				else if (!fontAsset.fallbackFontAssets.Contains(((TMP_Text)tmpro).font))
				{
					fontAsset.fallbackFontAssets.Insert(0, ((TMP_Text)tmpro).font);
				}
				((TMP_Text)tmpro).font = fontAsset;
				Material fallbackMaterial = TMP_MaterialManager.GetFallbackMaterial(sourceMaterial, ((TMP_Text)tmpro).fontSharedMaterial);
				((TMP_Text)tmpro).fontSharedMaterial = fallbackMaterial;
			}
		}

		private static void UnpatchTMPro(TextMeshPro tmpro, (float FontSize, TMP_FontAsset Font) attr)
		{
			if ((Object)(object)tmpro == (Object)null)
			{
				oldTMPros.Remove(tmpro);
				return;
			}
			string text = (((Object)(object)tmpro == (Object)null) ? "null" : ((Object)tmpro).GetInstanceID().ToString());
			string text2 = (((Object)(object)((TMP_Text)tmpro).font == (Object)null) ? "null" : ((Object)((TMP_Text)tmpro).font).name);
			string text3 = (((Object)(object)attr.Font == (Object)null) ? "null" : ((Object)attr.Font).name);
			if (text == "null" || text2 == "null" || text3 == "null")
			{
				logger.LogInfo((object)("(" + text + " ," + text2 + ", " + text3 + ")"));
			}
			((TMP_Text)tmpro).font = attr.Font;
			((TMP_Text)tmpro).fontSize = attr.FontSize;
		}

		internal static void TryUnpatchTMPro(TextMeshPro tmpro)
		{
			if (oldTMPros.TryGetValue(tmpro, out (float, TMP_FontAsset) value))
			{
				UnpatchTMPro(tmpro, value);
			}
		}

		internal static void TryUpdateTMPros()
		{
			if ((Object)(object)fontAsset == (Object)null)
			{
				return;
			}
			TextMeshPro key;
			(float, TMP_FontAsset) value;
			if (configReplaceFontMode.Value != ReplaceFontMode.All)
			{
				logger.LogDebug((object)"Unpatching TMPro");
				foreach (KeyValuePair<TextMeshPro, (float, TMP_FontAsset)> oldTMPro in oldTMPros)
				{
					oldTMPro.Deconstruct(out key, out value);
					TextMeshPro tmpro = key;
					(float, TMP_FontAsset) attr = value;
					UnpatchTMPro(tmpro, attr);
				}
			}
			else
			{
				logger.LogDebug((object)"Patching TMPro");
				foreach (KeyValuePair<TextMeshPro, (float, TMP_FontAsset)> oldTMPro2 in oldTMPros)
				{
					oldTMPro2.Deconstruct(out key, out value);
					TextMeshPro val = key;
					(float, TMP_FontAsset) tuple = value;
					PatchTMPro(val, tuple.Item1 * configFontScale.Value, ((TMP_Text)val).fontSharedMaterial);
				}
			}
			ChangeFontByLanguage[] array = Object.FindObjectsByType<ChangeFontByLanguage>((FindObjectsSortMode)0);
			for (int i = 0; i < array.Length; i++)
			{
				array[i].SetFont();
			}
		}

		public static string PathOf(GameObject go)
		{
			Transform val = go.transform;
			StringBuilder stringBuilder = new StringBuilder(((Object)val).name);
			while ((Object)(object)val.parent != (Object)null)
			{
				val = val.parent;
				stringBuilder.Insert(0, ((Object)val).name + "/");
			}
			return stringBuilder.ToString();
		}

		public static LocalisedString Localized(string key)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			return new LocalisedString("Mods.io.github.carrieforle.customfont", key);
		}

		public static string Localized(string key, params object[] args)
		{
			return string.Format(Language.Get(key, "Mods.io.github.carrieforle.customfont"), args);
		}
	}
	internal static class Patch
	{
		[HarmonyPostfix]
		[HarmonyPriority(500)]
		[HarmonyPatch(typeof(GameManager), "LevelActivated")]
		private static void AddTMProsInScene()
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			CustomFontPlugin.logger.LogInfo((object)"Entering Scene");
			CustomFontPlugin.cfblCanPatch = true;
			if ((Object)(object)CustomFontPlugin.fontAsset == (Object)null)
			{
				return;
			}
			Scene activeScene = SceneManager.GetActiveScene();
			IEnumerable<TextMeshPro> enumerable = ((Scene)(ref activeScene)).GetRootGameObjects().SelectMany((GameObject go) => go.GetComponentsInChildren<TextMeshPro>(true));
			bool flag = false;
			foreach (TextMeshPro item in enumerable)
			{
				if (!((Object)(object)((TMP_Text)item).fontSharedMaterial == (Object)null) && !((Object)(object)((TMP_Text)item).font == (Object)null))
				{
					GameObject gameObject = ((Component)item.transform.parent).gameObject;
					if (!((Object)(object)gameObject != (Object)null) || !((Object)(object)gameObject.GetComponent<MenuButtonIcon>() != (Object)null))
					{
						flag = flag || CustomFontPlugin.oldTMPros.TryAdd(item, (((TMP_Text)item).fontSize, ((TMP_Text)item).font));
					}
				}
			}
			if (flag)
			{
				CustomFontPlugin.logger.LogDebug((object)"Found scene tmpros");
				CustomFontPlugin.TryUpdateTMPros();
			}
		}

		[HarmonyPostfix]
		[HarmonyPriority(500)]
		[HarmonyPatch(typeof(OpeningSequence), "Start")]
		private static void AddTMProsInActCard(OpeningSequence __instance)
		{
			if (!((Object)(object)CustomFontPlugin.fontAsset == (Object)null) && CustomFontPlugin.configReplaceFontMode.Value != ReplaceFontMode.Disabled)
			{
				CustomFontPlugin.logger.LogDebug((object)"Patching act cards");
				TextMeshPro[] componentsInChildren = ((Component)__instance).GetComponentsInChildren<TextMeshPro>(true);
				foreach (TextMeshPro val in componentsInChildren)
				{
					CustomFontPlugin.PatchTMPro(val, ((TMP_Text)val).fontSize * CustomFontPlugin.configFontScale.Value, ((TMP_Text)val).fontSharedMaterial);
				}
			}
		}

		[HarmonyPrefix]
		[HarmonyPriority(500)]
		[HarmonyPatch(typeof(CinematicPlayer), "FinishInGameVideo")]
		private static void AddTMProsInActCard(CinematicPlayer __instance)
		{
			if (!((Object)(object)CustomFontPlugin.fontAsset == (Object)null) && !((Object)(object)__instance.actCard == (Object)null) && CustomFontPlugin.configReplaceFontMode.Value != ReplaceFontMode.Disabled)
			{
				CustomFontPlugin.logger.LogDebug((object)"Patching act cards");
				TextMeshPro[] componentsInChildren = ((Component)__instance.actCard).GetComponentsInChildren<TextMeshPro>(true);
				foreach (TextMeshPro val in componentsInChildren)
				{
					CustomFontPlugin.PatchTMPro(val, ((TMP_Text)val).fontScale * CustomFontPlugin.configFontScale.Value, ((TMP_Text)val).fontSharedMaterial);
				}
			}
		}

		[HarmonyPostfix]
		[HarmonyPriority(500)]
		[HarmonyPatch(typeof(SimpleShopMenu), "Awake")]
		private static void AddTMProsInShop(SimpleShopMenu __instance)
		{
			if ((Object)(object)CustomFontPlugin.fontAsset == (Object)null)
			{
				return;
			}
			((InventoryPaneBase)__instance.pane).OnPaneStart += delegate
			{
				TextMeshPro[] componentsInChildren = ((Component)__instance).GetComponentsInChildren<TextMeshPro>(true);
				bool flag = false;
				TextMeshPro[] array = componentsInChildren;
				foreach (TextMeshPro val in array)
				{
					if (!((Object)(object)((TMP_Text)val).fontSharedMaterial == (Object)null) && !((Object)(object)((TMP_Text)val).font == (Object)null))
					{
						flag = flag || CustomFontPlugin.oldTMPros.TryAdd(val, (((TMP_Text)val).fontSize, ((TMP_Text)val).font));
					}
				}
				if (flag)
				{
					CustomFontPlugin.logger.LogDebug((object)"Found shop price tags");
					CustomFontPlugin.TryUpdateTMPros();
				}
			};
		}

		[HarmonyPostfix]
		[HarmonyPriority(500)]
		[HarmonyPatch(typeof(ChangeFontByLanguage), "SetFont", new Type[] { })]
		private static void SetFont(ChangeFontByLanguage __instance)
		{
			TextMeshPro tmpro = __instance.tmpro;
			if (!((Object)(object)tmpro == (Object)null) && !((Object)(object)CustomFontPlugin.fontAsset == (Object)null) && CustomFontPlugin.cfblCanPatch)
			{
				CustomFontPlugin.oldTMPros.TryAdd(tmpro, (((TMP_Text)tmpro).fontSize, ((TMP_Text)tmpro).font));
				if (CustomFontPlugin.configReplaceFontMode.Value != ReplaceFontMode.Disabled)
				{
					CustomFontPlugin.PatchTMPro(tmpro, CustomFontPlugin.oldTMPros[tmpro].FontSize * CustomFontPlugin.configFontScale.Value, __instance.defaultMaterial);
				}
			}
		}

		[HarmonyPostfix]
		[HarmonyPriority(500)]
		[HarmonyPatch(typeof(QuestItemManager), "ResetExtraDisplay")]
		[HarmonyPatch(typeof(QuestItemManager), "SetDisplay", new Type[] { typeof(InventoryItemSelectable) })]
		private static void PatchFontSize(QuestItemManager __instance)
		{
			if (!((Object)(object)CustomFontPlugin.fontAsset == (Object)null) && CustomFontPlugin.oldTMPros.TryGetValue(((InventoryItemManager)__instance).descriptionText, out (float, TMP_FontAsset) value))
			{
				if (CustomFontPlugin.configReplaceFontMode.Value == ReplaceFontMode.Disabled)
				{
					((TMP_Text)((InventoryItemManager)__instance).descriptionText).fontSize = value.Item1;
				}
				else
				{
					((TMP_Text)((InventoryItemManager)__instance).descriptionText).fontSize = value.Item1 * CustomFontPlugin.configFontScale.Value;
				}
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(UIManager), "Start")]
		private static void ClearTMPros()
		{
			CustomFontPlugin.logger.LogDebug((object)"Clearing TMPros");
			CustomFontPlugin.cfblCanPatch = false;
			CustomFontPlugin.oldTMPros.Clear();
		}

		[HarmonyPostfix]
		[HarmonyPriority(500)]
		[HarmonyPatch(typeof(GameManager), "ContinueGame")]
		[HarmonyPatch(typeof(GameManager), "StartNewGame")]
		private static void StartGame()
		{
			CollectionExtensions.Do<TextMeshPro>((IEnumerable<TextMeshPro>)((Component)GameCameras.SilentInstance.hudCamera).gameObject.GetComponentsInChildren<TextMeshPro>(true), (Action<TextMeshPro>)delegate(TextMeshPro tmpro)
			{
				CustomFontPlugin.oldTMPros.TryAdd(tmpro, (((TMP_Text)tmpro).fontSize, ((TMP_Text)tmpro).font));
			});
			CustomFontPlugin.TryLoadFont();
		}

		[HarmonyPostfix]
		[HarmonyPriority(500)]
		[HarmonyPatch(typeof(TextMeshPro), "OnDestroy")]
		private static void RemoveTMPro(TextMeshPro __instance)
		{
			CustomFontPlugin.oldTMPros.Remove(__instance);
		}

		[HarmonyPrefix]
		[HarmonyPriority(500)]
		[HarmonyPatch(typeof(InventoryItemListManager<InventoryItemCollectable, CollectableItem>), "UpdateList")]
		private static void UnpatchInventory(InventoryItemListManager<InventoryItemCollectable, CollectableItem> __instance)
		{
			TextMeshPro[] componentsInChildren = ((Component)__instance).GetComponentsInChildren<TextMeshPro>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				CustomFontPlugin.TryUnpatchTMPro(componentsInChildren[i]);
			}
		}

		[HarmonyPostfix]
		[HarmonyPriority(500)]
		[HarmonyPatch(typeof(InventoryItemListManager<InventoryItemCollectable, CollectableItem>), "UpdateList")]
		private static void PatchInventory(InventoryItemListManager<InventoryItemCollectable, CollectableItem> __instance)
		{
			TextMeshPro[] componentsInChildren = ((Component)__instance).GetComponentsInChildren<TextMeshPro>(true);
			foreach (TextMeshPro val in componentsInChildren)
			{
				CustomFontPlugin.oldTMPros.TryAdd(val, (((TMP_Text)val).fontSize, ((TMP_Text)val).font));
			}
			CustomFontPlugin.TryUpdateTMPros();
		}
	}
	internal enum ReplaceFontMode
	{
		Disabled,
		EffectedByLanguage,
		All
	}
	public class CustomFontException : Exception
	{
		public CustomFontException(string message)
			: base(message)
		{
		}
	}
	public class FontAssetBuilder
	{
		public Font Font { get; set; }

		public ISet<uint> CharList { get; set; } = new HashSet<uint>();

		public int FaceIndex { get; set; }

		public int SamplingPointSize { get; set; } = 90;

		public int AtlasPadding { get; set; } = 9;

		public GlyphRenderMode RenderMode { get; set; } = (GlyphRenderMode)4165;

		public int AtlasWidth { get; set; } = 1024;

		public int AtlasHeight { get; set; } = 1024;

		public FontAssetBuilder(Font font)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			Font = font;
		}

		public TMP_FontAsset Create()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Invalid comparison between Unknown and I4
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Invalid comparison between Unknown and I4
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Invalid comparison between Unknown and I4
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Invalid comparison between Unknown and I4
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Invalid comparison between Unknown and I4
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Invalid comparison between Unknown and I4
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Invalid comparison between Unknown and I4
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Invalid comparison between Unknown and I4
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Invalid comparison between Unknown and I4
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Invalid comparison between Unknown and I4
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Invalid comparison between Unknown and I4
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Invalid comparison between Unknown and I4
			//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0226: Unknown result type (might be due to invalid IL or missing references)
			//IL_0227: Unknown result type (might be due to invalid IL or missing references)
			//IL_026d: Unknown result type (might be due to invalid IL or missing references)
			GlyphRenderMode renderMode = RenderMode;
			if ((int)renderMode <= 4169)
			{
				if ((int)renderMode <= 4122)
				{
					if (renderMode - 4117 <= 1 || renderMode - 4121 <= 1)
					{
						goto IL_008d;
					}
				}
				else if ((int)renderMode == 4134 || (int)renderMode == 4165 || (int)renderMode == 4169)
				{
					goto IL_0089;
				}
			}
			else if ((int)renderMode <= 16422)
			{
				if ((int)renderMode == 8230 || (int)renderMode == 16422)
				{
					goto IL_0089;
				}
			}
			else
			{
				if ((int)renderMode == 32806)
				{
					goto IL_0089;
				}
				if ((int)renderMode == 69652 || (int)renderMode == 69656)
				{
					goto IL_008d;
				}
			}
			throw new CustomFontException("GlyphRenderMode.DEFAULT is not allowed.");
			IL_008d:
			FontAssetTypes fontAssetType = (FontAssetTypes)2;
			goto IL_009c;
			IL_0089:
			fontAssetType = (FontAssetTypes)1;
			goto IL_009c;
			IL_009c:
			FontAsset val = FontAsset.CreateFontAsset(Font, FaceIndex, SamplingPointSize, AtlasPadding, RenderMode, AtlasWidth, AtlasHeight, (AtlasPopulationMode)1, false);
			if ((Object)(object)val == (Object)null)
			{
				throw new CustomFontException("Failed to create font asset.");
			}
			TMP_FontAsset obj = ScriptableObject.CreateInstance<TMP_FontAsset>();
			((Object)obj).name = ((Object)Font).name;
			obj.fallbackFontAssets = new List<TMP_FontAsset>();
			IEnumerable<uint> source = CharList;
			if (!source.Any())
			{
				source = from c in Enumerable.Range(0, 1114111)
					select (uint)c;
			}
			uint[] source2 = default(uint[]);
			if (!val.TryAddCharacters(source.ToArray(), ref source2, true))
			{
				string text = new string(source2.Select((uint c) => (char)c).ToArray());
				if (CharList.Any())
				{
					CustomFontPlugin.logger.LogWarning((object)("Failed to add characters: \"" + text + "\". These will not be rendered."));
				}
			}
			TMP_Glyph[] array = val.characterTable.Select((Character character) => NewToOld(character, AtlasHeight)).ToArray();
			CustomFontPlugin.logger.LogDebug((object)$"Loaded {array.Length} glyphs.");
			obj.m_fontInfo = NewToOld(val.faceInfo, AtlasWidth, AtlasHeight, AtlasPadding, array.Length);
			obj.AddGlyphInfo(array);
			obj.AddKerningInfo(NewToOld(val));
			obj.fontAssetType = fontAssetType;
			Texture2D atlasTexture = val.atlasTexture;
			obj.atlas = atlasTexture;
			CustomFontPlugin.logger.LogDebug((object)$"Created {val.atlasTextureCount} atlases.");
			((TMP_Asset)obj).material = ((TextAsset)val).material;
			obj.ReadFontDefinition();
			FontEngine.UnloadFontFace();
			return obj;
		}

		public FontAssetBuilder AddChars(string chars)
		{
			HashSet<uint> hashSet = new HashSet<uint>();
			for (int i = 0; i < chars.Length; i++)
			{
				uint item = chars[i];
				if (char.IsHighSurrogate(chars, i))
				{
					item = (uint)char.ConvertToUtf32(chars[i], chars[i + 1]);
					i++;
				}
				hashSet.Add(item);
			}
			return AddChars(hashSet);
		}

		public FontAssetBuilder AddChars(ISet<uint> unicodes)
		{
			CharList = CharList.Union(unicodes).ToHashSet();
			return this;
		}

		public FontAssetBuilder AddChars(uint start, uint end)
		{
			if (start >= end)
			{
				throw new ArgumentException($"start({start}) is greater than or equal to end({end})");
			}
			CharList = CharList.Union(from u in Enumerable.Range((int)start, (int)end)
				select (uint)u).ToHashSet();
			return this;
		}

		private static KerningTable NewToOld(FontAsset fontAsset)
		{
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Expected O, but got Unknown
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			Dictionary<uint, uint> glyphToUnicode = new Dictionary<uint, uint>();
			HashSet<uint> hashSet = new HashSet<uint>();
			foreach (Character item in fontAsset.characterTable)
			{
				if (!glyphToUnicode.TryAdd(((TextElement)item).glyphIndex, ((TextElement)item).unicode))
				{
					hashSet.Add(((TextElement)item).glyphIndex);
				}
			}
			CollectionExtensions.Do<uint>((IEnumerable<uint>)hashSet, (Action<uint>)delegate(uint glyph)
			{
				glyphToUnicode.Remove(glyph);
			});
			KerningTable val = new KerningTable();
			foreach (GlyphPairAdjustmentRecord glyphPairAdjustmentRecord in fontAsset.fontFeatureTable.glyphPairAdjustmentRecords)
			{
				GlyphPairAdjustmentRecord current2 = glyphPairAdjustmentRecord;
				Dictionary<uint, uint> dictionary = glyphToUnicode;
				GlyphAdjustmentRecord val2 = ((GlyphPairAdjustmentRecord)(ref current2)).firstAdjustmentRecord;
				if (dictionary.TryGetValue(((GlyphAdjustmentRecord)(ref val2)).glyphIndex, out var value))
				{
					Dictionary<uint, uint> dictionary2 = glyphToUnicode;
					val2 = ((GlyphPairAdjustmentRecord)(ref current2)).secondAdjustmentRecord;
					if (dictionary2.TryGetValue(((GlyphAdjustmentRecord)(ref val2)).glyphIndex, out var value2))
					{
						uint num = value;
						uint num2 = value2;
						val2 = ((GlyphPairAdjustmentRecord)(ref current2)).firstAdjustmentRecord;
						GlyphValueRecord glyphValueRecord = ((GlyphAdjustmentRecord)(ref val2)).glyphValueRecord;
						val.AddKerningPair((int)num, (int)num2, ((GlyphValueRecord)(ref glyphValueRecord)).xAdvance);
					}
				}
			}
			return val;
		}

		private static TMP_Glyph NewToOld(Character character, int atlasHeight)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Expected O, but got Unknown
			TMP_Glyph val = new TMP_Glyph
			{
				id = (int)((TextElement)character).m_Unicode
			};
			GlyphRect glyphRect = ((TextElement)character).glyph.glyphRect;
			((TMP_TextElement)val).x = ((GlyphRect)(ref glyphRect)).x;
			glyphRect = ((TextElement)character).glyph.glyphRect;
			float num = atlasHeight - ((GlyphRect)(ref glyphRect)).y;
			GlyphMetrics metrics = ((TextElement)character).glyph.metrics;
			((TMP_TextElement)val).y = num - ((GlyphMetrics)(ref metrics)).height;
			metrics = ((TextElement)character).glyph.metrics;
			((TMP_TextElement)val).width = ((GlyphMetrics)(ref metrics)).width;
			metrics = ((TextElement)character).glyph.metrics;
			((TMP_TextElement)val).height = ((GlyphMetrics)(ref metrics)).height;
			metrics = ((TextElement)character).glyph.metrics;
			((TMP_TextElement)val).xOffset = ((GlyphMetrics)(ref metrics)).horizontalBearingX;
			metrics = ((TextElement)character).glyph.metrics;
			((TMP_TextElement)val).yOffset = ((GlyphMetrics)(ref metrics)).horizontalBearingY;
			metrics = ((TextElement)character).glyph.metrics;
			((TMP_TextElement)val).xAdvance = ((GlyphMetrics)(ref metrics)).horizontalAdvance;
			((TMP_TextElement)val).scale = 1f;
			return val;
		}

		private static FaceInfo NewToOld(FaceInfo newFaceInfo, float atlasWidth, float atlasHeight, float atlasPadding, int charCount)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Expected O, but got Unknown
			return new FaceInfo
			{
				Name = ((FaceInfo)(ref newFaceInfo)).familyName,
				PointSize = ((FaceInfo)(ref newFaceInfo)).pointSize,
				Scale = ((FaceInfo)(ref newFaceInfo)).scale,
				CharacterCount = charCount,
				LineHeight = ((FaceInfo)(ref newFaceInfo)).lineHeight,
				Baseline = ((FaceInfo)(ref newFaceInfo)).baseline,
				Ascender = ((FaceInfo)(ref newFaceInfo)).ascentLine,
				CapHeight = ((FaceInfo)(ref newFaceInfo)).capLine,
				Descender = ((FaceInfo)(ref newFaceInfo)).descentLine,
				CenterLine = ((FaceInfo)(ref newFaceInfo)).meanLine,
				SuperscriptOffset = ((FaceInfo)(ref newFaceInfo)).superscriptOffset,
				SubscriptOffset = ((FaceInfo)(ref newFaceInfo)).subscriptOffset,
				SubSize = ((FaceInfo)(ref newFaceInfo)).subscriptSize,
				Underline = ((FaceInfo)(ref newFaceInfo)).underlineOffset,
				UnderlineThickness = ((FaceInfo)(ref newFaceInfo)).underlineThickness,
				TabWidth = ((FaceInfo)(ref newFaceInfo)).tabWidth,
				Padding = atlasPadding,
				AtlasWidth = atlasWidth,
				AtlasHeight = atlasHeight
			};
		}
	}
}