Initial Commit
This commit is contained in:
parent
53eb92e9af
commit
270ab7d11f
15341 changed files with 700234 additions and 0 deletions
|
@ -0,0 +1,11 @@
|
|||
using System.Runtime.CompilerServices;
|
||||
|
||||
// Allow internal visibility for testing purposes.
|
||||
[assembly: InternalsVisibleTo("Unity.TextCore")]
|
||||
|
||||
[assembly: InternalsVisibleTo("Unity.FontEngine.Tests")]
|
||||
|
||||
#if UNITY_EDITOR
|
||||
[assembly: InternalsVisibleTo("Unity.TextCore.Editor")]
|
||||
[assembly: InternalsVisibleTo("Unity.TextMeshPro.Editor")]
|
||||
#endif
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 1c147d10db452eb4b854a35f84472017
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,150 @@
|
|||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
|
||||
namespace TMPro
|
||||
{
|
||||
public class FastAction
|
||||
{
|
||||
|
||||
LinkedList<System.Action> delegates = new LinkedList<System.Action>();
|
||||
|
||||
Dictionary<System.Action, LinkedListNode<System.Action>> lookup = new Dictionary<System.Action, LinkedListNode<System.Action>>();
|
||||
|
||||
public void Add(System.Action rhs)
|
||||
{
|
||||
if (lookup.ContainsKey(rhs)) return;
|
||||
|
||||
lookup[rhs] = delegates.AddLast(rhs);
|
||||
}
|
||||
|
||||
public void Remove(System.Action rhs)
|
||||
{
|
||||
LinkedListNode<System.Action> node;
|
||||
if (lookup.TryGetValue(rhs, out node))
|
||||
{
|
||||
lookup.Remove(rhs);
|
||||
delegates.Remove(node);
|
||||
}
|
||||
}
|
||||
|
||||
public void Call()
|
||||
{
|
||||
var node = delegates.First;
|
||||
while (node != null)
|
||||
{
|
||||
node.Value();
|
||||
node = node.Next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public class FastAction<A>
|
||||
{
|
||||
|
||||
LinkedList<System.Action<A>> delegates = new LinkedList<System.Action<A>>();
|
||||
|
||||
Dictionary<System.Action<A>, LinkedListNode<System.Action<A>>> lookup = new Dictionary<System.Action<A>, LinkedListNode<System.Action<A>>>();
|
||||
|
||||
public void Add(System.Action<A> rhs)
|
||||
{
|
||||
if (lookup.ContainsKey(rhs)) return;
|
||||
|
||||
lookup[rhs] = delegates.AddLast(rhs);
|
||||
}
|
||||
|
||||
public void Remove(System.Action<A> rhs)
|
||||
{
|
||||
LinkedListNode<System.Action<A>> node;
|
||||
if (lookup.TryGetValue(rhs, out node))
|
||||
{
|
||||
lookup.Remove(rhs);
|
||||
delegates.Remove(node);
|
||||
}
|
||||
}
|
||||
|
||||
public void Call(A a)
|
||||
{
|
||||
var node = delegates.First;
|
||||
while (node != null)
|
||||
{
|
||||
node.Value(a);
|
||||
node = node.Next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public class FastAction<A, B>
|
||||
{
|
||||
|
||||
LinkedList<System.Action<A, B>> delegates = new LinkedList<System.Action<A, B>>();
|
||||
|
||||
Dictionary<System.Action<A, B>, LinkedListNode<System.Action<A, B>>> lookup = new Dictionary<System.Action<A, B>, LinkedListNode<System.Action<A, B>>>();
|
||||
|
||||
public void Add(System.Action<A, B> rhs)
|
||||
{
|
||||
if (lookup.ContainsKey(rhs)) return;
|
||||
|
||||
lookup[rhs] = delegates.AddLast(rhs);
|
||||
}
|
||||
|
||||
public void Remove(System.Action<A, B> rhs)
|
||||
{
|
||||
LinkedListNode<System.Action<A, B>> node;
|
||||
if (lookup.TryGetValue(rhs, out node))
|
||||
{
|
||||
lookup.Remove(rhs);
|
||||
delegates.Remove(node);
|
||||
}
|
||||
}
|
||||
|
||||
public void Call(A a, B b)
|
||||
{
|
||||
var node = delegates.First;
|
||||
while (node != null)
|
||||
{
|
||||
node.Value(a, b);
|
||||
node = node.Next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public class FastAction<A, B, C>
|
||||
{
|
||||
|
||||
LinkedList<System.Action<A, B, C>> delegates = new LinkedList<System.Action<A, B, C>>();
|
||||
|
||||
Dictionary<System.Action<A, B, C>, LinkedListNode<System.Action<A, B, C>>> lookup = new Dictionary<System.Action<A, B, C>, LinkedListNode<System.Action<A, B, C>>>();
|
||||
|
||||
public void Add(System.Action<A, B, C> rhs)
|
||||
{
|
||||
if (lookup.ContainsKey(rhs)) return;
|
||||
|
||||
lookup[rhs] = delegates.AddLast(rhs);
|
||||
}
|
||||
|
||||
public void Remove(System.Action<A, B, C> rhs)
|
||||
{
|
||||
LinkedListNode<System.Action<A, B, C>> node;
|
||||
if (lookup.TryGetValue(rhs, out node))
|
||||
{
|
||||
lookup.Remove(rhs);
|
||||
delegates.Remove(node);
|
||||
}
|
||||
}
|
||||
|
||||
public void Call(A a, B b, C c)
|
||||
{
|
||||
var node = delegates.First;
|
||||
while (node != null)
|
||||
{
|
||||
node.Value(a, b, c);
|
||||
node = node.Next;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 871f8edd56e84b8fb295b10cc3c78f36
|
||||
timeCreated: 1435956061
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,17 @@
|
|||
|
||||
|
||||
namespace TMPro
|
||||
{
|
||||
/// <summary>
|
||||
/// Interface used for preprocessing and shaping of text.
|
||||
/// </summary>
|
||||
public interface ITextPreprocessor
|
||||
{
|
||||
/// <summary>
|
||||
/// Function used for preprocessing of text
|
||||
/// </summary>
|
||||
/// <param name="text">Source text to be processed</param>
|
||||
/// <returns>Processed text</returns>
|
||||
string PreprocessText(string text);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: afc31ad767318c9488de260c166cd21d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,625 @@
|
|||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
|
||||
namespace TMPro
|
||||
{
|
||||
|
||||
public class MaterialReferenceManager
|
||||
{
|
||||
private static MaterialReferenceManager s_Instance;
|
||||
|
||||
// Dictionaries used to track Asset references.
|
||||
private Dictionary<int, Material> m_FontMaterialReferenceLookup = new Dictionary<int, Material>();
|
||||
private Dictionary<int, TMP_FontAsset> m_FontAssetReferenceLookup = new Dictionary<int, TMP_FontAsset>();
|
||||
private Dictionary<int, TMP_SpriteAsset> m_SpriteAssetReferenceLookup = new Dictionary<int, TMP_SpriteAsset>();
|
||||
private Dictionary<int, TMP_ColorGradient> m_ColorGradientReferenceLookup = new Dictionary<int, TMP_ColorGradient>();
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Get a singleton instance of the registry
|
||||
/// </summary>
|
||||
public static MaterialReferenceManager instance
|
||||
{
|
||||
get
|
||||
{
|
||||
if (MaterialReferenceManager.s_Instance == null)
|
||||
MaterialReferenceManager.s_Instance = new MaterialReferenceManager();
|
||||
return MaterialReferenceManager.s_Instance;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Add new font asset reference to dictionary.
|
||||
/// </summary>
|
||||
/// <param name="fontAsset"></param>
|
||||
public static void AddFontAsset(TMP_FontAsset fontAsset)
|
||||
{
|
||||
MaterialReferenceManager.instance.AddFontAssetInternal(fontAsset);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add new Font Asset reference to dictionary.
|
||||
/// </summary>
|
||||
/// <param name="fontAsset"></param>
|
||||
private void AddFontAssetInternal(TMP_FontAsset fontAsset)
|
||||
{
|
||||
if (m_FontAssetReferenceLookup.ContainsKey(fontAsset.hashCode)) return;
|
||||
|
||||
// Add reference to the font asset.
|
||||
m_FontAssetReferenceLookup.Add(fontAsset.hashCode, fontAsset);
|
||||
|
||||
// Add reference to the font material.
|
||||
m_FontMaterialReferenceLookup.Add(fontAsset.materialHashCode, fontAsset.material);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Add new Sprite Asset to dictionary.
|
||||
/// </summary>
|
||||
/// <param name="hashCode"></param>
|
||||
/// <param name="spriteAsset"></param>
|
||||
public static void AddSpriteAsset(TMP_SpriteAsset spriteAsset)
|
||||
{
|
||||
MaterialReferenceManager.instance.AddSpriteAssetInternal(spriteAsset);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Internal method to add a new sprite asset to the dictionary.
|
||||
/// </summary>
|
||||
/// <param name="hashCode"></param>
|
||||
/// <param name="spriteAsset"></param>
|
||||
private void AddSpriteAssetInternal(TMP_SpriteAsset spriteAsset)
|
||||
{
|
||||
if (m_SpriteAssetReferenceLookup.ContainsKey(spriteAsset.hashCode)) return;
|
||||
|
||||
// Add reference to sprite asset.
|
||||
m_SpriteAssetReferenceLookup.Add(spriteAsset.hashCode, spriteAsset);
|
||||
|
||||
// Adding reference to the sprite asset material as well
|
||||
m_FontMaterialReferenceLookup.Add(spriteAsset.hashCode, spriteAsset.material);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add new Sprite Asset to dictionary.
|
||||
/// </summary>
|
||||
/// <param name="hashCode"></param>
|
||||
/// <param name="spriteAsset"></param>
|
||||
public static void AddSpriteAsset(int hashCode, TMP_SpriteAsset spriteAsset)
|
||||
{
|
||||
MaterialReferenceManager.instance.AddSpriteAssetInternal(hashCode, spriteAsset);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Internal method to add a new sprite asset to the dictionary.
|
||||
/// </summary>
|
||||
/// <param name="hashCode"></param>
|
||||
/// <param name="spriteAsset"></param>
|
||||
private void AddSpriteAssetInternal(int hashCode, TMP_SpriteAsset spriteAsset)
|
||||
{
|
||||
if (m_SpriteAssetReferenceLookup.ContainsKey(hashCode)) return;
|
||||
|
||||
// Add reference to Sprite Asset.
|
||||
m_SpriteAssetReferenceLookup.Add(hashCode, spriteAsset);
|
||||
|
||||
// Add reference to Sprite Asset using the asset hashcode.
|
||||
m_FontMaterialReferenceLookup.Add(hashCode, spriteAsset.material);
|
||||
|
||||
// Compatibility check
|
||||
if (spriteAsset.hashCode == 0) spriteAsset.hashCode = hashCode;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Add new Material reference to dictionary.
|
||||
/// </summary>
|
||||
/// <param name="hashCode"></param>
|
||||
/// <param name="material"></param>
|
||||
public static void AddFontMaterial(int hashCode, Material material)
|
||||
{
|
||||
MaterialReferenceManager.instance.AddFontMaterialInternal(hashCode, material);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add new material reference to dictionary.
|
||||
/// </summary>
|
||||
/// <param name="hashCode"></param>
|
||||
/// <param name="material"></param>
|
||||
private void AddFontMaterialInternal(int hashCode, Material material)
|
||||
{
|
||||
// Since this function is called after checking if the material is
|
||||
// contained in the dictionary, there is no need to check again.
|
||||
m_FontMaterialReferenceLookup.Add(hashCode, material);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Add new Color Gradient Preset to dictionary.
|
||||
/// </summary>
|
||||
/// <param name="hashCode"></param>
|
||||
/// <param name="spriteAsset"></param>
|
||||
public static void AddColorGradientPreset(int hashCode, TMP_ColorGradient spriteAsset)
|
||||
{
|
||||
MaterialReferenceManager.instance.AddColorGradientPreset_Internal(hashCode, spriteAsset);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Internal method to add a new Color Gradient Preset to the dictionary.
|
||||
/// </summary>
|
||||
/// <param name="hashCode"></param>
|
||||
/// <param name="spriteAsset"></param>
|
||||
private void AddColorGradientPreset_Internal(int hashCode, TMP_ColorGradient spriteAsset)
|
||||
{
|
||||
if (m_ColorGradientReferenceLookup.ContainsKey(hashCode)) return;
|
||||
|
||||
// Add reference to Color Gradient Preset Asset.
|
||||
m_ColorGradientReferenceLookup.Add(hashCode, spriteAsset);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Add new material reference and return the index of this new reference in the materialReferences array.
|
||||
/// </summary>
|
||||
/// <param name="material"></param>
|
||||
/// <param name="materialHashCode"></param>
|
||||
/// <param name="fontAsset"></param>
|
||||
//public int AddMaterial(Material material, int materialHashCode, TMP_FontAsset fontAsset)
|
||||
//{
|
||||
// if (!m_MaterialReferenceLookup.ContainsKey(materialHashCode))
|
||||
// {
|
||||
// int index = m_MaterialReferenceLookup.Count;
|
||||
|
||||
// materialReferences[index].fontAsset = fontAsset;
|
||||
// materialReferences[index].material = material;
|
||||
// materialReferences[index].isDefaultMaterial = material.GetInstanceID() == fontAsset.material.GetInstanceID() ? true : false;
|
||||
// materialReferences[index].index = index;
|
||||
// materialReferences[index].referenceCount = 0;
|
||||
|
||||
// m_MaterialReferenceLookup[materialHashCode] = index;
|
||||
|
||||
// // Compute Padding value and store it
|
||||
// // TODO
|
||||
|
||||
// int fontAssetHashCode = fontAsset.hashCode;
|
||||
|
||||
// if (!m_FontAssetReferenceLookup.ContainsKey(fontAssetHashCode))
|
||||
// m_FontAssetReferenceLookup.Add(fontAssetHashCode, fontAsset);
|
||||
|
||||
// m_countInternal += 1;
|
||||
|
||||
// return index;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// return m_MaterialReferenceLookup[materialHashCode];
|
||||
// }
|
||||
//}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Add new material reference and return the index of this new reference in the materialReferences array.
|
||||
/// </summary>
|
||||
/// <param name="material"></param>
|
||||
/// <param name="materialHashCode"></param>
|
||||
/// <param name="spriteAsset"></param>
|
||||
/// <returns></returns>
|
||||
//public int AddMaterial(Material material, int materialHashCode, TMP_SpriteAsset spriteAsset)
|
||||
//{
|
||||
// if (!m_MaterialReferenceLookup.ContainsKey(materialHashCode))
|
||||
// {
|
||||
// int index = m_MaterialReferenceLookup.Count;
|
||||
|
||||
// materialReferences[index].fontAsset = materialReferences[0].fontAsset;
|
||||
// materialReferences[index].spriteAsset = spriteAsset;
|
||||
// materialReferences[index].material = material;
|
||||
// materialReferences[index].isDefaultMaterial = true;
|
||||
// materialReferences[index].index = index;
|
||||
// materialReferences[index].referenceCount = 0;
|
||||
|
||||
// m_MaterialReferenceLookup[materialHashCode] = index;
|
||||
|
||||
// int spriteAssetHashCode = spriteAsset.hashCode;
|
||||
|
||||
// if (!m_SpriteAssetReferenceLookup.ContainsKey(spriteAssetHashCode))
|
||||
// m_SpriteAssetReferenceLookup.Add(spriteAssetHashCode, spriteAsset);
|
||||
|
||||
// m_countInternal += 1;
|
||||
|
||||
// return index;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// return m_MaterialReferenceLookup[materialHashCode];
|
||||
// }
|
||||
//}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function to check if the font asset is already referenced.
|
||||
/// </summary>
|
||||
/// <param name="font"></param>
|
||||
/// <returns></returns>
|
||||
public bool Contains(TMP_FontAsset font)
|
||||
{
|
||||
return m_FontAssetReferenceLookup.ContainsKey(font.hashCode);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function to check if the sprite asset is already referenced.
|
||||
/// </summary>
|
||||
/// <param name="font"></param>
|
||||
/// <returns></returns>
|
||||
public bool Contains(TMP_SpriteAsset sprite)
|
||||
{
|
||||
return m_FontAssetReferenceLookup.ContainsKey(sprite.hashCode);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function returning the Font Asset corresponding to the provided hash code.
|
||||
/// </summary>
|
||||
/// <param name="hashCode"></param>
|
||||
/// <param name="fontAsset"></param>
|
||||
/// <returns></returns>
|
||||
public static bool TryGetFontAsset(int hashCode, out TMP_FontAsset fontAsset)
|
||||
{
|
||||
return MaterialReferenceManager.instance.TryGetFontAssetInternal(hashCode, out fontAsset);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Internal Function returning the Font Asset corresponding to the provided hash code.
|
||||
/// </summary>
|
||||
/// <param name="hashCode"></param>
|
||||
/// <param name="fontAsset"></param>
|
||||
/// <returns></returns>
|
||||
private bool TryGetFontAssetInternal(int hashCode, out TMP_FontAsset fontAsset)
|
||||
{
|
||||
fontAsset = null;
|
||||
|
||||
return m_FontAssetReferenceLookup.TryGetValue(hashCode, out fontAsset);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function returning the Sprite Asset corresponding to the provided hash code.
|
||||
/// </summary>
|
||||
/// <param name="hashCode"></param>
|
||||
/// <param name="spriteAsset"></param>
|
||||
/// <returns></returns>
|
||||
public static bool TryGetSpriteAsset(int hashCode, out TMP_SpriteAsset spriteAsset)
|
||||
{
|
||||
return MaterialReferenceManager.instance.TryGetSpriteAssetInternal(hashCode, out spriteAsset);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Internal function returning the Sprite Asset corresponding to the provided hash code.
|
||||
/// </summary>
|
||||
/// <param name="hashCode"></param>
|
||||
/// <param name="fontAsset"></param>
|
||||
/// <returns></returns>
|
||||
private bool TryGetSpriteAssetInternal(int hashCode, out TMP_SpriteAsset spriteAsset)
|
||||
{
|
||||
spriteAsset = null;
|
||||
|
||||
return m_SpriteAssetReferenceLookup.TryGetValue(hashCode, out spriteAsset);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function returning the Color Gradient Preset corresponding to the provided hash code.
|
||||
/// </summary>
|
||||
/// <param name="hashCode"></param>
|
||||
/// <param name="gradientPreset"></param>
|
||||
/// <returns></returns>
|
||||
public static bool TryGetColorGradientPreset(int hashCode, out TMP_ColorGradient gradientPreset)
|
||||
{
|
||||
return MaterialReferenceManager.instance.TryGetColorGradientPresetInternal(hashCode, out gradientPreset);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Internal function returning the Color Gradient Preset corresponding to the provided hash code.
|
||||
/// </summary>
|
||||
/// <param name="hashCode"></param>
|
||||
/// <param name="fontAsset"></param>
|
||||
/// <returns></returns>
|
||||
private bool TryGetColorGradientPresetInternal(int hashCode, out TMP_ColorGradient gradientPreset)
|
||||
{
|
||||
gradientPreset = null;
|
||||
|
||||
return m_ColorGradientReferenceLookup.TryGetValue(hashCode, out gradientPreset);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function returning the Font Material corresponding to the provided hash code.
|
||||
/// </summary>
|
||||
/// <param name="hashCode"></param>
|
||||
/// <param name="material"></param>
|
||||
/// <returns></returns>
|
||||
public static bool TryGetMaterial(int hashCode, out Material material)
|
||||
{
|
||||
return MaterialReferenceManager.instance.TryGetMaterialInternal(hashCode, out material);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Internal function returning the Font Material corresponding to the provided hash code.
|
||||
/// </summary>
|
||||
/// <param name="hashCode"></param>
|
||||
/// <param name="material"></param>
|
||||
/// <returns></returns>
|
||||
private bool TryGetMaterialInternal(int hashCode, out Material material)
|
||||
{
|
||||
material = null;
|
||||
|
||||
return m_FontMaterialReferenceLookup.TryGetValue(hashCode, out material);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function to lookup a material based on hash code and returning the MaterialReference containing this material.
|
||||
/// </summary>
|
||||
/// <param name="hashCode"></param>
|
||||
/// <param name="material"></param>
|
||||
/// <returns></returns>
|
||||
//public bool TryGetMaterial(int hashCode, out MaterialReference materialReference)
|
||||
//{
|
||||
// int materialIndex = -1;
|
||||
|
||||
// if (m_MaterialReferenceLookup.TryGetValue(hashCode, out materialIndex))
|
||||
// {
|
||||
// materialReference = materialReferences[materialIndex];
|
||||
|
||||
// return true;
|
||||
// }
|
||||
|
||||
// materialReference = new MaterialReference();
|
||||
|
||||
// return false;
|
||||
//}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="fontAsset"></param>
|
||||
/// <returns></returns>
|
||||
//public int GetMaterialIndex(TMP_FontAsset fontAsset)
|
||||
//{
|
||||
// if (m_MaterialReferenceLookup.ContainsKey(fontAsset.materialHashCode))
|
||||
// return m_MaterialReferenceLookup[fontAsset.materialHashCode];
|
||||
|
||||
// return -1;
|
||||
//}
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="index"></param>
|
||||
/// <returns></returns>
|
||||
//public TMP_FontAsset GetFontAsset(int index)
|
||||
//{
|
||||
// if (index >= 0 && index < materialReferences.Length)
|
||||
// return materialReferences[index].fontAsset;
|
||||
|
||||
// return null;
|
||||
//}
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="material"></param>
|
||||
/// <param name="materialHashCode"></param>
|
||||
/// <param name="fontAsset"></param>
|
||||
//public void SetDefaultMaterial(Material material, int materialHashCode, TMP_FontAsset fontAsset)
|
||||
//{
|
||||
// if (!m_MaterialReferenceLookup.ContainsKey(materialHashCode))
|
||||
// {
|
||||
// materialReferences[0].fontAsset = fontAsset;
|
||||
// materialReferences[0].material = material;
|
||||
// materialReferences[0].index = 0;
|
||||
// materialReferences[0].isDefaultMaterial = material.GetInstanceID() == fontAsset.material.GetInstanceID() ? true : false;
|
||||
// materialReferences[0].referenceCount = 0;
|
||||
// m_MaterialReferenceLookup[materialHashCode] = 0;
|
||||
|
||||
// // Compute Padding value and store it
|
||||
// // TODO
|
||||
|
||||
// int fontHashCode = fontAsset.hashCode;
|
||||
|
||||
// if (!m_FontAssetReferenceLookup.ContainsKey(fontHashCode))
|
||||
// m_FontAssetReferenceLookup.Add(fontHashCode, fontAsset);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// materialReferences[0].fontAsset = fontAsset;
|
||||
// materialReferences[0].material = material;
|
||||
// materialReferences[0].index = 0;
|
||||
// materialReferences[0].referenceCount = 0;
|
||||
// m_MaterialReferenceLookup[materialHashCode] = 0;
|
||||
// }
|
||||
// // Compute padding
|
||||
// // TODO
|
||||
|
||||
// m_countInternal = 1;
|
||||
//}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
//public void Clear()
|
||||
//{
|
||||
// //m_currentIndex = 0;
|
||||
// m_MaterialReferenceLookup.Clear();
|
||||
// m_SpriteAssetReferenceLookup.Clear();
|
||||
// m_FontAssetReferenceLookup.Clear();
|
||||
//}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function to clear the reference count for each of the material references.
|
||||
/// </summary>
|
||||
//public void ClearReferenceCount()
|
||||
//{
|
||||
// m_countInternal = 0;
|
||||
|
||||
// for (int i = 0; i < materialReferences.Length; i++)
|
||||
// {
|
||||
// if (materialReferences[i].fontAsset == null)
|
||||
// return;
|
||||
|
||||
// materialReferences[i].referenceCount = 0;
|
||||
// }
|
||||
//}
|
||||
|
||||
}
|
||||
|
||||
|
||||
public struct TMP_MaterialReference
|
||||
{
|
||||
public Material material;
|
||||
public int referenceCount;
|
||||
}
|
||||
|
||||
|
||||
public struct MaterialReference
|
||||
{
|
||||
|
||||
public int index;
|
||||
public TMP_FontAsset fontAsset;
|
||||
public TMP_SpriteAsset spriteAsset;
|
||||
public Material material;
|
||||
public bool isDefaultMaterial;
|
||||
public bool isFallbackMaterial;
|
||||
public Material fallbackMaterial;
|
||||
public float padding;
|
||||
public int referenceCount;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Constructor for new Material Reference.
|
||||
/// </summary>
|
||||
/// <param name="index"></param>
|
||||
/// <param name="fontAsset"></param>
|
||||
/// <param name="spriteAsset"></param>
|
||||
/// <param name="material"></param>
|
||||
/// <param name="padding"></param>
|
||||
public MaterialReference(int index, TMP_FontAsset fontAsset, TMP_SpriteAsset spriteAsset, Material material, float padding)
|
||||
{
|
||||
this.index = index;
|
||||
this.fontAsset = fontAsset;
|
||||
this.spriteAsset = spriteAsset;
|
||||
this.material = material;
|
||||
this.isDefaultMaterial = material.GetInstanceID() == fontAsset.material.GetInstanceID() ? true : false;
|
||||
this.isFallbackMaterial = false;
|
||||
this.fallbackMaterial = null;
|
||||
this.padding = padding;
|
||||
this.referenceCount = 0;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function to check if a certain font asset is contained in the material reference array.
|
||||
/// </summary>
|
||||
/// <param name="materialReferences"></param>
|
||||
/// <param name="fontAsset"></param>
|
||||
/// <returns></returns>
|
||||
public static bool Contains(MaterialReference[] materialReferences, TMP_FontAsset fontAsset)
|
||||
{
|
||||
int id = fontAsset.GetInstanceID();
|
||||
|
||||
for (int i = 0; i < materialReferences.Length && materialReferences[i].fontAsset != null; i++)
|
||||
{
|
||||
if (materialReferences[i].fontAsset.GetInstanceID() == id)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function to add a new material reference and returning its index in the material reference array.
|
||||
/// </summary>
|
||||
/// <param name="material"></param>
|
||||
/// <param name="fontAsset"></param>
|
||||
/// <param name="materialReferences"></param>
|
||||
/// <param name="materialReferenceIndexLookup"></param>
|
||||
/// <returns></returns>
|
||||
public static int AddMaterialReference(Material material, TMP_FontAsset fontAsset, ref MaterialReference[] materialReferences, Dictionary<int, int> materialReferenceIndexLookup)
|
||||
{
|
||||
int materialID = material.GetInstanceID();
|
||||
int index;
|
||||
|
||||
if (materialReferenceIndexLookup.TryGetValue(materialID, out index))
|
||||
return index;
|
||||
|
||||
index = materialReferenceIndexLookup.Count;
|
||||
|
||||
// Add new reference index
|
||||
materialReferenceIndexLookup[materialID] = index;
|
||||
|
||||
if (index >= materialReferences.Length)
|
||||
System.Array.Resize(ref materialReferences, Mathf.NextPowerOfTwo(index + 1));
|
||||
|
||||
materialReferences[index].index = index;
|
||||
materialReferences[index].fontAsset = fontAsset;
|
||||
materialReferences[index].spriteAsset = null;
|
||||
materialReferences[index].material = material;
|
||||
materialReferences[index].isDefaultMaterial = materialID == fontAsset.material.GetInstanceID() ? true : false;
|
||||
//materialReferences[index].padding = 0;
|
||||
materialReferences[index].referenceCount = 0;
|
||||
|
||||
return index;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="material"></param>
|
||||
/// <param name="spriteAsset"></param>
|
||||
/// <param name="materialReferences"></param>
|
||||
/// <param name="materialReferenceIndexLookup"></param>
|
||||
/// <returns></returns>
|
||||
public static int AddMaterialReference(Material material, TMP_SpriteAsset spriteAsset, ref MaterialReference[] materialReferences, Dictionary<int, int> materialReferenceIndexLookup)
|
||||
{
|
||||
int materialID = material.GetInstanceID();
|
||||
int index;
|
||||
|
||||
if (materialReferenceIndexLookup.TryGetValue(materialID, out index))
|
||||
return index;
|
||||
|
||||
index = materialReferenceIndexLookup.Count;
|
||||
|
||||
// Add new reference index
|
||||
materialReferenceIndexLookup[materialID] = index;
|
||||
|
||||
if (index >= materialReferences.Length)
|
||||
System.Array.Resize(ref materialReferences, Mathf.NextPowerOfTwo(index + 1));
|
||||
|
||||
materialReferences[index].index = index;
|
||||
materialReferences[index].fontAsset = materialReferences[0].fontAsset;
|
||||
materialReferences[index].spriteAsset = spriteAsset;
|
||||
materialReferences[index].material = material;
|
||||
materialReferences[index].isDefaultMaterial = true;
|
||||
//materialReferences[index].padding = 0;
|
||||
materialReferences[index].referenceCount = 0;
|
||||
|
||||
return index;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 11a6a034ab84493cbed6af5ae7aae78b
|
||||
timeCreated: 1449743129
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,42 @@
|
|||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace TMPro
|
||||
{
|
||||
|
||||
// Base class inherited by the various TextMeshPro Assets.
|
||||
[Serializable]
|
||||
public abstract class TMP_Asset : ScriptableObject
|
||||
{
|
||||
/// <summary>
|
||||
/// Instance ID of the TMP Asset
|
||||
/// </summary>
|
||||
public int instanceID
|
||||
{
|
||||
get
|
||||
{
|
||||
if (m_InstanceID == 0)
|
||||
m_InstanceID = GetInstanceID();
|
||||
|
||||
return m_InstanceID;
|
||||
}
|
||||
}
|
||||
private int m_InstanceID;
|
||||
|
||||
/// <summary>
|
||||
/// HashCode based on the name of the asset.
|
||||
/// </summary>
|
||||
public int hashCode;
|
||||
|
||||
/// <summary>
|
||||
/// The material used by this asset.
|
||||
/// </summary>
|
||||
public Material material;
|
||||
|
||||
/// <summary>
|
||||
/// HashCode based on the name of the material assigned to this asset.
|
||||
/// </summary>
|
||||
public int materialHashCode;
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 3bda1886f58f4e0ab1139400b160c3ee
|
||||
timeCreated: 1459318952
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,70 @@
|
|||
using System;
|
||||
using UnityEngine.TextCore;
|
||||
|
||||
namespace TMPro
|
||||
{
|
||||
/// <summary>
|
||||
/// A basic element of text.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class TMP_Character : TMP_TextElement
|
||||
{
|
||||
/// <summary>
|
||||
/// Default constructor.
|
||||
/// </summary>
|
||||
public TMP_Character()
|
||||
{
|
||||
m_ElementType = TextElementType.Character;
|
||||
this.scale = 1.0f;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor for new character
|
||||
/// </summary>
|
||||
/// <param name="unicode">Unicode value.</param>
|
||||
/// <param name="glyph">Glyph</param>
|
||||
public TMP_Character(uint unicode, Glyph glyph)
|
||||
{
|
||||
m_ElementType = TextElementType.Character;
|
||||
|
||||
this.unicode = unicode;
|
||||
this.textAsset = null;
|
||||
this.glyph = glyph;
|
||||
this.glyphIndex = glyph.index;
|
||||
this.scale = 1.0f;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor for new character
|
||||
/// </summary>
|
||||
/// <param name="unicode">Unicode value.</param>
|
||||
/// <param name="fontAsset">The font asset to which this character belongs.</param>
|
||||
/// <param name="glyph">Glyph</param>
|
||||
public TMP_Character(uint unicode, TMP_FontAsset fontAsset, Glyph glyph)
|
||||
{
|
||||
m_ElementType = TextElementType.Character;
|
||||
|
||||
this.unicode = unicode;
|
||||
this.textAsset = fontAsset;
|
||||
this.glyph = glyph;
|
||||
this.glyphIndex = glyph.index;
|
||||
this.scale = 1.0f;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor for new character
|
||||
/// </summary>
|
||||
/// <param name="unicode">Unicode value.</param>
|
||||
/// <param name="glyphIndex">Glyph index.</param>
|
||||
internal TMP_Character(uint unicode, uint glyphIndex)
|
||||
{
|
||||
m_ElementType = TextElementType.Character;
|
||||
|
||||
this.unicode = unicode;
|
||||
this.textAsset = null;
|
||||
this.glyph = null;
|
||||
this.glyphIndex = glyphIndex;
|
||||
this.scale = 1.0f;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 4ac5b6a65aaeb59478e3b78660e9f134
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,220 @@
|
|||
using System.Diagnostics;
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
namespace TMPro
|
||||
{
|
||||
public struct TMP_Vertex
|
||||
{
|
||||
public Vector3 position;
|
||||
public Vector2 uv;
|
||||
public Vector2 uv2;
|
||||
public Vector2 uv4;
|
||||
public Color32 color;
|
||||
|
||||
public static TMP_Vertex zero { get { return k_Zero; } }
|
||||
|
||||
//public Vector3 normal;
|
||||
//public Vector4 tangent;
|
||||
|
||||
static readonly TMP_Vertex k_Zero = new TMP_Vertex();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public struct TMP_Offset
|
||||
{
|
||||
public float left { get { return m_Left; } set { m_Left = value; } }
|
||||
|
||||
public float right { get { return m_Right; } set { m_Right = value; } }
|
||||
|
||||
public float top { get { return m_Top; } set { m_Top = value; } }
|
||||
|
||||
public float bottom { get { return m_Bottom; } set { m_Bottom = value; } }
|
||||
|
||||
public float horizontal { get { return m_Left; } set { m_Left = value; m_Right = value; } }
|
||||
|
||||
public float vertical { get { return m_Top; } set { m_Top = value; m_Bottom = value; } }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static TMP_Offset zero { get { return k_ZeroOffset; } }
|
||||
|
||||
// =============================================
|
||||
// Private backing fields for public properties.
|
||||
// =============================================
|
||||
|
||||
float m_Left;
|
||||
float m_Right;
|
||||
float m_Top;
|
||||
float m_Bottom;
|
||||
|
||||
static readonly TMP_Offset k_ZeroOffset = new TMP_Offset(0F, 0F, 0F, 0F);
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="left"></param>
|
||||
/// <param name="right"></param>
|
||||
/// <param name="top"></param>
|
||||
/// <param name="bottom"></param>
|
||||
public TMP_Offset(float left, float right, float top, float bottom)
|
||||
{
|
||||
m_Left = left;
|
||||
m_Right = right;
|
||||
m_Top = top;
|
||||
m_Bottom = bottom;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="horizontal"></param>
|
||||
/// <param name="vertical"></param>
|
||||
public TMP_Offset(float horizontal, float vertical)
|
||||
{
|
||||
m_Left = horizontal;
|
||||
m_Right = horizontal;
|
||||
m_Top = vertical;
|
||||
m_Bottom = vertical;
|
||||
}
|
||||
|
||||
public static bool operator ==(TMP_Offset lhs, TMP_Offset rhs)
|
||||
{
|
||||
return lhs.m_Left == rhs.m_Left &&
|
||||
lhs.m_Right == rhs.m_Right &&
|
||||
lhs.m_Top == rhs.m_Top &&
|
||||
lhs.m_Bottom == rhs.m_Bottom;
|
||||
}
|
||||
|
||||
public static bool operator !=(TMP_Offset lhs, TMP_Offset rhs)
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
public static TMP_Offset operator *(TMP_Offset a, float b)
|
||||
{
|
||||
return new TMP_Offset(a.m_Left * b, a.m_Right * b, a.m_Top * b, a.m_Bottom * b);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return base.GetHashCode();
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
return base.Equals(obj);
|
||||
}
|
||||
|
||||
public bool Equals(TMP_Offset other)
|
||||
{
|
||||
return base.Equals(other);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public struct HighlightState
|
||||
{
|
||||
public Color32 color;
|
||||
public TMP_Offset padding;
|
||||
|
||||
public HighlightState(Color32 color, TMP_Offset padding)
|
||||
{
|
||||
this.color = color;
|
||||
this.padding = padding;
|
||||
}
|
||||
|
||||
public static bool operator ==(HighlightState lhs, HighlightState rhs)
|
||||
{
|
||||
return lhs.color.Compare(rhs.color) && lhs.padding == rhs.padding;
|
||||
}
|
||||
|
||||
public static bool operator !=(HighlightState lhs, HighlightState rhs)
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return base.GetHashCode();
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
return base.Equals(obj);
|
||||
}
|
||||
|
||||
public bool Equals(HighlightState other)
|
||||
{
|
||||
return base.Equals(other);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Structure containing information about individual text elements (character or sprites).
|
||||
/// </summary>
|
||||
[DebuggerDisplay("Unicode '{character}' ({((uint)character).ToString(\"X\")})")]
|
||||
public struct TMP_CharacterInfo
|
||||
{
|
||||
public char character; // Should be changed to an uint to handle UTF32
|
||||
/// <summary>
|
||||
/// Index of the character in the raw string.
|
||||
/// </summary>
|
||||
public int index; // Index of the character in the input string.
|
||||
public int stringLength;
|
||||
public TMP_TextElementType elementType;
|
||||
|
||||
public TMP_TextElement textElement;
|
||||
public TMP_FontAsset fontAsset;
|
||||
public TMP_SpriteAsset spriteAsset;
|
||||
public int spriteIndex;
|
||||
public Material material;
|
||||
public int materialReferenceIndex;
|
||||
public bool isUsingAlternateTypeface;
|
||||
|
||||
public float pointSize;
|
||||
|
||||
//public short wordNumber;
|
||||
public int lineNumber;
|
||||
//public short charNumber;
|
||||
public int pageNumber;
|
||||
|
||||
|
||||
public int vertexIndex;
|
||||
public TMP_Vertex vertex_BL;
|
||||
public TMP_Vertex vertex_TL;
|
||||
public TMP_Vertex vertex_TR;
|
||||
public TMP_Vertex vertex_BR;
|
||||
|
||||
public Vector3 topLeft;
|
||||
public Vector3 bottomLeft;
|
||||
public Vector3 topRight;
|
||||
public Vector3 bottomRight;
|
||||
|
||||
public float origin;
|
||||
public float xAdvance;
|
||||
public float ascender;
|
||||
public float baseLine;
|
||||
public float descender;
|
||||
internal float adjustedAscender;
|
||||
internal float adjustedDescender;
|
||||
|
||||
public float aspectRatio;
|
||||
public float scale;
|
||||
public Color32 color;
|
||||
public Color32 underlineColor;
|
||||
public int underlineVertexIndex;
|
||||
public Color32 strikethroughColor;
|
||||
public int strikethroughVertexIndex;
|
||||
public Color32 highlightColor;
|
||||
public HighlightState highlightState;
|
||||
public FontStyles style;
|
||||
public bool isVisible;
|
||||
//public bool isIgnoringAlignment;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 90fe1c65e6bb3bc4e90862df7297719e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,68 @@
|
|||
using UnityEngine;
|
||||
using System.Collections;
|
||||
|
||||
namespace TMPro
|
||||
{
|
||||
public enum ColorMode
|
||||
{
|
||||
Single,
|
||||
HorizontalGradient,
|
||||
VerticalGradient,
|
||||
FourCornersGradient
|
||||
}
|
||||
|
||||
[System.Serializable][ExcludeFromPresetAttribute]
|
||||
public class TMP_ColorGradient : ScriptableObject
|
||||
{
|
||||
public ColorMode colorMode = ColorMode.FourCornersGradient;
|
||||
|
||||
public Color topLeft;
|
||||
public Color topRight;
|
||||
public Color bottomLeft;
|
||||
public Color bottomRight;
|
||||
|
||||
const ColorMode k_DefaultColorMode = ColorMode.FourCornersGradient;
|
||||
static readonly Color k_DefaultColor = Color.white;
|
||||
|
||||
/// <summary>
|
||||
/// Default Constructor which sets each of the colors as white.
|
||||
/// </summary>
|
||||
public TMP_ColorGradient()
|
||||
{
|
||||
colorMode = k_DefaultColorMode;
|
||||
topLeft = k_DefaultColor;
|
||||
topRight = k_DefaultColor;
|
||||
bottomLeft = k_DefaultColor;
|
||||
bottomRight = k_DefaultColor;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor allowing to set the default color of the Color Gradient.
|
||||
/// </summary>
|
||||
/// <param name="color"></param>
|
||||
public TMP_ColorGradient(Color color)
|
||||
{
|
||||
colorMode = k_DefaultColorMode;
|
||||
topLeft = color;
|
||||
topRight = color;
|
||||
bottomLeft = color;
|
||||
bottomRight = color;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The vertex colors at the corners of the characters.
|
||||
/// </summary>
|
||||
/// <param name="color0">Top left color.</param>
|
||||
/// <param name="color1">Top right color.</param>
|
||||
/// <param name="color2">Bottom left color.</param>
|
||||
/// <param name="color3">Bottom right color.</param>
|
||||
public TMP_ColorGradient(Color color0, Color color1, Color color2, Color color3)
|
||||
{
|
||||
colorMode = k_DefaultColorMode;
|
||||
this.topLeft = color0;
|
||||
this.topRight = color1;
|
||||
this.bottomLeft = color2;
|
||||
this.bottomRight = color3;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 54d21f6ece3b46479f0c328f8c6007e0
|
||||
timeCreated: 1468187202
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,74 @@
|
|||
using UnityEngine;
|
||||
using System.Collections;
|
||||
|
||||
|
||||
namespace TMPro
|
||||
{
|
||||
// Class used to convert scenes and objects saved in version 0.1.44 to the new Text Container
|
||||
public static class TMP_Compatibility
|
||||
{
|
||||
public enum AnchorPositions { TopLeft, Top, TopRight, Left, Center, Right, BottomLeft, Bottom, BottomRight, BaseLine, None };
|
||||
|
||||
/// <summary>
|
||||
/// Function used to convert text alignment option enumeration format.
|
||||
/// </summary>
|
||||
/// <param name="oldValue"></param>
|
||||
/// <returns></returns>
|
||||
public static TextAlignmentOptions ConvertTextAlignmentEnumValues(TextAlignmentOptions oldValue)
|
||||
{
|
||||
switch ((int)oldValue)
|
||||
{
|
||||
case 0:
|
||||
return TextAlignmentOptions.TopLeft;
|
||||
case 1:
|
||||
return TextAlignmentOptions.Top;
|
||||
case 2:
|
||||
return TextAlignmentOptions.TopRight;
|
||||
case 3:
|
||||
return TextAlignmentOptions.TopJustified;
|
||||
case 4:
|
||||
return TextAlignmentOptions.Left;
|
||||
case 5:
|
||||
return TextAlignmentOptions.Center;
|
||||
case 6:
|
||||
return TextAlignmentOptions.Right;
|
||||
case 7:
|
||||
return TextAlignmentOptions.Justified;
|
||||
case 8:
|
||||
return TextAlignmentOptions.BottomLeft;
|
||||
case 9:
|
||||
return TextAlignmentOptions.Bottom;
|
||||
case 10:
|
||||
return TextAlignmentOptions.BottomRight;
|
||||
case 11:
|
||||
return TextAlignmentOptions.BottomJustified;
|
||||
case 12:
|
||||
return TextAlignmentOptions.BaselineLeft;
|
||||
case 13:
|
||||
return TextAlignmentOptions.Baseline;
|
||||
case 14:
|
||||
return TextAlignmentOptions.BaselineRight;
|
||||
case 15:
|
||||
return TextAlignmentOptions.BaselineJustified;
|
||||
case 16:
|
||||
return TextAlignmentOptions.MidlineLeft;
|
||||
case 17:
|
||||
return TextAlignmentOptions.Midline;
|
||||
case 18:
|
||||
return TextAlignmentOptions.MidlineRight;
|
||||
case 19:
|
||||
return TextAlignmentOptions.MidlineJustified;
|
||||
case 20:
|
||||
return TextAlignmentOptions.CaplineLeft;
|
||||
case 21:
|
||||
return TextAlignmentOptions.Capline;
|
||||
case 22:
|
||||
return TextAlignmentOptions.CaplineRight;
|
||||
case 23:
|
||||
return TextAlignmentOptions.CaplineJustified;
|
||||
}
|
||||
|
||||
return TextAlignmentOptions.TopLeft;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 21364f754cf9b9b47a60742332d4af56
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,246 @@
|
|||
using UnityEngine;
|
||||
using UnityEngine.Events;
|
||||
using System.Collections;
|
||||
|
||||
|
||||
namespace TMPro
|
||||
{
|
||||
// Base interface for tweeners,
|
||||
// using an interface instead of
|
||||
// an abstract class as we want the
|
||||
// tweens to be structs.
|
||||
internal interface ITweenValue
|
||||
{
|
||||
void TweenValue(float floatPercentage);
|
||||
bool ignoreTimeScale { get; }
|
||||
float duration { get; }
|
||||
bool ValidTarget();
|
||||
}
|
||||
|
||||
// Color tween class, receives the
|
||||
// TweenValue callback and then sets
|
||||
// the value on the target.
|
||||
internal struct ColorTween : ITweenValue
|
||||
{
|
||||
public enum ColorTweenMode
|
||||
{
|
||||
All,
|
||||
RGB,
|
||||
Alpha
|
||||
}
|
||||
|
||||
public class ColorTweenCallback : UnityEvent<Color> { }
|
||||
|
||||
private ColorTweenCallback m_Target;
|
||||
private Color m_StartColor;
|
||||
private Color m_TargetColor;
|
||||
private ColorTweenMode m_TweenMode;
|
||||
|
||||
private float m_Duration;
|
||||
private bool m_IgnoreTimeScale;
|
||||
|
||||
public Color startColor
|
||||
{
|
||||
get { return m_StartColor; }
|
||||
set { m_StartColor = value; }
|
||||
}
|
||||
|
||||
public Color targetColor
|
||||
{
|
||||
get { return m_TargetColor; }
|
||||
set { m_TargetColor = value; }
|
||||
}
|
||||
|
||||
public ColorTweenMode tweenMode
|
||||
{
|
||||
get { return m_TweenMode; }
|
||||
set { m_TweenMode = value; }
|
||||
}
|
||||
|
||||
public float duration
|
||||
{
|
||||
get { return m_Duration; }
|
||||
set { m_Duration = value; }
|
||||
}
|
||||
|
||||
public bool ignoreTimeScale
|
||||
{
|
||||
get { return m_IgnoreTimeScale; }
|
||||
set { m_IgnoreTimeScale = value; }
|
||||
}
|
||||
|
||||
public void TweenValue(float floatPercentage)
|
||||
{
|
||||
if (!ValidTarget())
|
||||
return;
|
||||
|
||||
var newColor = Color.Lerp(m_StartColor, m_TargetColor, floatPercentage);
|
||||
|
||||
if (m_TweenMode == ColorTweenMode.Alpha)
|
||||
{
|
||||
newColor.r = m_StartColor.r;
|
||||
newColor.g = m_StartColor.g;
|
||||
newColor.b = m_StartColor.b;
|
||||
}
|
||||
else if (m_TweenMode == ColorTweenMode.RGB)
|
||||
{
|
||||
newColor.a = m_StartColor.a;
|
||||
}
|
||||
m_Target.Invoke(newColor);
|
||||
}
|
||||
|
||||
public void AddOnChangedCallback(UnityAction<Color> callback)
|
||||
{
|
||||
if (m_Target == null)
|
||||
m_Target = new ColorTweenCallback();
|
||||
|
||||
m_Target.AddListener(callback);
|
||||
}
|
||||
|
||||
public bool GetIgnoreTimescale()
|
||||
{
|
||||
return m_IgnoreTimeScale;
|
||||
}
|
||||
|
||||
public float GetDuration()
|
||||
{
|
||||
return m_Duration;
|
||||
}
|
||||
|
||||
public bool ValidTarget()
|
||||
{
|
||||
return m_Target != null;
|
||||
}
|
||||
}
|
||||
|
||||
// Float tween class, receives the
|
||||
// TweenValue callback and then sets
|
||||
// the value on the target.
|
||||
internal struct FloatTween : ITweenValue
|
||||
{
|
||||
public class FloatTweenCallback : UnityEvent<float> { }
|
||||
|
||||
private FloatTweenCallback m_Target;
|
||||
private float m_StartValue;
|
||||
private float m_TargetValue;
|
||||
|
||||
private float m_Duration;
|
||||
private bool m_IgnoreTimeScale;
|
||||
|
||||
public float startValue
|
||||
{
|
||||
get { return m_StartValue; }
|
||||
set { m_StartValue = value; }
|
||||
}
|
||||
|
||||
public float targetValue
|
||||
{
|
||||
get { return m_TargetValue; }
|
||||
set { m_TargetValue = value; }
|
||||
}
|
||||
|
||||
public float duration
|
||||
{
|
||||
get { return m_Duration; }
|
||||
set { m_Duration = value; }
|
||||
}
|
||||
|
||||
public bool ignoreTimeScale
|
||||
{
|
||||
get { return m_IgnoreTimeScale; }
|
||||
set { m_IgnoreTimeScale = value; }
|
||||
}
|
||||
|
||||
public void TweenValue(float floatPercentage)
|
||||
{
|
||||
if (!ValidTarget())
|
||||
return;
|
||||
|
||||
var newValue = Mathf.Lerp(m_StartValue, m_TargetValue, floatPercentage);
|
||||
m_Target.Invoke(newValue);
|
||||
}
|
||||
|
||||
public void AddOnChangedCallback(UnityAction<float> callback)
|
||||
{
|
||||
if (m_Target == null)
|
||||
m_Target = new FloatTweenCallback();
|
||||
|
||||
m_Target.AddListener(callback);
|
||||
}
|
||||
|
||||
public bool GetIgnoreTimescale()
|
||||
{
|
||||
return m_IgnoreTimeScale;
|
||||
}
|
||||
|
||||
public float GetDuration()
|
||||
{
|
||||
return m_Duration;
|
||||
}
|
||||
|
||||
public bool ValidTarget()
|
||||
{
|
||||
return m_Target != null;
|
||||
}
|
||||
}
|
||||
|
||||
// Tween runner, executes the given tween.
|
||||
// The coroutine will live within the given
|
||||
// behaviour container.
|
||||
internal class TweenRunner<T> where T : struct, ITweenValue
|
||||
{
|
||||
protected MonoBehaviour m_CoroutineContainer;
|
||||
protected IEnumerator m_Tween;
|
||||
|
||||
// utility function for starting the tween
|
||||
private static IEnumerator Start(T tweenInfo)
|
||||
{
|
||||
if (!tweenInfo.ValidTarget())
|
||||
yield break;
|
||||
|
||||
var elapsedTime = 0.0f;
|
||||
while (elapsedTime < tweenInfo.duration)
|
||||
{
|
||||
elapsedTime += tweenInfo.ignoreTimeScale ? Time.unscaledDeltaTime : Time.deltaTime;
|
||||
var percentage = Mathf.Clamp01(elapsedTime / tweenInfo.duration);
|
||||
tweenInfo.TweenValue(percentage);
|
||||
yield return null;
|
||||
}
|
||||
tweenInfo.TweenValue(1.0f);
|
||||
}
|
||||
|
||||
public void Init(MonoBehaviour coroutineContainer)
|
||||
{
|
||||
m_CoroutineContainer = coroutineContainer;
|
||||
}
|
||||
|
||||
public void StartTween(T info)
|
||||
{
|
||||
if (m_CoroutineContainer == null)
|
||||
{
|
||||
Debug.LogWarning("Coroutine container not configured... did you forget to call Init?");
|
||||
return;
|
||||
}
|
||||
|
||||
StopTween();
|
||||
|
||||
if (!m_CoroutineContainer.gameObject.activeInHierarchy)
|
||||
{
|
||||
info.TweenValue(1.0f);
|
||||
return;
|
||||
}
|
||||
|
||||
m_Tween = Start(info);
|
||||
m_CoroutineContainer.StartCoroutine(m_Tween);
|
||||
}
|
||||
|
||||
public void StopTween()
|
||||
{
|
||||
if (m_Tween != null)
|
||||
{
|
||||
m_CoroutineContainer.StopCoroutine(m_Tween);
|
||||
m_Tween = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 658c1fb149e7498aa072b0c0f3bf13f0
|
||||
timeCreated: 1464850953
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,400 @@
|
|||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using UnityEngine.UI;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
#endif
|
||||
|
||||
|
||||
namespace TMPro
|
||||
{
|
||||
|
||||
public static class TMP_DefaultControls
|
||||
{
|
||||
public struct Resources
|
||||
{
|
||||
public Sprite standard;
|
||||
public Sprite background;
|
||||
public Sprite inputField;
|
||||
public Sprite knob;
|
||||
public Sprite checkmark;
|
||||
public Sprite dropdown;
|
||||
public Sprite mask;
|
||||
}
|
||||
|
||||
private const float kWidth = 160f;
|
||||
private const float kThickHeight = 30f;
|
||||
private const float kThinHeight = 20f;
|
||||
private static Vector2 s_TextElementSize = new Vector2(100f, 100f);
|
||||
private static Vector2 s_ThickElementSize = new Vector2(kWidth, kThickHeight);
|
||||
private static Vector2 s_ThinElementSize = new Vector2(kWidth, kThinHeight);
|
||||
//private static Vector2 s_ImageElementSize = new Vector2(100f, 100f);
|
||||
private static Color s_DefaultSelectableColor = new Color(1f, 1f, 1f, 1f);
|
||||
//private static Color s_PanelColor = new Color(1f, 1f, 1f, 0.392f);
|
||||
private static Color s_TextColor = new Color(50f / 255f, 50f / 255f, 50f / 255f, 1f);
|
||||
|
||||
|
||||
private static GameObject CreateUIElementRoot(string name, Vector2 size)
|
||||
{
|
||||
GameObject child = new GameObject(name);
|
||||
RectTransform rectTransform = child.AddComponent<RectTransform>();
|
||||
rectTransform.sizeDelta = size;
|
||||
return child;
|
||||
}
|
||||
|
||||
static GameObject CreateUIObject(string name, GameObject parent)
|
||||
{
|
||||
GameObject go = new GameObject(name);
|
||||
go.AddComponent<RectTransform>();
|
||||
SetParentAndAlign(go, parent);
|
||||
return go;
|
||||
}
|
||||
|
||||
private static void SetDefaultTextValues(TMP_Text lbl)
|
||||
{
|
||||
// Set text values we want across UI elements in default controls.
|
||||
// Don't set values which are the same as the default values for the Text component,
|
||||
// since there's no point in that, and it's good to keep them as consistent as possible.
|
||||
lbl.color = s_TextColor;
|
||||
lbl.fontSize = 14;
|
||||
}
|
||||
|
||||
private static void SetDefaultColorTransitionValues(Selectable slider)
|
||||
{
|
||||
ColorBlock colors = slider.colors;
|
||||
colors.highlightedColor = new Color(0.882f, 0.882f, 0.882f);
|
||||
colors.pressedColor = new Color(0.698f, 0.698f, 0.698f);
|
||||
colors.disabledColor = new Color(0.521f, 0.521f, 0.521f);
|
||||
}
|
||||
|
||||
private static void SetParentAndAlign(GameObject child, GameObject parent)
|
||||
{
|
||||
if (parent == null)
|
||||
return;
|
||||
|
||||
child.transform.SetParent(parent.transform, false);
|
||||
SetLayerRecursively(child, parent.layer);
|
||||
}
|
||||
|
||||
private static void SetLayerRecursively(GameObject go, int layer)
|
||||
{
|
||||
go.layer = layer;
|
||||
Transform t = go.transform;
|
||||
for (int i = 0; i < t.childCount; i++)
|
||||
SetLayerRecursively(t.GetChild(i).gameObject, layer);
|
||||
}
|
||||
|
||||
// Actual controls
|
||||
|
||||
public static GameObject CreateScrollbar(Resources resources)
|
||||
{
|
||||
// Create GOs Hierarchy
|
||||
GameObject scrollbarRoot = CreateUIElementRoot("Scrollbar", s_ThinElementSize);
|
||||
|
||||
GameObject sliderArea = CreateUIObject("Sliding Area", scrollbarRoot);
|
||||
GameObject handle = CreateUIObject("Handle", sliderArea);
|
||||
|
||||
Image bgImage = scrollbarRoot.AddComponent<Image>();
|
||||
bgImage.sprite = resources.background;
|
||||
bgImage.type = Image.Type.Sliced;
|
||||
bgImage.color = s_DefaultSelectableColor;
|
||||
|
||||
Image handleImage = handle.AddComponent<Image>();
|
||||
handleImage.sprite = resources.standard;
|
||||
handleImage.type = Image.Type.Sliced;
|
||||
handleImage.color = s_DefaultSelectableColor;
|
||||
|
||||
RectTransform sliderAreaRect = sliderArea.GetComponent<RectTransform>();
|
||||
sliderAreaRect.sizeDelta = new Vector2(-20, -20);
|
||||
sliderAreaRect.anchorMin = Vector2.zero;
|
||||
sliderAreaRect.anchorMax = Vector2.one;
|
||||
|
||||
RectTransform handleRect = handle.GetComponent<RectTransform>();
|
||||
handleRect.sizeDelta = new Vector2(20, 20);
|
||||
|
||||
Scrollbar scrollbar = scrollbarRoot.AddComponent<Scrollbar>();
|
||||
scrollbar.handleRect = handleRect;
|
||||
scrollbar.targetGraphic = handleImage;
|
||||
SetDefaultColorTransitionValues(scrollbar);
|
||||
|
||||
return scrollbarRoot;
|
||||
}
|
||||
|
||||
public static GameObject CreateButton(Resources resources)
|
||||
{
|
||||
GameObject buttonRoot = CreateUIElementRoot("Button", s_ThickElementSize);
|
||||
|
||||
GameObject childText = new GameObject("Text (TMP)");
|
||||
childText.AddComponent<RectTransform>();
|
||||
SetParentAndAlign(childText, buttonRoot);
|
||||
|
||||
Image image = buttonRoot.AddComponent<Image>();
|
||||
image.sprite = resources.standard;
|
||||
image.type = Image.Type.Sliced;
|
||||
image.color = s_DefaultSelectableColor;
|
||||
|
||||
Button bt = buttonRoot.AddComponent<Button>();
|
||||
SetDefaultColorTransitionValues(bt);
|
||||
|
||||
TextMeshProUGUI text = childText.AddComponent<TextMeshProUGUI>();
|
||||
text.text = "Button";
|
||||
text.alignment = TextAlignmentOptions.Center;
|
||||
SetDefaultTextValues(text);
|
||||
|
||||
RectTransform textRectTransform = childText.GetComponent<RectTransform>();
|
||||
textRectTransform.anchorMin = Vector2.zero;
|
||||
textRectTransform.anchorMax = Vector2.one;
|
||||
textRectTransform.sizeDelta = Vector2.zero;
|
||||
|
||||
return buttonRoot;
|
||||
}
|
||||
|
||||
public static GameObject CreateText(Resources resources)
|
||||
{
|
||||
GameObject go = null;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
go = ObjectFactory.CreateGameObject("Text (TMP)");
|
||||
ObjectFactory.AddComponent<TextMeshProUGUI>(go);
|
||||
#else
|
||||
go = CreateUIElementRoot("Text (TMP)", s_TextElementSize);
|
||||
go.AddComponent<TextMeshProUGUI>();
|
||||
#endif
|
||||
|
||||
return go;
|
||||
}
|
||||
|
||||
|
||||
public static GameObject CreateInputField(Resources resources)
|
||||
{
|
||||
GameObject root = CreateUIElementRoot("InputField (TMP)", s_ThickElementSize);
|
||||
|
||||
GameObject textArea = CreateUIObject("Text Area", root);
|
||||
GameObject childPlaceholder = CreateUIObject("Placeholder", textArea);
|
||||
GameObject childText = CreateUIObject("Text", textArea);
|
||||
|
||||
Image image = root.AddComponent<Image>();
|
||||
image.sprite = resources.inputField;
|
||||
image.type = Image.Type.Sliced;
|
||||
image.color = s_DefaultSelectableColor;
|
||||
|
||||
TMP_InputField inputField = root.AddComponent<TMP_InputField>();
|
||||
SetDefaultColorTransitionValues(inputField);
|
||||
|
||||
// Use UI.Mask for Unity 5.0 - 5.1 and 2D RectMask for Unity 5.2 and up
|
||||
RectMask2D rectMask = textArea.AddComponent<RectMask2D>();
|
||||
#if UNITY_2019_4_OR_NEWER
|
||||
rectMask.padding = new Vector4(-8, -5, -8, -5);
|
||||
#endif
|
||||
|
||||
RectTransform textAreaRectTransform = textArea.GetComponent<RectTransform>();
|
||||
textAreaRectTransform.anchorMin = Vector2.zero;
|
||||
textAreaRectTransform.anchorMax = Vector2.one;
|
||||
textAreaRectTransform.sizeDelta = Vector2.zero;
|
||||
textAreaRectTransform.offsetMin = new Vector2(10, 6);
|
||||
textAreaRectTransform.offsetMax = new Vector2(-10, -7);
|
||||
|
||||
|
||||
TextMeshProUGUI text = childText.AddComponent<TextMeshProUGUI>();
|
||||
text.text = "";
|
||||
text.enableWordWrapping = false;
|
||||
text.extraPadding = true;
|
||||
text.richText = true;
|
||||
SetDefaultTextValues(text);
|
||||
|
||||
TextMeshProUGUI placeholder = childPlaceholder.AddComponent<TextMeshProUGUI>();
|
||||
placeholder.text = "Enter text...";
|
||||
placeholder.fontSize = 14;
|
||||
placeholder.fontStyle = FontStyles.Italic;
|
||||
placeholder.enableWordWrapping = false;
|
||||
placeholder.extraPadding = true;
|
||||
|
||||
// Make placeholder color half as opaque as normal text color.
|
||||
Color placeholderColor = text.color;
|
||||
placeholderColor.a *= 0.5f;
|
||||
placeholder.color = placeholderColor;
|
||||
|
||||
// Add Layout component to placeholder.
|
||||
placeholder.gameObject.AddComponent<LayoutElement>().ignoreLayout = true;
|
||||
|
||||
RectTransform textRectTransform = childText.GetComponent<RectTransform>();
|
||||
textRectTransform.anchorMin = Vector2.zero;
|
||||
textRectTransform.anchorMax = Vector2.one;
|
||||
textRectTransform.sizeDelta = Vector2.zero;
|
||||
textRectTransform.offsetMin = new Vector2(0, 0);
|
||||
textRectTransform.offsetMax = new Vector2(0, 0);
|
||||
|
||||
RectTransform placeholderRectTransform = childPlaceholder.GetComponent<RectTransform>();
|
||||
placeholderRectTransform.anchorMin = Vector2.zero;
|
||||
placeholderRectTransform.anchorMax = Vector2.one;
|
||||
placeholderRectTransform.sizeDelta = Vector2.zero;
|
||||
placeholderRectTransform.offsetMin = new Vector2(0, 0);
|
||||
placeholderRectTransform.offsetMax = new Vector2(0, 0);
|
||||
|
||||
inputField.textViewport = textAreaRectTransform;
|
||||
inputField.textComponent = text;
|
||||
inputField.placeholder = placeholder;
|
||||
inputField.fontAsset = text.font;
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
public static GameObject CreateDropdown(Resources resources)
|
||||
{
|
||||
GameObject root = CreateUIElementRoot("Dropdown", s_ThickElementSize);
|
||||
|
||||
GameObject label = CreateUIObject("Label", root);
|
||||
GameObject arrow = CreateUIObject("Arrow", root);
|
||||
GameObject template = CreateUIObject("Template", root);
|
||||
GameObject viewport = CreateUIObject("Viewport", template);
|
||||
GameObject content = CreateUIObject("Content", viewport);
|
||||
GameObject item = CreateUIObject("Item", content);
|
||||
GameObject itemBackground = CreateUIObject("Item Background", item);
|
||||
GameObject itemCheckmark = CreateUIObject("Item Checkmark", item);
|
||||
GameObject itemLabel = CreateUIObject("Item Label", item);
|
||||
|
||||
// Sub controls.
|
||||
|
||||
GameObject scrollbar = CreateScrollbar(resources);
|
||||
scrollbar.name = "Scrollbar";
|
||||
SetParentAndAlign(scrollbar, template);
|
||||
|
||||
Scrollbar scrollbarScrollbar = scrollbar.GetComponent<Scrollbar>();
|
||||
scrollbarScrollbar.SetDirection(Scrollbar.Direction.BottomToTop, true);
|
||||
|
||||
RectTransform vScrollbarRT = scrollbar.GetComponent<RectTransform>();
|
||||
vScrollbarRT.anchorMin = Vector2.right;
|
||||
vScrollbarRT.anchorMax = Vector2.one;
|
||||
vScrollbarRT.pivot = Vector2.one;
|
||||
vScrollbarRT.sizeDelta = new Vector2(vScrollbarRT.sizeDelta.x, 0);
|
||||
|
||||
// Setup item UI components.
|
||||
|
||||
TextMeshProUGUI itemLabelText = itemLabel.AddComponent<TextMeshProUGUI>();
|
||||
SetDefaultTextValues(itemLabelText);
|
||||
itemLabelText.alignment = TextAlignmentOptions.Left;
|
||||
|
||||
Image itemBackgroundImage = itemBackground.AddComponent<Image>();
|
||||
itemBackgroundImage.color = new Color32(245, 245, 245, 255);
|
||||
|
||||
Image itemCheckmarkImage = itemCheckmark.AddComponent<Image>();
|
||||
itemCheckmarkImage.sprite = resources.checkmark;
|
||||
|
||||
Toggle itemToggle = item.AddComponent<Toggle>();
|
||||
itemToggle.targetGraphic = itemBackgroundImage;
|
||||
itemToggle.graphic = itemCheckmarkImage;
|
||||
itemToggle.isOn = true;
|
||||
|
||||
// Setup template UI components.
|
||||
|
||||
Image templateImage = template.AddComponent<Image>();
|
||||
templateImage.sprite = resources.standard;
|
||||
templateImage.type = Image.Type.Sliced;
|
||||
|
||||
ScrollRect templateScrollRect = template.AddComponent<ScrollRect>();
|
||||
templateScrollRect.content = (RectTransform)content.transform;
|
||||
templateScrollRect.viewport = (RectTransform)viewport.transform;
|
||||
templateScrollRect.horizontal = false;
|
||||
templateScrollRect.movementType = ScrollRect.MovementType.Clamped;
|
||||
templateScrollRect.verticalScrollbar = scrollbarScrollbar;
|
||||
templateScrollRect.verticalScrollbarVisibility = ScrollRect.ScrollbarVisibility.AutoHideAndExpandViewport;
|
||||
templateScrollRect.verticalScrollbarSpacing = -3;
|
||||
|
||||
Mask scrollRectMask = viewport.AddComponent<Mask>();
|
||||
scrollRectMask.showMaskGraphic = false;
|
||||
|
||||
Image viewportImage = viewport.AddComponent<Image>();
|
||||
viewportImage.sprite = resources.mask;
|
||||
viewportImage.type = Image.Type.Sliced;
|
||||
|
||||
// Setup dropdown UI components.
|
||||
|
||||
TextMeshProUGUI labelText = label.AddComponent<TextMeshProUGUI>();
|
||||
SetDefaultTextValues(labelText);
|
||||
labelText.alignment = TextAlignmentOptions.Left;
|
||||
|
||||
Image arrowImage = arrow.AddComponent<Image>();
|
||||
arrowImage.sprite = resources.dropdown;
|
||||
|
||||
Image backgroundImage = root.AddComponent<Image>();
|
||||
backgroundImage.sprite = resources.standard;
|
||||
backgroundImage.color = s_DefaultSelectableColor;
|
||||
backgroundImage.type = Image.Type.Sliced;
|
||||
|
||||
TMP_Dropdown dropdown = root.AddComponent<TMP_Dropdown>();
|
||||
dropdown.targetGraphic = backgroundImage;
|
||||
SetDefaultColorTransitionValues(dropdown);
|
||||
dropdown.template = template.GetComponent<RectTransform>();
|
||||
dropdown.captionText = labelText;
|
||||
dropdown.itemText = itemLabelText;
|
||||
|
||||
// Setting default Item list.
|
||||
itemLabelText.text = "Option A";
|
||||
dropdown.options.Add(new TMP_Dropdown.OptionData {text = "Option A" });
|
||||
dropdown.options.Add(new TMP_Dropdown.OptionData {text = "Option B" });
|
||||
dropdown.options.Add(new TMP_Dropdown.OptionData {text = "Option C" });
|
||||
dropdown.RefreshShownValue();
|
||||
|
||||
// Set up RectTransforms.
|
||||
|
||||
RectTransform labelRT = label.GetComponent<RectTransform>();
|
||||
labelRT.anchorMin = Vector2.zero;
|
||||
labelRT.anchorMax = Vector2.one;
|
||||
labelRT.offsetMin = new Vector2(10, 6);
|
||||
labelRT.offsetMax = new Vector2(-25, -7);
|
||||
|
||||
RectTransform arrowRT = arrow.GetComponent<RectTransform>();
|
||||
arrowRT.anchorMin = new Vector2(1, 0.5f);
|
||||
arrowRT.anchorMax = new Vector2(1, 0.5f);
|
||||
arrowRT.sizeDelta = new Vector2(20, 20);
|
||||
arrowRT.anchoredPosition = new Vector2(-15, 0);
|
||||
|
||||
RectTransform templateRT = template.GetComponent<RectTransform>();
|
||||
templateRT.anchorMin = new Vector2(0, 0);
|
||||
templateRT.anchorMax = new Vector2(1, 0);
|
||||
templateRT.pivot = new Vector2(0.5f, 1);
|
||||
templateRT.anchoredPosition = new Vector2(0, 2);
|
||||
templateRT.sizeDelta = new Vector2(0, 150);
|
||||
|
||||
RectTransform viewportRT = viewport.GetComponent<RectTransform>();
|
||||
viewportRT.anchorMin = new Vector2(0, 0);
|
||||
viewportRT.anchorMax = new Vector2(1, 1);
|
||||
viewportRT.sizeDelta = new Vector2(-18, 0);
|
||||
viewportRT.pivot = new Vector2(0, 1);
|
||||
|
||||
RectTransform contentRT = content.GetComponent<RectTransform>();
|
||||
contentRT.anchorMin = new Vector2(0f, 1);
|
||||
contentRT.anchorMax = new Vector2(1f, 1);
|
||||
contentRT.pivot = new Vector2(0.5f, 1);
|
||||
contentRT.anchoredPosition = new Vector2(0, 0);
|
||||
contentRT.sizeDelta = new Vector2(0, 28);
|
||||
|
||||
RectTransform itemRT = item.GetComponent<RectTransform>();
|
||||
itemRT.anchorMin = new Vector2(0, 0.5f);
|
||||
itemRT.anchorMax = new Vector2(1, 0.5f);
|
||||
itemRT.sizeDelta = new Vector2(0, 20);
|
||||
|
||||
RectTransform itemBackgroundRT = itemBackground.GetComponent<RectTransform>();
|
||||
itemBackgroundRT.anchorMin = Vector2.zero;
|
||||
itemBackgroundRT.anchorMax = Vector2.one;
|
||||
itemBackgroundRT.sizeDelta = Vector2.zero;
|
||||
|
||||
RectTransform itemCheckmarkRT = itemCheckmark.GetComponent<RectTransform>();
|
||||
itemCheckmarkRT.anchorMin = new Vector2(0, 0.5f);
|
||||
itemCheckmarkRT.anchorMax = new Vector2(0, 0.5f);
|
||||
itemCheckmarkRT.sizeDelta = new Vector2(20, 20);
|
||||
itemCheckmarkRT.anchoredPosition = new Vector2(10, 0);
|
||||
|
||||
RectTransform itemLabelRT = itemLabel.GetComponent<RectTransform>();
|
||||
itemLabelRT.anchorMin = Vector2.zero;
|
||||
itemLabelRT.anchorMax = Vector2.one;
|
||||
itemLabelRT.offsetMin = new Vector2(20, 1);
|
||||
itemLabelRT.offsetMax = new Vector2(-10, -2);
|
||||
|
||||
template.SetActive(false);
|
||||
|
||||
return root;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 322392995be44d23a3c86cfd972f838f
|
||||
timeCreated: 1446378357
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 7b743370ac3e4ec2a1668f5455a8ef8a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {fileID: 2800000, guid: a7ec9e7ad8b847b7ae4510af83c5d868, type: 3}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,184 @@
|
|||
#if UNITY_EDITOR
|
||||
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
|
||||
|
||||
namespace TMPro
|
||||
{
|
||||
public class TMP_EditorResourceManager
|
||||
{
|
||||
private static TMP_EditorResourceManager s_Instance;
|
||||
|
||||
private readonly List<Object> m_ObjectUpdateQueue = new List<Object>();
|
||||
private HashSet<int> m_ObjectUpdateQueueLookup = new HashSet<int>();
|
||||
|
||||
private readonly List<Object> m_ObjectReImportQueue = new List<Object>();
|
||||
private HashSet<int> m_ObjectReImportQueueLookup = new HashSet<int>();
|
||||
|
||||
private readonly List<TMP_FontAsset> m_FontAssetDefinitionRefreshQueue = new List<TMP_FontAsset>();
|
||||
private HashSet<int> m_FontAssetDefinitionRefreshQueueLookup = new HashSet<int>();
|
||||
|
||||
/// <summary>
|
||||
/// Get a singleton instance of the manager.
|
||||
/// </summary>
|
||||
public static TMP_EditorResourceManager instance
|
||||
{
|
||||
get
|
||||
{
|
||||
if (s_Instance == null)
|
||||
s_Instance = new TMP_EditorResourceManager();
|
||||
|
||||
return s_Instance;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Register to receive rendering callbacks.
|
||||
/// </summary>
|
||||
private TMP_EditorResourceManager()
|
||||
{
|
||||
Camera.onPostRender += OnCameraPostRender;
|
||||
Canvas.willRenderCanvases += OnPreRenderCanvases;
|
||||
}
|
||||
|
||||
void OnCameraPostRender(Camera cam)
|
||||
{
|
||||
// Exclude the PreRenderCamera
|
||||
if (cam.cameraType != CameraType.SceneView)
|
||||
return;
|
||||
|
||||
DoPostRenderUpdates();
|
||||
}
|
||||
|
||||
void OnPreRenderCanvases()
|
||||
{
|
||||
DoPreRenderUpdates();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Register resource for re-import.
|
||||
/// </summary>
|
||||
/// <param name="obj"></param>
|
||||
internal static void RegisterResourceForReimport(Object obj)
|
||||
{
|
||||
instance.InternalRegisterResourceForReimport(obj);
|
||||
}
|
||||
|
||||
private void InternalRegisterResourceForReimport(Object obj)
|
||||
{
|
||||
int id = obj.GetInstanceID();
|
||||
|
||||
if (m_ObjectReImportQueueLookup.Contains(id))
|
||||
return;
|
||||
|
||||
m_ObjectReImportQueueLookup.Add(id);
|
||||
m_ObjectReImportQueue.Add(obj);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Register resource to be updated.
|
||||
/// </summary>
|
||||
/// <param name="textObject"></param>
|
||||
internal static void RegisterResourceForUpdate(Object obj)
|
||||
{
|
||||
instance.InternalRegisterResourceForUpdate(obj);
|
||||
}
|
||||
|
||||
private void InternalRegisterResourceForUpdate(Object obj)
|
||||
{
|
||||
int id = obj.GetInstanceID();
|
||||
|
||||
if (m_ObjectUpdateQueueLookup.Contains(id))
|
||||
return;
|
||||
|
||||
m_ObjectUpdateQueueLookup.Add(id);
|
||||
m_ObjectUpdateQueue.Add(obj);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="fontAsset"></param>
|
||||
internal static void RegisterFontAssetForDefinitionRefresh(TMP_FontAsset fontAsset)
|
||||
{
|
||||
instance.InternalRegisterFontAssetForDefinitionRefresh(fontAsset);
|
||||
}
|
||||
|
||||
private void InternalRegisterFontAssetForDefinitionRefresh(TMP_FontAsset fontAsset)
|
||||
{
|
||||
int id = fontAsset.GetInstanceID();
|
||||
|
||||
if (m_FontAssetDefinitionRefreshQueueLookup.Contains(id))
|
||||
return;
|
||||
|
||||
m_FontAssetDefinitionRefreshQueueLookup.Add(id);
|
||||
m_FontAssetDefinitionRefreshQueue.Add(fontAsset);
|
||||
}
|
||||
|
||||
void DoPostRenderUpdates()
|
||||
{
|
||||
// Handle objects that need updating
|
||||
int objUpdateCount = m_ObjectUpdateQueue.Count;
|
||||
|
||||
for (int i = 0; i < objUpdateCount; i++)
|
||||
{
|
||||
Object obj = m_ObjectUpdateQueue[i];
|
||||
if (obj != null)
|
||||
{
|
||||
EditorUtility.SetDirty(obj);
|
||||
}
|
||||
}
|
||||
|
||||
if (objUpdateCount > 0)
|
||||
{
|
||||
//Debug.Log("Saving assets");
|
||||
//AssetDatabase.SaveAssets();
|
||||
|
||||
m_ObjectUpdateQueue.Clear();
|
||||
m_ObjectUpdateQueueLookup.Clear();
|
||||
}
|
||||
|
||||
// Handle objects that need re-importing
|
||||
int objReImportCount = m_ObjectReImportQueue.Count;
|
||||
|
||||
for (int i = 0; i < objReImportCount; i++)
|
||||
{
|
||||
Object obj = m_ObjectReImportQueue[i];
|
||||
if (obj != null)
|
||||
{
|
||||
AssetDatabase.ImportAsset(AssetDatabase.GetAssetPath(obj));
|
||||
}
|
||||
}
|
||||
|
||||
if (objReImportCount > 0)
|
||||
{
|
||||
m_ObjectReImportQueue.Clear();
|
||||
m_ObjectReImportQueueLookup.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
void DoPreRenderUpdates()
|
||||
{
|
||||
// Handle Font Asset Definition Refresh
|
||||
for (int i = 0; i < m_FontAssetDefinitionRefreshQueue.Count; i++)
|
||||
{
|
||||
TMP_FontAsset fontAsset = m_FontAssetDefinitionRefreshQueue[i];
|
||||
|
||||
if (fontAsset != null)
|
||||
{
|
||||
fontAsset.ReadFontAssetDefinition();
|
||||
TMPro_EventManager.ON_FONT_PROPERTY_CHANGED(true, fontAsset);
|
||||
}
|
||||
}
|
||||
|
||||
if (m_FontAssetDefinitionRefreshQueue.Count > 0)
|
||||
{
|
||||
m_FontAssetDefinitionRefreshQueue.Clear();
|
||||
m_FontAssetDefinitionRefreshQueueLookup.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 6b259c4003a802847b9ada90744e34c5
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 71c1514a6bd24e1e882cebbe1904ce04
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {fileID: 2800000, guid: ee148e281f3c41c5b4ff5f8a5afe5a6c, type: 3}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,456 @@
|
|||
using UnityEngine;
|
||||
using UnityEngine.Serialization;
|
||||
using UnityEngine.TextCore;
|
||||
using UnityEngine.TextCore.LowLevel;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
|
||||
namespace TMPro
|
||||
{
|
||||
/// <summary>
|
||||
/// Class that contains the basic information about the font.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class FaceInfo_Legacy
|
||||
{
|
||||
public string Name;
|
||||
public float PointSize;
|
||||
public float Scale;
|
||||
|
||||
public int CharacterCount;
|
||||
|
||||
public float LineHeight;
|
||||
public float Baseline;
|
||||
public float Ascender;
|
||||
public float CapHeight;
|
||||
public float Descender;
|
||||
public float CenterLine;
|
||||
|
||||
public float SuperscriptOffset;
|
||||
public float SubscriptOffset;
|
||||
public float SubSize;
|
||||
|
||||
public float Underline;
|
||||
public float UnderlineThickness;
|
||||
|
||||
public float strikethrough;
|
||||
public float strikethroughThickness;
|
||||
|
||||
public float TabWidth;
|
||||
|
||||
public float Padding;
|
||||
public float AtlasWidth;
|
||||
public float AtlasHeight;
|
||||
}
|
||||
|
||||
|
||||
// Class which contains the Glyph Info / Character definition for each character contained in the font asset.
|
||||
[Serializable]
|
||||
public class TMP_Glyph : TMP_TextElement_Legacy
|
||||
{
|
||||
/// <summary>
|
||||
/// Function to create a deep copy of a GlyphInfo.
|
||||
/// </summary>
|
||||
/// <param name="source"></param>
|
||||
/// <returns></returns>
|
||||
public static TMP_Glyph Clone(TMP_Glyph source)
|
||||
{
|
||||
TMP_Glyph copy = new TMP_Glyph();
|
||||
|
||||
copy.id = source.id;
|
||||
copy.x = source.x;
|
||||
copy.y = source.y;
|
||||
copy.width = source.width;
|
||||
copy.height = source.height;
|
||||
copy.xOffset = source.xOffset;
|
||||
copy.yOffset = source.yOffset;
|
||||
copy.xAdvance = source.xAdvance;
|
||||
copy.scale = source.scale;
|
||||
|
||||
return copy;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Structure which holds the font creation settings
|
||||
[Serializable]
|
||||
public struct FontAssetCreationSettings
|
||||
{
|
||||
public string sourceFontFileName;
|
||||
public string sourceFontFileGUID;
|
||||
public int pointSizeSamplingMode;
|
||||
public int pointSize;
|
||||
public int padding;
|
||||
public int packingMode;
|
||||
public int atlasWidth;
|
||||
public int atlasHeight;
|
||||
public int characterSetSelectionMode;
|
||||
public string characterSequence;
|
||||
public string referencedFontAssetGUID;
|
||||
public string referencedTextAssetGUID;
|
||||
public int fontStyle;
|
||||
public float fontStyleModifier;
|
||||
public int renderMode;
|
||||
public bool includeFontFeatures;
|
||||
|
||||
internal FontAssetCreationSettings(string sourceFontFileGUID, int pointSize, int pointSizeSamplingMode, int padding, int packingMode, int atlasWidth, int atlasHeight, int characterSelectionMode, string characterSet, int renderMode)
|
||||
{
|
||||
this.sourceFontFileName = string.Empty;
|
||||
this.sourceFontFileGUID = sourceFontFileGUID;
|
||||
this.pointSize = pointSize;
|
||||
this.pointSizeSamplingMode = pointSizeSamplingMode;
|
||||
this.padding = padding;
|
||||
this.packingMode = packingMode;
|
||||
this.atlasWidth = atlasWidth;
|
||||
this.atlasHeight = atlasHeight;
|
||||
this.characterSequence = characterSet;
|
||||
this.characterSetSelectionMode = characterSelectionMode;
|
||||
this.renderMode = renderMode;
|
||||
|
||||
this.referencedFontAssetGUID = string.Empty;
|
||||
this.referencedTextAssetGUID = string.Empty;
|
||||
this.fontStyle = 0;
|
||||
this.fontStyleModifier = 0;
|
||||
this.includeFontFeatures = false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Contains the font assets for the regular and italic styles associated with a given font weight.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public struct TMP_FontWeightPair
|
||||
{
|
||||
public TMP_FontAsset regularTypeface;
|
||||
public TMP_FontAsset italicTypeface;
|
||||
}
|
||||
|
||||
|
||||
public struct KerningPairKey
|
||||
{
|
||||
public uint ascii_Left;
|
||||
public uint ascii_Right;
|
||||
public uint key;
|
||||
|
||||
public KerningPairKey(uint ascii_left, uint ascii_right)
|
||||
{
|
||||
ascii_Left = ascii_left;
|
||||
ascii_Right = ascii_right;
|
||||
key = (ascii_right << 16) + ascii_left;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Positional adjustments of a glyph
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public struct GlyphValueRecord_Legacy
|
||||
{
|
||||
public float xPlacement;
|
||||
public float yPlacement;
|
||||
public float xAdvance;
|
||||
public float yAdvance;
|
||||
|
||||
internal GlyphValueRecord_Legacy(UnityEngine.TextCore.LowLevel.GlyphValueRecord valueRecord)
|
||||
{
|
||||
this.xPlacement = valueRecord.xPlacement;
|
||||
this.yPlacement = valueRecord.yPlacement;
|
||||
this.xAdvance = valueRecord.xAdvance;
|
||||
this.yAdvance = valueRecord.yAdvance;
|
||||
}
|
||||
|
||||
public static GlyphValueRecord_Legacy operator +(GlyphValueRecord_Legacy a, GlyphValueRecord_Legacy b)
|
||||
{
|
||||
GlyphValueRecord_Legacy c;
|
||||
c.xPlacement = a.xPlacement + b.xPlacement;
|
||||
c.yPlacement = a.yPlacement + b.yPlacement;
|
||||
c.xAdvance = a.xAdvance + b.xAdvance;
|
||||
c.yAdvance = a.yAdvance + b.yAdvance;
|
||||
|
||||
return c;
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class KerningPair
|
||||
{
|
||||
/// <summary>
|
||||
/// The first glyph part of a kerning pair.
|
||||
/// </summary>
|
||||
public uint firstGlyph
|
||||
{
|
||||
get { return m_FirstGlyph; }
|
||||
set { m_FirstGlyph = value; }
|
||||
}
|
||||
[FormerlySerializedAs("AscII_Left")]
|
||||
[SerializeField]
|
||||
private uint m_FirstGlyph;
|
||||
|
||||
/// <summary>
|
||||
/// The positional adjustment of the first glyph.
|
||||
/// </summary>
|
||||
public GlyphValueRecord_Legacy firstGlyphAdjustments
|
||||
{
|
||||
get { return m_FirstGlyphAdjustments; }
|
||||
}
|
||||
[SerializeField]
|
||||
private GlyphValueRecord_Legacy m_FirstGlyphAdjustments;
|
||||
|
||||
/// <summary>
|
||||
/// The second glyph part of a kerning pair.
|
||||
/// </summary>
|
||||
public uint secondGlyph
|
||||
{
|
||||
get { return m_SecondGlyph; }
|
||||
set { m_SecondGlyph = value; }
|
||||
}
|
||||
[FormerlySerializedAs("AscII_Right")]
|
||||
[SerializeField]
|
||||
private uint m_SecondGlyph;
|
||||
|
||||
/// <summary>
|
||||
/// The positional adjustment of the second glyph.
|
||||
/// </summary>
|
||||
public GlyphValueRecord_Legacy secondGlyphAdjustments
|
||||
{
|
||||
get { return m_SecondGlyphAdjustments; }
|
||||
}
|
||||
[SerializeField]
|
||||
private GlyphValueRecord_Legacy m_SecondGlyphAdjustments;
|
||||
|
||||
[FormerlySerializedAs("XadvanceOffset")]
|
||||
public float xOffset;
|
||||
|
||||
internal static KerningPair empty = new KerningPair(0, new GlyphValueRecord_Legacy(), 0, new GlyphValueRecord_Legacy());
|
||||
|
||||
/// <summary>
|
||||
/// Determines if the Character Spacing property of the text object will affect the kerning pair.
|
||||
/// This is mostly relevant when using Diacritical marks to prevent Character Spacing from altering the
|
||||
/// </summary>
|
||||
public bool ignoreSpacingAdjustments
|
||||
{
|
||||
get { return m_IgnoreSpacingAdjustments; }
|
||||
}
|
||||
[SerializeField]
|
||||
private bool m_IgnoreSpacingAdjustments = false;
|
||||
|
||||
public KerningPair()
|
||||
{
|
||||
m_FirstGlyph = 0;
|
||||
m_FirstGlyphAdjustments = new GlyphValueRecord_Legacy();
|
||||
|
||||
m_SecondGlyph = 0;
|
||||
m_SecondGlyphAdjustments = new GlyphValueRecord_Legacy();
|
||||
}
|
||||
|
||||
public KerningPair(uint left, uint right, float offset)
|
||||
{
|
||||
firstGlyph = left;
|
||||
m_SecondGlyph = right;
|
||||
xOffset = offset;
|
||||
}
|
||||
|
||||
public KerningPair(uint firstGlyph, GlyphValueRecord_Legacy firstGlyphAdjustments, uint secondGlyph, GlyphValueRecord_Legacy secondGlyphAdjustments)
|
||||
{
|
||||
m_FirstGlyph = firstGlyph;
|
||||
m_FirstGlyphAdjustments = firstGlyphAdjustments;
|
||||
m_SecondGlyph = secondGlyph;
|
||||
m_SecondGlyphAdjustments = secondGlyphAdjustments;
|
||||
}
|
||||
|
||||
internal void ConvertLegacyKerningData()
|
||||
{
|
||||
m_FirstGlyphAdjustments.xAdvance = xOffset;
|
||||
//xOffset = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class KerningTable
|
||||
{
|
||||
public List<KerningPair> kerningPairs;
|
||||
|
||||
public KerningTable()
|
||||
{
|
||||
kerningPairs = new List<KerningPair>();
|
||||
}
|
||||
|
||||
|
||||
public void AddKerningPair()
|
||||
{
|
||||
if (kerningPairs.Count == 0)
|
||||
{
|
||||
kerningPairs.Add(new KerningPair(0, 0, 0));
|
||||
}
|
||||
else
|
||||
{
|
||||
uint left = kerningPairs.Last().firstGlyph;
|
||||
uint right = kerningPairs.Last().secondGlyph;
|
||||
float xoffset = kerningPairs.Last().xOffset;
|
||||
|
||||
kerningPairs.Add(new KerningPair(left, right, xoffset));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Add Kerning Pair
|
||||
/// </summary>
|
||||
/// <param name="first">First glyph</param>
|
||||
/// <param name="second">Second glyph</param>
|
||||
/// <param name="offset">xAdvance value</param>
|
||||
/// <returns></returns>
|
||||
public int AddKerningPair(uint first, uint second, float offset)
|
||||
{
|
||||
int index = kerningPairs.FindIndex(item => item.firstGlyph == first && item.secondGlyph == second);
|
||||
|
||||
if (index == -1)
|
||||
{
|
||||
kerningPairs.Add(new KerningPair(first, second, offset));
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Return -1 if Kerning Pair already exists.
|
||||
return -1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add Glyph pair adjustment record
|
||||
/// </summary>
|
||||
/// <param name="firstGlyph">The first glyph</param>
|
||||
/// <param name="firstGlyphAdjustments">Adjustment record for the first glyph</param>
|
||||
/// <param name="secondGlyph">The second glyph</param>
|
||||
/// <param name="secondGlyphAdjustments">Adjustment record for the second glyph</param>
|
||||
/// <returns></returns>
|
||||
public int AddGlyphPairAdjustmentRecord(uint first, GlyphValueRecord_Legacy firstAdjustments, uint second, GlyphValueRecord_Legacy secondAdjustments)
|
||||
{
|
||||
int index = kerningPairs.FindIndex(item => item.firstGlyph == first && item.secondGlyph == second);
|
||||
|
||||
if (index == -1)
|
||||
{
|
||||
kerningPairs.Add(new KerningPair(first, firstAdjustments, second, secondAdjustments));
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Return -1 if Kerning Pair already exists.
|
||||
return -1;
|
||||
}
|
||||
|
||||
public void RemoveKerningPair(int left, int right)
|
||||
{
|
||||
int index = kerningPairs.FindIndex(item => item.firstGlyph == left && item.secondGlyph == right);
|
||||
|
||||
if (index != -1)
|
||||
kerningPairs.RemoveAt(index);
|
||||
}
|
||||
|
||||
|
||||
public void RemoveKerningPair(int index)
|
||||
{
|
||||
kerningPairs.RemoveAt(index);
|
||||
}
|
||||
|
||||
|
||||
public void SortKerningPairs()
|
||||
{
|
||||
// Sort List of Kerning Info
|
||||
if (kerningPairs.Count > 0)
|
||||
kerningPairs = kerningPairs.OrderBy(s => s.firstGlyph).ThenBy(s => s.secondGlyph).ToList();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static class TMP_FontUtilities
|
||||
{
|
||||
private static List<int> k_searchedFontAssets;
|
||||
|
||||
/// <summary>
|
||||
/// Search through the given font and its fallbacks for the specified character.
|
||||
/// </summary>
|
||||
/// <param name="font">The font asset to search for the given character.</param>
|
||||
/// <param name="unicode">The character to find.</param>
|
||||
/// <param name="character">out parameter containing the glyph for the specified character (if found).</param>
|
||||
/// <returns></returns>
|
||||
public static TMP_FontAsset SearchForCharacter(TMP_FontAsset font, uint unicode, out TMP_Character character)
|
||||
{
|
||||
if (k_searchedFontAssets == null)
|
||||
k_searchedFontAssets = new List<int>();
|
||||
|
||||
k_searchedFontAssets.Clear();
|
||||
|
||||
return SearchForCharacterInternal(font, unicode, out character);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Search through the given list of fonts and their possible fallbacks for the specified character.
|
||||
/// </summary>
|
||||
/// <param name="fonts"></param>
|
||||
/// <param name="unicode"></param>
|
||||
/// <param name="character"></param>
|
||||
/// <returns></returns>
|
||||
public static TMP_FontAsset SearchForCharacter(List<TMP_FontAsset> fonts, uint unicode, out TMP_Character character)
|
||||
{
|
||||
return SearchForCharacterInternal(fonts, unicode, out character);
|
||||
}
|
||||
|
||||
|
||||
private static TMP_FontAsset SearchForCharacterInternal(TMP_FontAsset font, uint unicode, out TMP_Character character)
|
||||
{
|
||||
character = null;
|
||||
|
||||
if (font == null) return null;
|
||||
|
||||
if (font.characterLookupTable.TryGetValue(unicode, out character))
|
||||
{
|
||||
return font;
|
||||
}
|
||||
else if (font.fallbackFontAssetTable != null && font.fallbackFontAssetTable.Count > 0)
|
||||
{
|
||||
for (int i = 0; i < font.fallbackFontAssetTable.Count && character == null; i++)
|
||||
{
|
||||
TMP_FontAsset temp = font.fallbackFontAssetTable[i];
|
||||
if (temp == null) continue;
|
||||
|
||||
int id = temp.GetInstanceID();
|
||||
|
||||
// Skip over the fallback font asset in the event it is null or if already searched.
|
||||
if (k_searchedFontAssets.Contains(id)) continue;
|
||||
|
||||
// Add to list of font assets already searched.
|
||||
k_searchedFontAssets.Add(id);
|
||||
|
||||
temp = SearchForCharacterInternal(temp, unicode, out character);
|
||||
|
||||
if (temp != null)
|
||||
return temp;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
private static TMP_FontAsset SearchForCharacterInternal(List<TMP_FontAsset> fonts, uint unicode, out TMP_Character character)
|
||||
{
|
||||
character = null;
|
||||
|
||||
if (fonts != null && fonts.Count > 0)
|
||||
{
|
||||
for (int i = 0; i < fonts.Count; i++)
|
||||
{
|
||||
TMP_FontAsset fontAsset = SearchForCharacterInternal(fonts[i], unicode, out character);
|
||||
|
||||
if (fontAsset != null)
|
||||
return fontAsset;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
fileFormatVersion: 2
|
||||
guid: f695b5f9415c40b39ae877eaff41c96e
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,442 @@
|
|||
using System.Collections.Generic;
|
||||
using UnityEngine.TextCore;
|
||||
using UnityEngine.TextCore.LowLevel;
|
||||
|
||||
|
||||
namespace TMPro
|
||||
{
|
||||
public class TMP_FontAssetUtilities
|
||||
{
|
||||
private static readonly TMP_FontAssetUtilities s_Instance = new TMP_FontAssetUtilities();
|
||||
|
||||
/// <summary>
|
||||
/// Default constructor
|
||||
/// </summary>
|
||||
static TMP_FontAssetUtilities() { }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Get a singleton instance of the Font Asset Utilities class.
|
||||
/// </summary>
|
||||
public static TMP_FontAssetUtilities instance
|
||||
{
|
||||
get { return s_Instance; }
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// HashSet containing instance ID of font assets already searched.
|
||||
/// </summary>
|
||||
private static HashSet<int> k_SearchedAssets;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Returns the text element (character) for the given unicode value taking into consideration the requested font style and weight.
|
||||
/// Function searches the source font asset, its list of font assets assigned as alternative typefaces and potentially its fallbacks.
|
||||
/// The font asset out parameter contains a reference to the font asset containing the character.
|
||||
/// The typeface type indicates whether the returned font asset is the source font asset, an alternative typeface or fallback font asset.
|
||||
/// </summary>
|
||||
/// <param name="unicode">The unicode value of the requested character</param>
|
||||
/// <param name="sourceFontAsset">The font asset to be searched</param>
|
||||
/// <param name="includeFallbacks">Include the fallback font assets in the search</param>
|
||||
/// <param name="fontStyle">The font style</param>
|
||||
/// <param name="fontWeight">The font weight</param>
|
||||
/// <param name="isAlternativeTypeface">Indicates if the OUT font asset is an alternative typeface or fallback font asset</param>
|
||||
/// <param name="fontAsset">The font asset that contains the requested character</param>
|
||||
/// <returns></returns>
|
||||
public static TMP_Character GetCharacterFromFontAsset(uint unicode, TMP_FontAsset sourceFontAsset, bool includeFallbacks, FontStyles fontStyle, FontWeight fontWeight, out bool isAlternativeTypeface)
|
||||
{
|
||||
if (includeFallbacks)
|
||||
{
|
||||
if (k_SearchedAssets == null)
|
||||
k_SearchedAssets = new HashSet<int>();
|
||||
else
|
||||
k_SearchedAssets.Clear();
|
||||
}
|
||||
|
||||
return GetCharacterFromFontAsset_Internal(unicode, sourceFontAsset, includeFallbacks, fontStyle, fontWeight, out isAlternativeTypeface);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Internal function returning the text element character for the given unicode value taking into consideration the font style and weight.
|
||||
/// Function searches the source font asset, list of font assets assigned as alternative typefaces and list of fallback font assets.
|
||||
/// </summary>
|
||||
private static TMP_Character GetCharacterFromFontAsset_Internal(uint unicode, TMP_FontAsset sourceFontAsset, bool includeFallbacks, FontStyles fontStyle, FontWeight fontWeight, out bool isAlternativeTypeface)
|
||||
{
|
||||
isAlternativeTypeface = false;
|
||||
TMP_Character character = null;
|
||||
|
||||
#region FONT WEIGHT AND FONT STYLE HANDLING
|
||||
// Determine if a font weight or style is used. If so check if an alternative typeface is assigned for the given weight and / or style.
|
||||
bool isItalic = (fontStyle & FontStyles.Italic) == FontStyles.Italic;
|
||||
|
||||
if (isItalic || fontWeight != FontWeight.Regular)
|
||||
{
|
||||
// Get reference to the font weight pairs of the given font asset.
|
||||
TMP_FontWeightPair[] fontWeights = sourceFontAsset.fontWeightTable;
|
||||
|
||||
int fontWeightIndex = 4;
|
||||
switch (fontWeight)
|
||||
{
|
||||
case FontWeight.Thin:
|
||||
fontWeightIndex = 1;
|
||||
break;
|
||||
case FontWeight.ExtraLight:
|
||||
fontWeightIndex = 2;
|
||||
break;
|
||||
case FontWeight.Light:
|
||||
fontWeightIndex = 3;
|
||||
break;
|
||||
case FontWeight.Regular:
|
||||
fontWeightIndex = 4;
|
||||
break;
|
||||
case FontWeight.Medium:
|
||||
fontWeightIndex = 5;
|
||||
break;
|
||||
case FontWeight.SemiBold:
|
||||
fontWeightIndex = 6;
|
||||
break;
|
||||
case FontWeight.Bold:
|
||||
fontWeightIndex = 7;
|
||||
break;
|
||||
case FontWeight.Heavy:
|
||||
fontWeightIndex = 8;
|
||||
break;
|
||||
case FontWeight.Black:
|
||||
fontWeightIndex = 9;
|
||||
break;
|
||||
}
|
||||
|
||||
TMP_FontAsset temp = isItalic ? fontWeights[fontWeightIndex].italicTypeface : fontWeights[fontWeightIndex].regularTypeface;
|
||||
|
||||
if (temp != null)
|
||||
{
|
||||
if (temp.characterLookupTable.TryGetValue(unicode, out character))
|
||||
{
|
||||
isAlternativeTypeface = true;
|
||||
|
||||
return character;
|
||||
}
|
||||
|
||||
if (temp.atlasPopulationMode == AtlasPopulationMode.Dynamic)
|
||||
{
|
||||
if (temp.TryAddCharacterInternal(unicode, out character))
|
||||
{
|
||||
isAlternativeTypeface = true;
|
||||
|
||||
return character;
|
||||
}
|
||||
|
||||
// Check if the source font file contains the requested character.
|
||||
//if (TryGetCharacterFromFontFile(unicode, fontAsset, out characterData))
|
||||
//{
|
||||
// isAlternativeTypeface = true;
|
||||
|
||||
// return characterData;
|
||||
//}
|
||||
|
||||
// If we find the requested character, we add it to the font asset character table
|
||||
// and return its character data.
|
||||
// We also add this character to the list of characters we will need to add to the font atlas.
|
||||
// We assume the font atlas has room otherwise this font asset should not be marked as dynamic.
|
||||
// Alternatively, we could also add multiple pages of font atlas textures (feature consideration).
|
||||
}
|
||||
|
||||
// At this point, we were not able to find the requested character in the alternative typeface
|
||||
// so we check the source font asset and its potential fallbacks.
|
||||
}
|
||||
|
||||
}
|
||||
#endregion
|
||||
|
||||
// Search the source font asset for the requested character.
|
||||
if (sourceFontAsset.characterLookupTable.TryGetValue(unicode, out character))
|
||||
return character;
|
||||
|
||||
if (sourceFontAsset.atlasPopulationMode == AtlasPopulationMode.Dynamic)
|
||||
{
|
||||
if (sourceFontAsset.TryAddCharacterInternal(unicode, out character))
|
||||
return character;
|
||||
}
|
||||
|
||||
// Search fallback font assets if we still don't have a valid character and include fallback is set to true.
|
||||
if (character == null && includeFallbacks && sourceFontAsset.fallbackFontAssetTable != null)
|
||||
{
|
||||
// Get reference to the list of fallback font assets.
|
||||
List<TMP_FontAsset> fallbackFontAssets = sourceFontAsset.fallbackFontAssetTable;
|
||||
int fallbackCount = fallbackFontAssets.Count;
|
||||
|
||||
if (fallbackCount == 0)
|
||||
return null;
|
||||
|
||||
for (int i = 0; i < fallbackCount; i++)
|
||||
{
|
||||
TMP_FontAsset temp = fallbackFontAssets[i];
|
||||
|
||||
if (temp == null)
|
||||
continue;
|
||||
|
||||
int id = temp.instanceID;
|
||||
|
||||
// Try adding font asset to search list. If already present skip to the next one otherwise check if it contains the requested character.
|
||||
if (k_SearchedAssets.Add(id) == false)
|
||||
continue;
|
||||
|
||||
// Add reference to this search query
|
||||
sourceFontAsset.FallbackSearchQueryLookup.Add(id);
|
||||
|
||||
character = GetCharacterFromFontAsset_Internal(unicode, temp, true, fontStyle, fontWeight, out isAlternativeTypeface);
|
||||
|
||||
if (character != null)
|
||||
return character;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Returns the text element (character) for the given unicode value taking into consideration the requested font style and weight.
|
||||
/// Function searches the provided list of font assets, the list of font assets assigned as alternative typefaces to them as well as their fallbacks.
|
||||
/// The font asset out parameter contains a reference to the font asset containing the character.
|
||||
/// The typeface type indicates whether the returned font asset is the source font asset, an alternative typeface or fallback font asset.
|
||||
/// </summary>
|
||||
/// <param name="unicode">The unicode value of the requested character</param>
|
||||
/// <param name="sourceFontAsset">The font asset originating the search query</param>
|
||||
/// <param name="fontAssets">The list of font assets to search</param>
|
||||
/// <param name="includeFallbacks">Determines if the fallback of each font assets on the list will be searched</param>
|
||||
/// <param name="fontStyle">The font style</param>
|
||||
/// <param name="fontWeight">The font weight</param>
|
||||
/// <param name="isAlternativeTypeface">Determines if the OUT font asset is an alternative typeface or fallback font asset</param>
|
||||
/// <returns></returns>
|
||||
public static TMP_Character GetCharacterFromFontAssets(uint unicode, TMP_FontAsset sourceFontAsset, List<TMP_FontAsset> fontAssets, bool includeFallbacks, FontStyles fontStyle, FontWeight fontWeight, out bool isAlternativeTypeface)
|
||||
{
|
||||
isAlternativeTypeface = false;
|
||||
|
||||
// Make sure font asset list is valid
|
||||
if (fontAssets == null || fontAssets.Count == 0)
|
||||
return null;
|
||||
|
||||
if (includeFallbacks)
|
||||
{
|
||||
if (k_SearchedAssets == null)
|
||||
k_SearchedAssets = new HashSet<int>();
|
||||
else
|
||||
k_SearchedAssets.Clear();
|
||||
}
|
||||
|
||||
int fontAssetCount = fontAssets.Count;
|
||||
|
||||
for (int i = 0; i < fontAssetCount; i++)
|
||||
{
|
||||
TMP_FontAsset fontAsset = fontAssets[i];
|
||||
|
||||
if (fontAsset == null) continue;
|
||||
|
||||
// Add reference to this search query
|
||||
sourceFontAsset.FallbackSearchQueryLookup.Add(fontAsset.instanceID);
|
||||
|
||||
TMP_Character character = GetCharacterFromFontAsset_Internal(unicode, fontAsset, includeFallbacks, fontStyle, fontWeight, out isAlternativeTypeface);
|
||||
|
||||
if (character != null)
|
||||
return character;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// =====================================================================
|
||||
// SPRITE ASSET - Functions
|
||||
// =====================================================================
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="unicode"></param>
|
||||
/// <param name="spriteAsset"></param>
|
||||
/// <param name="includeFallbacks"></param>
|
||||
/// <returns></returns>
|
||||
public static TMP_SpriteCharacter GetSpriteCharacterFromSpriteAsset(uint unicode, TMP_SpriteAsset spriteAsset, bool includeFallbacks)
|
||||
{
|
||||
// Make sure we have a valid sprite asset to search
|
||||
if (spriteAsset == null)
|
||||
return null;
|
||||
|
||||
TMP_SpriteCharacter spriteCharacter;
|
||||
|
||||
// Search sprite asset for potential sprite character for the given unicode value
|
||||
if (spriteAsset.spriteCharacterLookupTable.TryGetValue(unicode, out spriteCharacter))
|
||||
return spriteCharacter;
|
||||
|
||||
if (includeFallbacks)
|
||||
{
|
||||
// Clear searched assets
|
||||
if (k_SearchedAssets == null)
|
||||
k_SearchedAssets = new HashSet<int>();
|
||||
else
|
||||
k_SearchedAssets.Clear();
|
||||
|
||||
// Add current sprite asset to already searched assets.
|
||||
k_SearchedAssets.Add(spriteAsset.instanceID);
|
||||
|
||||
List<TMP_SpriteAsset> fallbackSpriteAsset = spriteAsset.fallbackSpriteAssets;
|
||||
|
||||
if (fallbackSpriteAsset != null && fallbackSpriteAsset.Count > 0)
|
||||
{
|
||||
int fallbackCount = fallbackSpriteAsset.Count;
|
||||
|
||||
for (int i = 0; i < fallbackCount; i++)
|
||||
{
|
||||
TMP_SpriteAsset temp = fallbackSpriteAsset[i];
|
||||
|
||||
if (temp == null)
|
||||
continue;
|
||||
|
||||
int id = temp.instanceID;
|
||||
|
||||
// Try adding asset to search list. If already present skip to the next one otherwise check if it contains the requested character.
|
||||
if (k_SearchedAssets.Add(id) == false)
|
||||
continue;
|
||||
|
||||
spriteCharacter = GetSpriteCharacterFromSpriteAsset_Internal(unicode, temp, true);
|
||||
|
||||
if (spriteCharacter != null)
|
||||
return spriteCharacter;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="unicode"></param>
|
||||
/// <param name="spriteAsset"></param>
|
||||
/// <param name="includeFallbacks"></param>
|
||||
/// <returns></returns>
|
||||
static TMP_SpriteCharacter GetSpriteCharacterFromSpriteAsset_Internal(uint unicode, TMP_SpriteAsset spriteAsset, bool includeFallbacks)
|
||||
{
|
||||
TMP_SpriteCharacter spriteCharacter;
|
||||
|
||||
// Search sprite asset for potential sprite character for the given unicode value
|
||||
if (spriteAsset.spriteCharacterLookupTable.TryGetValue(unicode, out spriteCharacter))
|
||||
return spriteCharacter;
|
||||
|
||||
if (includeFallbacks)
|
||||
{
|
||||
List<TMP_SpriteAsset> fallbackSpriteAsset = spriteAsset.fallbackSpriteAssets;
|
||||
|
||||
if (fallbackSpriteAsset != null && fallbackSpriteAsset.Count > 0)
|
||||
{
|
||||
int fallbackCount = fallbackSpriteAsset.Count;
|
||||
|
||||
for (int i = 0; i < fallbackCount; i++)
|
||||
{
|
||||
TMP_SpriteAsset temp = fallbackSpriteAsset[i];
|
||||
|
||||
if (temp == null)
|
||||
continue;
|
||||
|
||||
int id = temp.instanceID;
|
||||
|
||||
// Try adding asset to search list. If already present skip to the next one otherwise check if it contains the requested character.
|
||||
if (k_SearchedAssets.Add(id) == false)
|
||||
continue;
|
||||
|
||||
spriteCharacter = GetSpriteCharacterFromSpriteAsset_Internal(unicode, temp, true);
|
||||
|
||||
if (spriteCharacter != null)
|
||||
return spriteCharacter;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
// =====================================================================
|
||||
// FONT ENGINE & FONT FILE MANAGEMENT - Fields, Properties and Functions
|
||||
// =====================================================================
|
||||
|
||||
private static bool k_IsFontEngineInitialized;
|
||||
|
||||
/*
|
||||
private static bool TryGetCharacterFromFontFile(uint unicode, TMP_FontAsset fontAsset, out TMP_Character character)
|
||||
{
|
||||
character = null;
|
||||
|
||||
// Initialize Font Engine library if not already initialized
|
||||
if (k_IsFontEngineInitialized == false)
|
||||
{
|
||||
FontEngineError error = FontEngine.InitializeFontEngine();
|
||||
|
||||
if (error == 0)
|
||||
k_IsFontEngineInitialized = true;
|
||||
}
|
||||
|
||||
// Load the font face for the given font asset.
|
||||
// TODO: Add manager to keep track of which font faces are currently loaded.
|
||||
FontEngine.LoadFontFace(fontAsset.sourceFontFile, fontAsset.faceInfo.pointSize);
|
||||
|
||||
Glyph glyph = null;
|
||||
uint glyphIndex = FontEngine.GetGlyphIndex(unicode);
|
||||
|
||||
// Check if glyph is already contained in the font asset as the same glyph might be referenced by multiple character.
|
||||
if (fontAsset.glyphLookupTable.TryGetValue(glyphIndex, out glyph))
|
||||
{
|
||||
character = fontAsset.AddCharacter_Internal(unicode, glyph);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
GlyphLoadFlags glyphLoadFlags = ((GlyphRasterModes)fontAsset.atlasRenderMode & GlyphRasterModes.RASTER_MODE_HINTED) == GlyphRasterModes.RASTER_MODE_HINTED ? GlyphLoadFlags.LOAD_RENDER : GlyphLoadFlags.LOAD_RENDER | GlyphLoadFlags.LOAD_NO_HINTING;
|
||||
|
||||
if (FontEngine.TryGetGlyphWithUnicodeValue(unicode, glyphLoadFlags, out glyph))
|
||||
{
|
||||
// Add new character to font asset (if needed)
|
||||
character = fontAsset.AddCharacter_Internal(unicode, glyph);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public static bool TryGetGlyphFromFontFile(uint glyphIndex, TMP_FontAsset fontAsset, out Glyph glyph)
|
||||
{
|
||||
glyph = null;
|
||||
|
||||
// Initialize Font Engine library if not already initialized
|
||||
if (k_IsFontEngineInitialized == false)
|
||||
{
|
||||
FontEngineError error = FontEngine.InitializeFontEngine();
|
||||
|
||||
if (error == 0)
|
||||
k_IsFontEngineInitialized = true;
|
||||
}
|
||||
|
||||
// Load the font face for the given font asset.
|
||||
// TODO: Add manager to keep track of which font faces are currently loaded.
|
||||
FontEngine.LoadFontFace(fontAsset.sourceFontFile, fontAsset.faceInfo.pointSize);
|
||||
|
||||
GlyphLoadFlags glyphLoadFlags = ((GlyphRasterModes)fontAsset.atlasRenderMode & GlyphRasterModes.RASTER_MODE_HINTED) == GlyphRasterModes.RASTER_MODE_HINTED ? GlyphLoadFlags.LOAD_RENDER : GlyphLoadFlags.LOAD_RENDER | GlyphLoadFlags.LOAD_NO_HINTING;
|
||||
|
||||
if (FontEngine.TryGetGlyphWithIndexValue(glyphIndex, glyphLoadFlags, out glyph))
|
||||
{
|
||||
// Add new glyph to font asset (if needed)
|
||||
//fontAsset.AddGlyph_Internal(glyph);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 0a017569bfe174e4890797b4d64cbabc
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,55 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
namespace TMPro
|
||||
{
|
||||
/// <summary>
|
||||
/// Table that contains the various font features available for the given font asset.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class TMP_FontFeatureTable
|
||||
{
|
||||
/// <summary>
|
||||
/// List that contains the glyph pair adjustment records.
|
||||
/// </summary>
|
||||
public List<TMP_GlyphPairAdjustmentRecord> glyphPairAdjustmentRecords
|
||||
{
|
||||
get { return m_GlyphPairAdjustmentRecords; }
|
||||
set { m_GlyphPairAdjustmentRecords = value; }
|
||||
}
|
||||
[SerializeField]
|
||||
internal List<TMP_GlyphPairAdjustmentRecord> m_GlyphPairAdjustmentRecords;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
internal Dictionary<uint, TMP_GlyphPairAdjustmentRecord> m_GlyphPairAdjustmentRecordLookupDictionary;
|
||||
|
||||
// =============================================
|
||||
// Constructor(s)
|
||||
// =============================================
|
||||
|
||||
public TMP_FontFeatureTable()
|
||||
{
|
||||
m_GlyphPairAdjustmentRecords = new List<TMP_GlyphPairAdjustmentRecord>();
|
||||
m_GlyphPairAdjustmentRecordLookupDictionary = new Dictionary<uint, TMP_GlyphPairAdjustmentRecord>();
|
||||
}
|
||||
|
||||
// =============================================
|
||||
// Utility Functions
|
||||
// =============================================
|
||||
|
||||
/// <summary>
|
||||
/// Sort the glyph pair adjustment records by glyph index.
|
||||
/// </summary>
|
||||
public void SortGlyphPairAdjustmentRecords()
|
||||
{
|
||||
// Sort List of Kerning Info
|
||||
if (m_GlyphPairAdjustmentRecords.Count > 0)
|
||||
m_GlyphPairAdjustmentRecords = m_GlyphPairAdjustmentRecords.OrderBy(s => s.firstAdjustmentRecord.glyphIndex).ThenBy(s => s.secondAdjustmentRecord.glyphIndex).ToList();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 5ea9f573d4b800a49b9d83a1f61c0a88
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,227 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.TextCore.LowLevel;
|
||||
|
||||
|
||||
namespace TMPro
|
||||
{
|
||||
[Flags]
|
||||
public enum FontFeatureLookupFlags
|
||||
{
|
||||
None = 0x0,
|
||||
IgnoreLigatures = 0x004,
|
||||
IgnoreSpacingAdjustments = 0x100,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The values used to adjust the position of a glyph or set of glyphs.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public struct TMP_GlyphValueRecord
|
||||
{
|
||||
/// <summary>
|
||||
/// The positional adjustment affecting the horizontal bearing X of the glyph.
|
||||
/// </summary>
|
||||
public float xPlacement { get { return m_XPlacement; } set { m_XPlacement = value; } }
|
||||
|
||||
/// <summary>
|
||||
/// The positional adjustment affecting the horizontal bearing Y of the glyph.
|
||||
/// </summary>
|
||||
public float yPlacement { get { return m_YPlacement; } set { m_YPlacement = value; } }
|
||||
|
||||
/// <summary>
|
||||
/// The positional adjustment affecting the horizontal advance of the glyph.
|
||||
/// </summary>
|
||||
public float xAdvance { get { return m_XAdvance; } set { m_XAdvance = value; } }
|
||||
|
||||
/// <summary>
|
||||
/// The positional adjustment affecting the vertical advance of the glyph.
|
||||
/// </summary>
|
||||
public float yAdvance { get { return m_YAdvance; } set { m_YAdvance = value; } }
|
||||
|
||||
// =============================================
|
||||
// Private backing fields for public properties.
|
||||
// =============================================
|
||||
|
||||
[SerializeField]
|
||||
internal float m_XPlacement;
|
||||
|
||||
[SerializeField]
|
||||
internal float m_YPlacement;
|
||||
|
||||
[SerializeField]
|
||||
internal float m_XAdvance;
|
||||
|
||||
[SerializeField]
|
||||
internal float m_YAdvance;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
/// <param name="xPlacement">The positional adjustment affecting the horizontal bearing X of the glyph.</param>
|
||||
/// <param name="yPlacement">The positional adjustment affecting the horizontal bearing Y of the glyph.</param>
|
||||
/// <param name="xAdvance">The positional adjustment affecting the horizontal advance of the glyph.</param>
|
||||
/// <param name="yAdvance">The positional adjustment affecting the vertical advance of the glyph.</param>
|
||||
public TMP_GlyphValueRecord(float xPlacement, float yPlacement, float xAdvance, float yAdvance)
|
||||
{
|
||||
m_XPlacement = xPlacement;
|
||||
m_YPlacement = yPlacement;
|
||||
m_XAdvance = xAdvance;
|
||||
m_YAdvance = yAdvance;
|
||||
}
|
||||
|
||||
internal TMP_GlyphValueRecord(GlyphValueRecord_Legacy valueRecord)
|
||||
{
|
||||
m_XPlacement = valueRecord.xPlacement;
|
||||
m_YPlacement = valueRecord.yPlacement;
|
||||
m_XAdvance = valueRecord.xAdvance;
|
||||
m_YAdvance = valueRecord.yAdvance;
|
||||
}
|
||||
|
||||
internal TMP_GlyphValueRecord(GlyphValueRecord valueRecord)
|
||||
{
|
||||
m_XPlacement = valueRecord.xPlacement;
|
||||
m_YPlacement = valueRecord.yPlacement;
|
||||
m_XAdvance = valueRecord.xAdvance;
|
||||
m_YAdvance = valueRecord.yAdvance;
|
||||
}
|
||||
|
||||
public static TMP_GlyphValueRecord operator +(TMP_GlyphValueRecord a, TMP_GlyphValueRecord b)
|
||||
{
|
||||
TMP_GlyphValueRecord c;
|
||||
c.m_XPlacement = a.xPlacement + b.xPlacement;
|
||||
c.m_YPlacement = a.yPlacement + b.yPlacement;
|
||||
c.m_XAdvance = a.xAdvance + b.xAdvance;
|
||||
c.m_YAdvance = a.yAdvance + b.yAdvance;
|
||||
|
||||
return c;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The positional adjustment values of a glyph.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public struct TMP_GlyphAdjustmentRecord
|
||||
{
|
||||
/// <summary>
|
||||
/// The index of the glyph in the source font file.
|
||||
/// </summary>
|
||||
public uint glyphIndex { get { return m_GlyphIndex; } set { m_GlyphIndex = value; } }
|
||||
|
||||
/// <summary>
|
||||
/// The GlyphValueRecord contains the positional adjustments of the glyph.
|
||||
/// </summary>
|
||||
public TMP_GlyphValueRecord glyphValueRecord { get { return m_GlyphValueRecord; } set { m_GlyphValueRecord = value; } }
|
||||
|
||||
// =============================================
|
||||
// Private backing fields for public properties.
|
||||
// =============================================
|
||||
|
||||
[SerializeField]
|
||||
internal uint m_GlyphIndex;
|
||||
|
||||
[SerializeField]
|
||||
internal TMP_GlyphValueRecord m_GlyphValueRecord;
|
||||
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
/// <param name="glyphIndex">The index of the glyph in the source font file.</param>
|
||||
/// <param name="glyphValueRecord">The GlyphValueRecord contains the positional adjustments of the glyph.</param>
|
||||
public TMP_GlyphAdjustmentRecord(uint glyphIndex, TMP_GlyphValueRecord glyphValueRecord)
|
||||
{
|
||||
m_GlyphIndex = glyphIndex;
|
||||
m_GlyphValueRecord = glyphValueRecord;
|
||||
}
|
||||
|
||||
internal TMP_GlyphAdjustmentRecord(GlyphAdjustmentRecord adjustmentRecord)
|
||||
{
|
||||
m_GlyphIndex = adjustmentRecord.glyphIndex;
|
||||
m_GlyphValueRecord = new TMP_GlyphValueRecord(adjustmentRecord.glyphValueRecord);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The positional adjustment values for a pair of glyphs.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class TMP_GlyphPairAdjustmentRecord
|
||||
{
|
||||
/// <summary>
|
||||
/// Contains the positional adjustment values for the first glyph.
|
||||
/// </summary>
|
||||
public TMP_GlyphAdjustmentRecord firstAdjustmentRecord { get { return m_FirstAdjustmentRecord; } set { m_FirstAdjustmentRecord = value; } }
|
||||
|
||||
/// <summary>
|
||||
/// Contains the positional adjustment values for the second glyph.
|
||||
/// </summary>
|
||||
public TMP_GlyphAdjustmentRecord secondAdjustmentRecord { get { return m_SecondAdjustmentRecord; } set { m_SecondAdjustmentRecord = value; } }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public FontFeatureLookupFlags featureLookupFlags { get { return m_FeatureLookupFlags; } set { m_FeatureLookupFlags = value; } }
|
||||
|
||||
// =============================================
|
||||
// Private backing fields for public properties.
|
||||
// =============================================
|
||||
|
||||
[SerializeField]
|
||||
internal TMP_GlyphAdjustmentRecord m_FirstAdjustmentRecord;
|
||||
|
||||
[SerializeField]
|
||||
internal TMP_GlyphAdjustmentRecord m_SecondAdjustmentRecord;
|
||||
|
||||
[SerializeField]
|
||||
internal FontFeatureLookupFlags m_FeatureLookupFlags;
|
||||
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
/// <param name="firstAdjustmentRecord">First glyph adjustment record.</param>
|
||||
/// <param name="secondAdjustmentRecord">Second glyph adjustment record.</param>
|
||||
public TMP_GlyphPairAdjustmentRecord(TMP_GlyphAdjustmentRecord firstAdjustmentRecord, TMP_GlyphAdjustmentRecord secondAdjustmentRecord)
|
||||
{
|
||||
m_FirstAdjustmentRecord = firstAdjustmentRecord;
|
||||
m_SecondAdjustmentRecord = secondAdjustmentRecord;
|
||||
m_FeatureLookupFlags = FontFeatureLookupFlags.None;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Internal constructor
|
||||
/// </summary>
|
||||
/// <param name="firstAdjustmentRecord"></param>
|
||||
/// <param name="secondAdjustmentRecord"></param>
|
||||
internal TMP_GlyphPairAdjustmentRecord(GlyphPairAdjustmentRecord glyphPairAdjustmentRecord)
|
||||
{
|
||||
m_FirstAdjustmentRecord = new TMP_GlyphAdjustmentRecord(glyphPairAdjustmentRecord.firstAdjustmentRecord);
|
||||
m_SecondAdjustmentRecord = new TMP_GlyphAdjustmentRecord(glyphPairAdjustmentRecord.secondAdjustmentRecord);
|
||||
m_FeatureLookupFlags = FontFeatureLookupFlags.None;
|
||||
}
|
||||
}
|
||||
|
||||
public struct GlyphPairKey
|
||||
{
|
||||
public uint firstGlyphIndex;
|
||||
public uint secondGlyphIndex;
|
||||
public uint key;
|
||||
|
||||
public GlyphPairKey(uint firstGlyphIndex, uint secondGlyphIndex)
|
||||
{
|
||||
this.firstGlyphIndex = firstGlyphIndex;
|
||||
this.secondGlyphIndex = secondGlyphIndex;
|
||||
key = secondGlyphIndex << 16 | firstGlyphIndex;
|
||||
}
|
||||
|
||||
internal GlyphPairKey(TMP_GlyphPairAdjustmentRecord record)
|
||||
{
|
||||
firstGlyphIndex = record.firstAdjustmentRecord.glyphIndex;
|
||||
secondGlyphIndex = record.secondAdjustmentRecord.glyphIndex;
|
||||
key = secondGlyphIndex << 16 | firstGlyphIndex;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 27df3b12f30d0b74a9b10a3968c402ff
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 2da0c512f12947e489f739169773d7ca
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {fileID: 2800000, guid: 3ee40aa79cd242a5b53b0b0ca4f13f0f, type: 3}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,15 @@
|
|||
using UnityEngine;
|
||||
using System.Collections;
|
||||
|
||||
|
||||
namespace TMPro
|
||||
{
|
||||
/// <summary>
|
||||
/// Custom text input validator where user can implement their own custom character validation.
|
||||
/// </summary>
|
||||
[System.Serializable]
|
||||
public abstract class TMP_InputValidator : ScriptableObject
|
||||
{
|
||||
public abstract char Validate(ref string text, ref int pos, char ch);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 79ff392d1bde4ad78a3836a4a480392d
|
||||
timeCreated: 1473021069
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,51 @@
|
|||
namespace TMPro
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Structure which contains information about the individual lines of text.
|
||||
/// </summary>
|
||||
public struct TMP_LineInfo
|
||||
{
|
||||
internal int controlCharacterCount;
|
||||
|
||||
public int characterCount;
|
||||
public int visibleCharacterCount;
|
||||
public int spaceCount;
|
||||
public int wordCount;
|
||||
public int firstCharacterIndex;
|
||||
public int firstVisibleCharacterIndex;
|
||||
public int lastCharacterIndex;
|
||||
public int lastVisibleCharacterIndex;
|
||||
|
||||
public float length;
|
||||
public float lineHeight;
|
||||
public float ascender;
|
||||
public float baseline;
|
||||
public float descender;
|
||||
public float maxAdvance;
|
||||
|
||||
public float width;
|
||||
public float marginLeft;
|
||||
public float marginRight;
|
||||
|
||||
public HorizontalAlignmentOptions alignment;
|
||||
public Extents lineExtents;
|
||||
|
||||
/// <summary>
|
||||
/// Function returning the current line of text.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
//public string GetLineText()
|
||||
//{
|
||||
// string word = string.Empty;
|
||||
// TMP_CharacterInfo[] charInfo = textComponent.textInfo.characterInfo;
|
||||
|
||||
// for (int i = firstCharacterIndex; i < lastCharacterIndex + 1; i++)
|
||||
// {
|
||||
// word += charInfo[i].character;
|
||||
// }
|
||||
|
||||
// return word;
|
||||
//}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
fileFormatVersion: 2
|
||||
guid: b6e75d7f429a4e7e9e1ffb4f85cff49f
|
||||
timeCreated: 1464310403
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,21 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
|
||||
namespace TMPro
|
||||
{
|
||||
internal static class TMP_ListPool<T>
|
||||
{
|
||||
// Object pool to avoid allocations.
|
||||
private static readonly TMP_ObjectPool<List<T>> s_ListPool = new TMP_ObjectPool<List<T>>(null, l => l.Clear());
|
||||
|
||||
public static List<T> Get()
|
||||
{
|
||||
return s_ListPool.Get();
|
||||
}
|
||||
|
||||
public static void Release(List<T> toRelease)
|
||||
{
|
||||
s_ListPool.Release(toRelease);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 28375447bcea455c9b51a6650b10c9d7
|
||||
timeCreated: 1458521386
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,682 @@
|
|||
//#define TMP_DEBUG_MODE
|
||||
|
||||
using UnityEngine;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using UnityEngine.UI;
|
||||
|
||||
|
||||
namespace TMPro
|
||||
{
|
||||
|
||||
public static class TMP_MaterialManager
|
||||
{
|
||||
private static List<MaskingMaterial> m_materialList = new List<MaskingMaterial>();
|
||||
|
||||
private static Dictionary<long, FallbackMaterial> m_fallbackMaterials = new Dictionary<long, FallbackMaterial>();
|
||||
private static Dictionary<int, long> m_fallbackMaterialLookup = new Dictionary<int, long>();
|
||||
private static List<FallbackMaterial> m_fallbackCleanupList = new List<FallbackMaterial>();
|
||||
|
||||
private static bool isFallbackListDirty;
|
||||
|
||||
static TMP_MaterialManager()
|
||||
{
|
||||
Canvas.willRenderCanvases += OnPreRender;
|
||||
}
|
||||
|
||||
static void OnPreRender()
|
||||
{
|
||||
if (isFallbackListDirty)
|
||||
{
|
||||
//Debug.Log("2 - Cleaning up Fallback Materials.");
|
||||
CleanupFallbackMaterials();
|
||||
isFallbackListDirty = false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a Masking Material Instance for the given ID
|
||||
/// </summary>
|
||||
/// <param name="baseMaterial"></param>
|
||||
/// <param name="stencilID"></param>
|
||||
/// <returns></returns>
|
||||
public static Material GetStencilMaterial(Material baseMaterial, int stencilID)
|
||||
{
|
||||
// Check if Material supports masking
|
||||
if (!baseMaterial.HasProperty(ShaderUtilities.ID_StencilID))
|
||||
{
|
||||
Debug.LogWarning("Selected Shader does not support Stencil Masking. Please select the Distance Field or Mobile Distance Field Shader.");
|
||||
return baseMaterial;
|
||||
}
|
||||
|
||||
int baseMaterialID = baseMaterial.GetInstanceID();
|
||||
|
||||
// If baseMaterial already has a corresponding masking material, return it.
|
||||
for (int i = 0; i < m_materialList.Count; i++)
|
||||
{
|
||||
if (m_materialList[i].baseMaterial.GetInstanceID() == baseMaterialID && m_materialList[i].stencilID == stencilID)
|
||||
{
|
||||
m_materialList[i].count += 1;
|
||||
|
||||
#if TMP_DEBUG_MODE
|
||||
ListMaterials();
|
||||
#endif
|
||||
|
||||
return m_materialList[i].stencilMaterial;
|
||||
}
|
||||
}
|
||||
|
||||
// No matching masking material found. Create and return a new one.
|
||||
|
||||
Material stencilMaterial;
|
||||
|
||||
//Create new Masking Material Instance for this Base Material
|
||||
stencilMaterial = new Material(baseMaterial);
|
||||
stencilMaterial.hideFlags = HideFlags.HideAndDontSave;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
stencilMaterial.name += " Masking ID:" + stencilID;
|
||||
#endif
|
||||
|
||||
stencilMaterial.shaderKeywords = baseMaterial.shaderKeywords;
|
||||
|
||||
// Set Stencil Properties
|
||||
ShaderUtilities.GetShaderPropertyIDs();
|
||||
stencilMaterial.SetFloat(ShaderUtilities.ID_StencilID, stencilID);
|
||||
//stencilMaterial.SetFloat(ShaderUtilities.ID_StencilOp, 0);
|
||||
stencilMaterial.SetFloat(ShaderUtilities.ID_StencilComp, 4);
|
||||
//stencilMaterial.SetFloat(ShaderUtilities.ID_StencilReadMask, stencilID);
|
||||
//stencilMaterial.SetFloat(ShaderUtilities.ID_StencilWriteMask, 0);
|
||||
|
||||
MaskingMaterial temp = new MaskingMaterial();
|
||||
temp.baseMaterial = baseMaterial;
|
||||
temp.stencilMaterial = stencilMaterial;
|
||||
temp.stencilID = stencilID;
|
||||
temp.count = 1;
|
||||
|
||||
m_materialList.Add(temp);
|
||||
|
||||
#if TMP_DEBUG_MODE
|
||||
ListMaterials();
|
||||
#endif
|
||||
|
||||
return stencilMaterial;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function to release the stencil material.
|
||||
/// </summary>
|
||||
/// <param name="stencilMaterial"></param>
|
||||
public static void ReleaseStencilMaterial(Material stencilMaterial)
|
||||
{
|
||||
int stencilMaterialID = stencilMaterial.GetInstanceID();
|
||||
|
||||
for (int i = 0; i < m_materialList.Count; i++)
|
||||
{
|
||||
if (m_materialList[i].stencilMaterial.GetInstanceID() == stencilMaterialID)
|
||||
{
|
||||
if (m_materialList[i].count > 1)
|
||||
m_materialList[i].count -= 1;
|
||||
else
|
||||
{
|
||||
Object.DestroyImmediate(m_materialList[i].stencilMaterial);
|
||||
m_materialList.RemoveAt(i);
|
||||
stencilMaterial = null;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if TMP_DEBUG_MODE
|
||||
ListMaterials();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
// Function which returns the base material associated with a Masking Material
|
||||
public static Material GetBaseMaterial(Material stencilMaterial)
|
||||
{
|
||||
// Check if maskingMaterial already has a base material associated with it.
|
||||
int index = m_materialList.FindIndex(item => item.stencilMaterial == stencilMaterial);
|
||||
|
||||
if (index == -1)
|
||||
return null;
|
||||
else
|
||||
return m_materialList[index].baseMaterial;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function to set the Material Stencil ID
|
||||
/// </summary>
|
||||
/// <param name="material"></param>
|
||||
/// <param name="stencilID"></param>
|
||||
/// <returns></returns>
|
||||
public static Material SetStencil(Material material, int stencilID)
|
||||
{
|
||||
material.SetFloat(ShaderUtilities.ID_StencilID, stencilID);
|
||||
|
||||
if (stencilID == 0)
|
||||
material.SetFloat(ShaderUtilities.ID_StencilComp, 8);
|
||||
else
|
||||
material.SetFloat(ShaderUtilities.ID_StencilComp, 4);
|
||||
|
||||
return material;
|
||||
}
|
||||
|
||||
|
||||
public static void AddMaskingMaterial(Material baseMaterial, Material stencilMaterial, int stencilID)
|
||||
{
|
||||
// Check if maskingMaterial already has a base material associated with it.
|
||||
int index = m_materialList.FindIndex(item => item.stencilMaterial == stencilMaterial);
|
||||
|
||||
if (index == -1)
|
||||
{
|
||||
MaskingMaterial temp = new MaskingMaterial();
|
||||
temp.baseMaterial = baseMaterial;
|
||||
temp.stencilMaterial = stencilMaterial;
|
||||
temp.stencilID = stencilID;
|
||||
temp.count = 1;
|
||||
|
||||
m_materialList.Add(temp);
|
||||
}
|
||||
else
|
||||
{
|
||||
stencilMaterial = m_materialList[index].stencilMaterial;
|
||||
m_materialList[index].count += 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static void RemoveStencilMaterial(Material stencilMaterial)
|
||||
{
|
||||
// Check if maskingMaterial is already on the list.
|
||||
int index = m_materialList.FindIndex(item => item.stencilMaterial == stencilMaterial);
|
||||
|
||||
if (index != -1)
|
||||
{
|
||||
m_materialList.RemoveAt(index);
|
||||
}
|
||||
|
||||
#if TMP_DEBUG_MODE
|
||||
ListMaterials();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static void ReleaseBaseMaterial(Material baseMaterial)
|
||||
{
|
||||
// Check if baseMaterial already has a masking material associated with it.
|
||||
int index = m_materialList.FindIndex(item => item.baseMaterial == baseMaterial);
|
||||
|
||||
if (index == -1)
|
||||
{
|
||||
Debug.Log("No Masking Material exists for " + baseMaterial.name);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_materialList[index].count > 1)
|
||||
{
|
||||
m_materialList[index].count -= 1;
|
||||
Debug.Log("Removed (1) reference to " + m_materialList[index].stencilMaterial.name + ". There are " + m_materialList[index].count + " references left.");
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Log("Removed last reference to " + m_materialList[index].stencilMaterial.name + " with ID " + m_materialList[index].stencilMaterial.GetInstanceID());
|
||||
Object.DestroyImmediate(m_materialList[index].stencilMaterial);
|
||||
m_materialList.RemoveAt(index);
|
||||
}
|
||||
}
|
||||
|
||||
#if TMP_DEBUG_MODE
|
||||
ListMaterials();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
public static void ClearMaterials()
|
||||
{
|
||||
if (m_materialList.Count == 0)
|
||||
{
|
||||
Debug.Log("Material List has already been cleared.");
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < m_materialList.Count; i++)
|
||||
{
|
||||
//Material baseMaterial = m_materialList[i].baseMaterial;
|
||||
Material stencilMaterial = m_materialList[i].stencilMaterial;
|
||||
|
||||
Object.DestroyImmediate(stencilMaterial);
|
||||
}
|
||||
m_materialList.Clear();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function to get the Stencil ID
|
||||
/// </summary>
|
||||
/// <param name="obj"></param>
|
||||
/// <returns></returns>
|
||||
public static int GetStencilID(GameObject obj)
|
||||
{
|
||||
// Implementation is almost copied from Unity UI
|
||||
|
||||
var count = 0;
|
||||
|
||||
var transform = obj.transform;
|
||||
var stopAfter = FindRootSortOverrideCanvas(transform);
|
||||
if (transform == stopAfter)
|
||||
return count;
|
||||
|
||||
var t = transform.parent;
|
||||
var components = TMP_ListPool<Mask>.Get();
|
||||
while (t != null)
|
||||
{
|
||||
t.GetComponents<Mask>(components);
|
||||
for (var i = 0; i < components.Count; ++i)
|
||||
{
|
||||
var mask = components[i];
|
||||
if (mask != null && mask.MaskEnabled() && mask.graphic.IsActive())
|
||||
{
|
||||
++count;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (t == stopAfter)
|
||||
break;
|
||||
|
||||
t = t.parent;
|
||||
}
|
||||
TMP_ListPool<Mask>.Release(components);
|
||||
|
||||
return Mathf.Min((1 << count) - 1, 255);
|
||||
}
|
||||
|
||||
|
||||
public static Material GetMaterialForRendering(MaskableGraphic graphic, Material baseMaterial)
|
||||
{
|
||||
if (baseMaterial == null)
|
||||
return null;
|
||||
|
||||
var modifiers = TMP_ListPool<IMaterialModifier>.Get();
|
||||
graphic.GetComponents(modifiers);
|
||||
|
||||
var result = baseMaterial;
|
||||
for (int i = 0; i < modifiers.Count; i++)
|
||||
result = modifiers[i].GetModifiedMaterial(result);
|
||||
|
||||
TMP_ListPool<IMaterialModifier>.Release(modifiers);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static Transform FindRootSortOverrideCanvas(Transform start)
|
||||
{
|
||||
// Implementation is copied from Unity UI
|
||||
|
||||
var canvasList = TMP_ListPool<Canvas>.Get();
|
||||
start.GetComponentsInParent(false, canvasList);
|
||||
Canvas canvas = null;
|
||||
|
||||
for (int i = 0; i < canvasList.Count; ++i)
|
||||
{
|
||||
canvas = canvasList[i];
|
||||
|
||||
// We found the canvas we want to use break
|
||||
if (canvas.overrideSorting)
|
||||
break;
|
||||
}
|
||||
TMP_ListPool<Canvas>.Release(canvasList);
|
||||
|
||||
return canvas != null ? canvas.transform : null;
|
||||
}
|
||||
|
||||
|
||||
internal static Material GetFallbackMaterial(TMP_FontAsset fontAsset, Material sourceMaterial, int atlasIndex)
|
||||
{
|
||||
int sourceMaterialID = sourceMaterial.GetInstanceID();
|
||||
Texture tex = fontAsset.atlasTextures[atlasIndex];
|
||||
int texID = tex.GetInstanceID();
|
||||
long key = (long)sourceMaterialID << 32 | (long)(uint)texID;
|
||||
FallbackMaterial fallback;
|
||||
|
||||
if (m_fallbackMaterials.TryGetValue(key, out fallback))
|
||||
{
|
||||
// Check if source material properties have changed.
|
||||
int sourceMaterialCRC = sourceMaterial.ComputeCRC();
|
||||
if (sourceMaterialCRC == fallback.sourceMaterialCRC)
|
||||
return fallback.fallbackMaterial;
|
||||
|
||||
CopyMaterialPresetProperties(sourceMaterial, fallback.fallbackMaterial);
|
||||
fallback.sourceMaterialCRC = sourceMaterialCRC;
|
||||
return fallback.fallbackMaterial;
|
||||
}
|
||||
|
||||
// Create new material from the source material and assign relevant atlas texture
|
||||
Material fallbackMaterial = new Material(sourceMaterial);
|
||||
fallbackMaterial.SetTexture(ShaderUtilities.ID_MainTex, tex);
|
||||
|
||||
fallbackMaterial.hideFlags = HideFlags.HideAndDontSave;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
fallbackMaterial.name += " + " + tex.name;
|
||||
#endif
|
||||
|
||||
fallback = new FallbackMaterial();
|
||||
fallback.fallbackID = key;
|
||||
fallback.sourceMaterial = fontAsset.material;
|
||||
fallback.sourceMaterialCRC = sourceMaterial.ComputeCRC();
|
||||
fallback.fallbackMaterial = fallbackMaterial;
|
||||
fallback.count = 0;
|
||||
|
||||
m_fallbackMaterials.Add(key, fallback);
|
||||
m_fallbackMaterialLookup.Add(fallbackMaterial.GetInstanceID(), key);
|
||||
|
||||
#if TMP_DEBUG_MODE
|
||||
ListFallbackMaterials();
|
||||
#endif
|
||||
|
||||
return fallbackMaterial;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// This function returns a material instance using the material properties of a previous material but using the font atlas texture of the new font asset.
|
||||
/// </summary>
|
||||
/// <param name="sourceMaterial">The material containing the source material properties to be copied to the new material.</param>
|
||||
/// <param name="targetMaterial">The font atlas texture that should be assigned to the new material.</param>
|
||||
/// <returns></returns>
|
||||
public static Material GetFallbackMaterial (Material sourceMaterial, Material targetMaterial)
|
||||
{
|
||||
int sourceID = sourceMaterial.GetInstanceID();
|
||||
Texture tex = targetMaterial.GetTexture(ShaderUtilities.ID_MainTex);
|
||||
int texID = tex.GetInstanceID();
|
||||
long key = (long)sourceID << 32 | (long)(uint)texID;
|
||||
FallbackMaterial fallback;
|
||||
|
||||
if (m_fallbackMaterials.TryGetValue(key, out fallback))
|
||||
{
|
||||
// Check if source material properties have changed.
|
||||
int sourceMaterialCRC = sourceMaterial.ComputeCRC();
|
||||
if (sourceMaterialCRC == fallback.sourceMaterialCRC)
|
||||
return fallback.fallbackMaterial;
|
||||
|
||||
CopyMaterialPresetProperties(sourceMaterial, fallback.fallbackMaterial);
|
||||
fallback.sourceMaterialCRC = sourceMaterialCRC;
|
||||
return fallback.fallbackMaterial;
|
||||
}
|
||||
|
||||
// Create new material from the source material and copy properties if using distance field shaders.
|
||||
Material fallbackMaterial;
|
||||
if (sourceMaterial.HasProperty(ShaderUtilities.ID_GradientScale) && targetMaterial.HasProperty(ShaderUtilities.ID_GradientScale))
|
||||
{
|
||||
fallbackMaterial = new Material(sourceMaterial);
|
||||
fallbackMaterial.hideFlags = HideFlags.HideAndDontSave;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
fallbackMaterial.name += " + " + tex.name;
|
||||
//Debug.Log("Creating new fallback material for " + fallbackMaterial.name);
|
||||
#endif
|
||||
|
||||
fallbackMaterial.SetTexture(ShaderUtilities.ID_MainTex, tex);
|
||||
// Retain material properties unique to target material.
|
||||
fallbackMaterial.SetFloat(ShaderUtilities.ID_GradientScale, targetMaterial.GetFloat(ShaderUtilities.ID_GradientScale));
|
||||
fallbackMaterial.SetFloat(ShaderUtilities.ID_TextureWidth, targetMaterial.GetFloat(ShaderUtilities.ID_TextureWidth));
|
||||
fallbackMaterial.SetFloat(ShaderUtilities.ID_TextureHeight, targetMaterial.GetFloat(ShaderUtilities.ID_TextureHeight));
|
||||
fallbackMaterial.SetFloat(ShaderUtilities.ID_WeightNormal, targetMaterial.GetFloat(ShaderUtilities.ID_WeightNormal));
|
||||
fallbackMaterial.SetFloat(ShaderUtilities.ID_WeightBold, targetMaterial.GetFloat(ShaderUtilities.ID_WeightBold));
|
||||
}
|
||||
else
|
||||
{
|
||||
fallbackMaterial = new Material(targetMaterial);
|
||||
}
|
||||
|
||||
fallback = new FallbackMaterial();
|
||||
fallback.fallbackID = key;
|
||||
fallback.sourceMaterial = sourceMaterial;
|
||||
fallback.sourceMaterialCRC = sourceMaterial.ComputeCRC();
|
||||
fallback.fallbackMaterial = fallbackMaterial;
|
||||
fallback.count = 0;
|
||||
|
||||
m_fallbackMaterials.Add(key, fallback);
|
||||
m_fallbackMaterialLookup.Add(fallbackMaterial.GetInstanceID(), key);
|
||||
|
||||
#if TMP_DEBUG_MODE
|
||||
ListFallbackMaterials();
|
||||
#endif
|
||||
|
||||
return fallbackMaterial;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="targetMaterial"></param>
|
||||
public static void AddFallbackMaterialReference(Material targetMaterial)
|
||||
{
|
||||
if (targetMaterial == null) return;
|
||||
|
||||
int sourceID = targetMaterial.GetInstanceID();
|
||||
long key;
|
||||
|
||||
// Lookup key to retrieve
|
||||
if (m_fallbackMaterialLookup.TryGetValue(sourceID, out key))
|
||||
{
|
||||
FallbackMaterial fallback;
|
||||
if (m_fallbackMaterials.TryGetValue(key, out fallback))
|
||||
{
|
||||
//Debug.Log("Adding Fallback material " + fallback.fallbackMaterial.name + " with reference count of " + (fallback.count + 1));
|
||||
fallback.count += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="targetMaterial"></param>
|
||||
public static void RemoveFallbackMaterialReference(Material targetMaterial)
|
||||
{
|
||||
if (targetMaterial == null) return;
|
||||
|
||||
int sourceID = targetMaterial.GetInstanceID();
|
||||
long key;
|
||||
|
||||
// Lookup key to retrieve
|
||||
if (m_fallbackMaterialLookup.TryGetValue(sourceID, out key))
|
||||
{
|
||||
FallbackMaterial fallback;
|
||||
if (m_fallbackMaterials.TryGetValue(key, out fallback))
|
||||
{
|
||||
fallback.count -= 1;
|
||||
|
||||
if (fallback.count < 1)
|
||||
m_fallbackCleanupList.Add(fallback);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static void CleanupFallbackMaterials()
|
||||
{
|
||||
// Return if the list is empty.
|
||||
if (m_fallbackCleanupList.Count == 0) return;
|
||||
|
||||
for (int i = 0; i < m_fallbackCleanupList.Count; i++)
|
||||
{
|
||||
FallbackMaterial fallback = m_fallbackCleanupList[i];
|
||||
|
||||
if (fallback.count < 1)
|
||||
{
|
||||
//Debug.Log("Cleaning up " + fallback.fallbackMaterial.name);
|
||||
|
||||
Material mat = fallback.fallbackMaterial;
|
||||
m_fallbackMaterials.Remove(fallback.fallbackID);
|
||||
m_fallbackMaterialLookup.Remove(mat.GetInstanceID());
|
||||
Object.DestroyImmediate(mat);
|
||||
mat = null;
|
||||
}
|
||||
}
|
||||
|
||||
m_fallbackCleanupList.Clear();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function to release the fallback material.
|
||||
/// </summary>
|
||||
/// <param name="fallbackMaterial">Material to be released.</param>
|
||||
public static void ReleaseFallbackMaterial(Material fallbackMaterial)
|
||||
{
|
||||
if (fallbackMaterial == null) return;
|
||||
|
||||
int materialID = fallbackMaterial.GetInstanceID();
|
||||
long key;
|
||||
|
||||
if (m_fallbackMaterialLookup.TryGetValue(materialID, out key))
|
||||
{
|
||||
FallbackMaterial fallback;
|
||||
if (m_fallbackMaterials.TryGetValue(key, out fallback))
|
||||
{
|
||||
//Debug.Log("Releasing Fallback material " + fallback.fallbackMaterial.name + " with remaining reference count of " + (fallback.count - 1));
|
||||
|
||||
fallback.count -= 1;
|
||||
|
||||
if (fallback.count < 1)
|
||||
m_fallbackCleanupList.Add(fallback);
|
||||
}
|
||||
}
|
||||
|
||||
isFallbackListDirty = true;
|
||||
|
||||
#if TMP_DEBUG_MODE
|
||||
ListFallbackMaterials();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
private class FallbackMaterial
|
||||
{
|
||||
public long fallbackID;
|
||||
public Material sourceMaterial;
|
||||
internal int sourceMaterialCRC;
|
||||
public Material fallbackMaterial;
|
||||
public int count;
|
||||
}
|
||||
|
||||
|
||||
private class MaskingMaterial
|
||||
{
|
||||
public Material baseMaterial;
|
||||
public Material stencilMaterial;
|
||||
public int count;
|
||||
public int stencilID;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function to copy the properties of a source material preset to another while preserving the unique font asset properties of the destination material.
|
||||
/// </summary>
|
||||
/// <param name="source"></param>
|
||||
/// <param name="destination"></param>
|
||||
public static void CopyMaterialPresetProperties(Material source, Material destination)
|
||||
{
|
||||
if (!source.HasProperty(ShaderUtilities.ID_GradientScale) || !destination.HasProperty(ShaderUtilities.ID_GradientScale))
|
||||
return;
|
||||
|
||||
// Save unique material properties
|
||||
Texture dst_texture = destination.GetTexture(ShaderUtilities.ID_MainTex);
|
||||
float dst_gradientScale = destination.GetFloat(ShaderUtilities.ID_GradientScale);
|
||||
float dst_texWidth = destination.GetFloat(ShaderUtilities.ID_TextureWidth);
|
||||
float dst_texHeight = destination.GetFloat(ShaderUtilities.ID_TextureHeight);
|
||||
float dst_weightNormal = destination.GetFloat(ShaderUtilities.ID_WeightNormal);
|
||||
float dst_weightBold = destination.GetFloat(ShaderUtilities.ID_WeightBold);
|
||||
|
||||
// Copy all material properties
|
||||
destination.CopyPropertiesFromMaterial(source);
|
||||
|
||||
// Copy shader keywords
|
||||
destination.shaderKeywords = source.shaderKeywords;
|
||||
|
||||
// Restore unique material properties
|
||||
destination.SetTexture(ShaderUtilities.ID_MainTex, dst_texture);
|
||||
destination.SetFloat(ShaderUtilities.ID_GradientScale, dst_gradientScale);
|
||||
destination.SetFloat(ShaderUtilities.ID_TextureWidth, dst_texWidth);
|
||||
destination.SetFloat(ShaderUtilities.ID_TextureHeight, dst_texHeight);
|
||||
destination.SetFloat(ShaderUtilities.ID_WeightNormal, dst_weightNormal);
|
||||
destination.SetFloat(ShaderUtilities.ID_WeightBold, dst_weightBold);
|
||||
}
|
||||
|
||||
|
||||
#if TMP_DEBUG_MODE
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static void ListMaterials()
|
||||
{
|
||||
|
||||
if (m_materialList.Count == 0)
|
||||
{
|
||||
Debug.Log("Material List is empty.");
|
||||
return;
|
||||
}
|
||||
|
||||
//Debug.Log("List contains " + m_materialList.Count() + " items.");
|
||||
|
||||
for (int i = 0; i < m_materialList.Count; i++)
|
||||
{
|
||||
Material baseMaterial = m_materialList[i].baseMaterial;
|
||||
Material stencilMaterial = m_materialList[i].stencilMaterial;
|
||||
|
||||
Debug.Log("Item #" + (i + 1) + " - Base Material is [" + baseMaterial.name + "] with ID " + baseMaterial.GetInstanceID() + " is associated with [" + (stencilMaterial != null ? stencilMaterial.name : "Null") + "] Stencil ID " + m_materialList[i].stencilID + " with ID " + (stencilMaterial != null ? stencilMaterial.GetInstanceID() : 0) + " and is referenced " + m_materialList[i].count + " time(s).");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static void ListFallbackMaterials()
|
||||
{
|
||||
|
||||
if (m_fallbackMaterials.Count == 0)
|
||||
{
|
||||
Debug.Log("Material List is empty.");
|
||||
return;
|
||||
}
|
||||
|
||||
Debug.Log("List contains " + m_fallbackMaterials.Count + " items.");
|
||||
|
||||
int count = 0;
|
||||
foreach (var fallback in m_fallbackMaterials)
|
||||
{
|
||||
Material baseMaterial = fallback.Value.baseMaterial;
|
||||
Material fallbackMaterial = fallback.Value.fallbackMaterial;
|
||||
|
||||
string output = "Item #" + (count++);
|
||||
if (baseMaterial != null)
|
||||
output += " - Base Material is [" + baseMaterial.name + "] with ID " + baseMaterial.GetInstanceID();
|
||||
if (fallbackMaterial != null)
|
||||
output += " is associated with [" + fallbackMaterial.name + "] with ID " + fallbackMaterial.GetInstanceID() + " and is referenced " + fallback.Value.count + " time(s).";
|
||||
|
||||
Debug.Log(output);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 6d9df2bc198c417db00037803568139c
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,675 @@
|
|||
using UnityEngine;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine.Rendering;
|
||||
|
||||
|
||||
namespace TMPro
|
||||
{
|
||||
public enum VertexSortingOrder { Normal, Reverse };
|
||||
|
||||
/// <summary>
|
||||
/// Structure which contains the vertex attributes (geometry) of the text object.
|
||||
/// </summary>
|
||||
public struct TMP_MeshInfo
|
||||
{
|
||||
private static readonly Color32 s_DefaultColor = new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue);
|
||||
private static readonly Vector3 s_DefaultNormal = new Vector3(0.0f, 0.0f, -1f);
|
||||
private static readonly Vector4 s_DefaultTangent = new Vector4(-1f, 0.0f, 0.0f, 1f);
|
||||
private static readonly Bounds s_DefaultBounds = new Bounds();
|
||||
|
||||
public Mesh mesh;
|
||||
public int vertexCount;
|
||||
|
||||
public Vector3[] vertices;
|
||||
public Vector3[] normals;
|
||||
public Vector4[] tangents;
|
||||
|
||||
public Vector2[] uvs0;
|
||||
public Vector2[] uvs2;
|
||||
//public Vector2[] uvs4;
|
||||
public Color32[] colors32;
|
||||
public int[] triangles;
|
||||
|
||||
public Material material;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function to pre-allocate vertex attributes for a mesh of size X.
|
||||
/// </summary>
|
||||
/// <param name="mesh"></param>
|
||||
/// <param name="size"></param>
|
||||
public TMP_MeshInfo(Mesh mesh, int size)
|
||||
{
|
||||
// Reference to the TMP Text Component.
|
||||
//this.textComponent = null;
|
||||
|
||||
// Clear existing mesh data
|
||||
if (mesh == null)
|
||||
mesh = new Mesh();
|
||||
else
|
||||
mesh.Clear();
|
||||
|
||||
this.mesh = mesh;
|
||||
|
||||
// Limit the mesh to less than 65535 vertices which is the limit for Unity's Mesh.
|
||||
size = Mathf.Min(size, 16383);
|
||||
|
||||
int sizeX4 = size * 4;
|
||||
int sizeX6 = size * 6;
|
||||
|
||||
this.vertexCount = 0;
|
||||
|
||||
this.vertices = new Vector3[sizeX4];
|
||||
this.uvs0 = new Vector2[sizeX4];
|
||||
this.uvs2 = new Vector2[sizeX4];
|
||||
//this.uvs4 = new Vector2[sizeX4]; // SDF scale data
|
||||
this.colors32 = new Color32[sizeX4];
|
||||
|
||||
this.normals = new Vector3[sizeX4];
|
||||
this.tangents = new Vector4[sizeX4];
|
||||
|
||||
this.triangles = new int[sizeX6];
|
||||
|
||||
int index_X6 = 0;
|
||||
int index_X4 = 0;
|
||||
while (index_X4 / 4 < size)
|
||||
{
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
this.vertices[index_X4 + i] = Vector3.zero;
|
||||
this.uvs0[index_X4 + i] = Vector2.zero;
|
||||
this.uvs2[index_X4 + i] = Vector2.zero;
|
||||
//this.uvs4[index_X4 + i] = Vector2.zero;
|
||||
this.colors32[index_X4 + i] = s_DefaultColor;
|
||||
this.normals[index_X4 + i] = s_DefaultNormal;
|
||||
this.tangents[index_X4 + i] = s_DefaultTangent;
|
||||
}
|
||||
|
||||
this.triangles[index_X6 + 0] = index_X4 + 0;
|
||||
this.triangles[index_X6 + 1] = index_X4 + 1;
|
||||
this.triangles[index_X6 + 2] = index_X4 + 2;
|
||||
this.triangles[index_X6 + 3] = index_X4 + 2;
|
||||
this.triangles[index_X6 + 4] = index_X4 + 3;
|
||||
this.triangles[index_X6 + 5] = index_X4 + 0;
|
||||
|
||||
index_X4 += 4;
|
||||
index_X6 += 6;
|
||||
}
|
||||
|
||||
// Pre-assign base vertex attributes.
|
||||
this.mesh.vertices = this.vertices;
|
||||
this.mesh.normals = this.normals;
|
||||
this.mesh.tangents = this.tangents;
|
||||
this.mesh.triangles = this.triangles;
|
||||
this.mesh.bounds = s_DefaultBounds;
|
||||
this.material = null;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function to pre-allocate vertex attributes for a mesh of size X.
|
||||
/// </summary>
|
||||
/// <param name="mesh"></param>
|
||||
/// <param name="size"></param>
|
||||
/// <param name="isVolumetric"></param>
|
||||
public TMP_MeshInfo(Mesh mesh, int size, bool isVolumetric)
|
||||
{
|
||||
// Reference to the TMP Text Component.
|
||||
//this.textComponent = null;
|
||||
|
||||
// Clear existing mesh data
|
||||
if (mesh == null)
|
||||
mesh = new Mesh();
|
||||
else
|
||||
mesh.Clear();
|
||||
|
||||
this.mesh = mesh;
|
||||
|
||||
int s0 = !isVolumetric ? 4 : 8;
|
||||
int s1 = !isVolumetric ? 6 : 36;
|
||||
|
||||
// Limit the mesh to less than 65535 vertices which is the limit for Unity's Mesh.
|
||||
size = Mathf.Min(size, 65532 / s0);
|
||||
|
||||
int size_x_s0 = size * s0;
|
||||
int size_x_s1 = size * s1;
|
||||
|
||||
this.vertexCount = 0;
|
||||
|
||||
this.vertices = new Vector3[size_x_s0];
|
||||
this.uvs0 = new Vector2[size_x_s0];
|
||||
this.uvs2 = new Vector2[size_x_s0];
|
||||
//this.uvs4 = new Vector2[sizeX8]; // SDF scale data
|
||||
this.colors32 = new Color32[size_x_s0];
|
||||
|
||||
this.normals = new Vector3[size_x_s0];
|
||||
this.tangents = new Vector4[size_x_s0];
|
||||
|
||||
this.triangles = new int[size_x_s1];
|
||||
|
||||
int index_x_s0 = 0;
|
||||
int index_x_s1 = 0;
|
||||
while (index_x_s0 / s0 < size)
|
||||
{
|
||||
for (int i = 0; i < s0; i++)
|
||||
{
|
||||
this.vertices[index_x_s0 + i] = Vector3.zero;
|
||||
this.uvs0[index_x_s0 + i] = Vector2.zero;
|
||||
this.uvs2[index_x_s0 + i] = Vector2.zero;
|
||||
//this.uvs4[index_X4 + i] = Vector2.zero;
|
||||
this.colors32[index_x_s0 + i] = s_DefaultColor;
|
||||
this.normals[index_x_s0 + i] = s_DefaultNormal;
|
||||
this.tangents[index_x_s0 + i] = s_DefaultTangent;
|
||||
}
|
||||
|
||||
// Front Face
|
||||
this.triangles[index_x_s1 + 0] = index_x_s0 + 0;
|
||||
this.triangles[index_x_s1 + 1] = index_x_s0 + 1;
|
||||
this.triangles[index_x_s1 + 2] = index_x_s0 + 2;
|
||||
this.triangles[index_x_s1 + 3] = index_x_s0 + 2;
|
||||
this.triangles[index_x_s1 + 4] = index_x_s0 + 3;
|
||||
this.triangles[index_x_s1 + 5] = index_x_s0 + 0;
|
||||
|
||||
if (isVolumetric)
|
||||
{
|
||||
// Left Face
|
||||
this.triangles[index_x_s1 + 6] = index_x_s0 + 4;
|
||||
this.triangles[index_x_s1 + 7] = index_x_s0 + 5;
|
||||
this.triangles[index_x_s1 + 8] = index_x_s0 + 1;
|
||||
this.triangles[index_x_s1 + 9] = index_x_s0 + 1;
|
||||
this.triangles[index_x_s1 + 10] = index_x_s0 + 0;
|
||||
this.triangles[index_x_s1 + 11] = index_x_s0 + 4;
|
||||
|
||||
// Right Face
|
||||
this.triangles[index_x_s1 + 12] = index_x_s0 + 3;
|
||||
this.triangles[index_x_s1 + 13] = index_x_s0 + 2;
|
||||
this.triangles[index_x_s1 + 14] = index_x_s0 + 6;
|
||||
this.triangles[index_x_s1 + 15] = index_x_s0 + 6;
|
||||
this.triangles[index_x_s1 + 16] = index_x_s0 + 7;
|
||||
this.triangles[index_x_s1 + 17] = index_x_s0 + 3;
|
||||
|
||||
// Top Face
|
||||
this.triangles[index_x_s1 + 18] = index_x_s0 + 1;
|
||||
this.triangles[index_x_s1 + 19] = index_x_s0 + 5;
|
||||
this.triangles[index_x_s1 + 20] = index_x_s0 + 6;
|
||||
this.triangles[index_x_s1 + 21] = index_x_s0 + 6;
|
||||
this.triangles[index_x_s1 + 22] = index_x_s0 + 2;
|
||||
this.triangles[index_x_s1 + 23] = index_x_s0 + 1;
|
||||
|
||||
// Bottom Face
|
||||
this.triangles[index_x_s1 + 24] = index_x_s0 + 4;
|
||||
this.triangles[index_x_s1 + 25] = index_x_s0 + 0;
|
||||
this.triangles[index_x_s1 + 26] = index_x_s0 + 3;
|
||||
this.triangles[index_x_s1 + 27] = index_x_s0 + 3;
|
||||
this.triangles[index_x_s1 + 28] = index_x_s0 + 7;
|
||||
this.triangles[index_x_s1 + 29] = index_x_s0 + 4;
|
||||
|
||||
// Back Face
|
||||
this.triangles[index_x_s1 + 30] = index_x_s0 + 7;
|
||||
this.triangles[index_x_s1 + 31] = index_x_s0 + 6;
|
||||
this.triangles[index_x_s1 + 32] = index_x_s0 + 5;
|
||||
this.triangles[index_x_s1 + 33] = index_x_s0 + 5;
|
||||
this.triangles[index_x_s1 + 34] = index_x_s0 + 4;
|
||||
this.triangles[index_x_s1 + 35] = index_x_s0 + 7;
|
||||
}
|
||||
|
||||
index_x_s0 += s0;
|
||||
index_x_s1 += s1;
|
||||
}
|
||||
|
||||
// Pre-assign base vertex attributes.
|
||||
this.mesh.vertices = this.vertices;
|
||||
this.mesh.normals = this.normals;
|
||||
this.mesh.tangents = this.tangents;
|
||||
this.mesh.triangles = this.triangles;
|
||||
this.mesh.bounds = s_DefaultBounds;
|
||||
this.material = null;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function to resized the content of MeshData and re-assign normals, tangents and triangles.
|
||||
/// </summary>
|
||||
/// <param name="meshData"></param>
|
||||
/// <param name="size"></param>
|
||||
public void ResizeMeshInfo(int size)
|
||||
{
|
||||
// If the requested size will exceed the 16 bit mesh limit, switch mesh to use 32 bit.
|
||||
//if (size > 16383 && this.mesh.indexFormat == IndexFormat.UInt16)
|
||||
// this.mesh.indexFormat = IndexFormat.UInt32;
|
||||
size = Mathf.Min(size, 16383);
|
||||
|
||||
int size_X4 = size * 4;
|
||||
int size_X6 = size * 6;
|
||||
|
||||
int previousSize = this.vertices.Length / 4;
|
||||
|
||||
Array.Resize(ref this.vertices, size_X4);
|
||||
Array.Resize(ref this.normals, size_X4);
|
||||
Array.Resize(ref this.tangents, size_X4);
|
||||
|
||||
Array.Resize(ref this.uvs0, size_X4);
|
||||
Array.Resize(ref this.uvs2, size_X4);
|
||||
//Array.Resize(ref this.uvs4, size_X4);
|
||||
|
||||
Array.Resize(ref this.colors32, size_X4);
|
||||
|
||||
Array.Resize(ref this.triangles, size_X6);
|
||||
|
||||
|
||||
// Re-assign Normals, Tangents and Triangles
|
||||
if (size <= previousSize)
|
||||
{
|
||||
this.mesh.triangles = this.triangles;
|
||||
this.mesh.vertices = this.vertices;
|
||||
this.mesh.normals = this.normals;
|
||||
this.mesh.tangents = this.tangents;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = previousSize; i < size; i++)
|
||||
{
|
||||
int index_X4 = i * 4;
|
||||
int index_X6 = i * 6;
|
||||
|
||||
this.normals[0 + index_X4] = s_DefaultNormal;
|
||||
this.normals[1 + index_X4] = s_DefaultNormal;
|
||||
this.normals[2 + index_X4] = s_DefaultNormal;
|
||||
this.normals[3 + index_X4] = s_DefaultNormal;
|
||||
|
||||
this.tangents[0 + index_X4] = s_DefaultTangent;
|
||||
this.tangents[1 + index_X4] = s_DefaultTangent;
|
||||
this.tangents[2 + index_X4] = s_DefaultTangent;
|
||||
this.tangents[3 + index_X4] = s_DefaultTangent;
|
||||
|
||||
// Setup Triangles
|
||||
this.triangles[0 + index_X6] = 0 + index_X4;
|
||||
this.triangles[1 + index_X6] = 1 + index_X4;
|
||||
this.triangles[2 + index_X6] = 2 + index_X4;
|
||||
this.triangles[3 + index_X6] = 2 + index_X4;
|
||||
this.triangles[4 + index_X6] = 3 + index_X4;
|
||||
this.triangles[5 + index_X6] = 0 + index_X4;
|
||||
}
|
||||
|
||||
this.mesh.vertices = this.vertices;
|
||||
this.mesh.normals = this.normals;
|
||||
this.mesh.tangents = this.tangents;
|
||||
this.mesh.triangles = this.triangles;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function to resized the content of MeshData and re-assign normals, tangents and triangles.
|
||||
/// </summary>
|
||||
/// <param name="size"></param>
|
||||
/// <param name="isVolumetric"></param>
|
||||
public void ResizeMeshInfo(int size, bool isVolumetric)
|
||||
{
|
||||
int s0 = !isVolumetric ? 4 : 8;
|
||||
int s1 = !isVolumetric ? 6 : 36;
|
||||
|
||||
// Limit the mesh to less than 65535 vertices which is the limit for Unity's Mesh.
|
||||
size = Mathf.Min(size, 65532 / s0);
|
||||
|
||||
int size_X4 = size * s0;
|
||||
int size_X6 = size * s1;
|
||||
|
||||
int previousSize = this.vertices.Length / s0;
|
||||
|
||||
Array.Resize(ref this.vertices, size_X4);
|
||||
Array.Resize(ref this.normals, size_X4);
|
||||
Array.Resize(ref this.tangents, size_X4);
|
||||
|
||||
Array.Resize(ref this.uvs0, size_X4);
|
||||
Array.Resize(ref this.uvs2, size_X4);
|
||||
//Array.Resize(ref this.uvs4, size_X4);
|
||||
|
||||
Array.Resize(ref this.colors32, size_X4);
|
||||
|
||||
Array.Resize(ref this.triangles, size_X6);
|
||||
|
||||
|
||||
// Re-assign Normals, Tangents and Triangles
|
||||
if (size <= previousSize)
|
||||
{
|
||||
this.mesh.triangles = this.triangles;
|
||||
this.mesh.vertices = this.vertices;
|
||||
this.mesh.normals = this.normals;
|
||||
this.mesh.tangents = this.tangents;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = previousSize; i < size; i++)
|
||||
{
|
||||
int index_X4 = i * s0;
|
||||
int index_X6 = i * s1;
|
||||
|
||||
this.normals[0 + index_X4] = s_DefaultNormal;
|
||||
this.normals[1 + index_X4] = s_DefaultNormal;
|
||||
this.normals[2 + index_X4] = s_DefaultNormal;
|
||||
this.normals[3 + index_X4] = s_DefaultNormal;
|
||||
|
||||
this.tangents[0 + index_X4] = s_DefaultTangent;
|
||||
this.tangents[1 + index_X4] = s_DefaultTangent;
|
||||
this.tangents[2 + index_X4] = s_DefaultTangent;
|
||||
this.tangents[3 + index_X4] = s_DefaultTangent;
|
||||
|
||||
if (isVolumetric)
|
||||
{
|
||||
this.normals[4 + index_X4] = s_DefaultNormal;
|
||||
this.normals[5 + index_X4] = s_DefaultNormal;
|
||||
this.normals[6 + index_X4] = s_DefaultNormal;
|
||||
this.normals[7 + index_X4] = s_DefaultNormal;
|
||||
|
||||
this.tangents[4 + index_X4] = s_DefaultTangent;
|
||||
this.tangents[5 + index_X4] = s_DefaultTangent;
|
||||
this.tangents[6 + index_X4] = s_DefaultTangent;
|
||||
this.tangents[7 + index_X4] = s_DefaultTangent;
|
||||
}
|
||||
|
||||
// Setup Triangles
|
||||
this.triangles[0 + index_X6] = 0 + index_X4;
|
||||
this.triangles[1 + index_X6] = 1 + index_X4;
|
||||
this.triangles[2 + index_X6] = 2 + index_X4;
|
||||
this.triangles[3 + index_X6] = 2 + index_X4;
|
||||
this.triangles[4 + index_X6] = 3 + index_X4;
|
||||
this.triangles[5 + index_X6] = 0 + index_X4;
|
||||
|
||||
if (isVolumetric)
|
||||
{
|
||||
// Left Face
|
||||
this.triangles[index_X6 + 6] = index_X4 + 4;
|
||||
this.triangles[index_X6 + 7] = index_X4 + 5;
|
||||
this.triangles[index_X6 + 8] = index_X4 + 1;
|
||||
this.triangles[index_X6 + 9] = index_X4 + 1;
|
||||
this.triangles[index_X6 + 10] = index_X4 + 0;
|
||||
this.triangles[index_X6 + 11] = index_X4 + 4;
|
||||
|
||||
// Right Face
|
||||
this.triangles[index_X6 + 12] = index_X4 + 3;
|
||||
this.triangles[index_X6 + 13] = index_X4 + 2;
|
||||
this.triangles[index_X6 + 14] = index_X4 + 6;
|
||||
this.triangles[index_X6 + 15] = index_X4 + 6;
|
||||
this.triangles[index_X6 + 16] = index_X4 + 7;
|
||||
this.triangles[index_X6 + 17] = index_X4 + 3;
|
||||
|
||||
// Top Face
|
||||
this.triangles[index_X6 + 18] = index_X4 + 1;
|
||||
this.triangles[index_X6 + 19] = index_X4 + 5;
|
||||
this.triangles[index_X6 + 20] = index_X4 + 6;
|
||||
this.triangles[index_X6 + 21] = index_X4 + 6;
|
||||
this.triangles[index_X6 + 22] = index_X4 + 2;
|
||||
this.triangles[index_X6 + 23] = index_X4 + 1;
|
||||
|
||||
// Bottom Face
|
||||
this.triangles[index_X6 + 24] = index_X4 + 4;
|
||||
this.triangles[index_X6 + 25] = index_X4 + 0;
|
||||
this.triangles[index_X6 + 26] = index_X4 + 3;
|
||||
this.triangles[index_X6 + 27] = index_X4 + 3;
|
||||
this.triangles[index_X6 + 28] = index_X4 + 7;
|
||||
this.triangles[index_X6 + 29] = index_X4 + 4;
|
||||
|
||||
// Back Face
|
||||
this.triangles[index_X6 + 30] = index_X4 + 7;
|
||||
this.triangles[index_X6 + 31] = index_X4 + 6;
|
||||
this.triangles[index_X6 + 32] = index_X4 + 5;
|
||||
this.triangles[index_X6 + 33] = index_X4 + 5;
|
||||
this.triangles[index_X6 + 34] = index_X4 + 4;
|
||||
this.triangles[index_X6 + 35] = index_X4 + 7;
|
||||
}
|
||||
}
|
||||
|
||||
this.mesh.vertices = this.vertices;
|
||||
this.mesh.normals = this.normals;
|
||||
this.mesh.tangents = this.tangents;
|
||||
this.mesh.triangles = this.triangles;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function to clear the vertices while preserving the Triangles, Normals and Tangents.
|
||||
/// </summary>
|
||||
public void Clear()
|
||||
{
|
||||
if (this.vertices == null) return;
|
||||
|
||||
Array.Clear(this.vertices, 0, this.vertices.Length);
|
||||
this.vertexCount = 0;
|
||||
|
||||
if (this.mesh != null)
|
||||
this.mesh.vertices = this.vertices;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function to clear the vertices while preserving the Triangles, Normals and Tangents.
|
||||
/// </summary>
|
||||
public void Clear(bool uploadChanges)
|
||||
{
|
||||
if (this.vertices == null) return;
|
||||
|
||||
Array.Clear(this.vertices, 0, this.vertices.Length);
|
||||
this.vertexCount = 0;
|
||||
|
||||
if (uploadChanges && this.mesh != null)
|
||||
this.mesh.vertices = this.vertices;
|
||||
|
||||
if (this.mesh != null)
|
||||
this.mesh.bounds = s_DefaultBounds;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function to clear the vertices while preserving the Triangles, Normals and Tangents.
|
||||
/// </summary>
|
||||
public void ClearUnusedVertices()
|
||||
{
|
||||
int length = vertices.Length - vertexCount;
|
||||
|
||||
if (length > 0)
|
||||
Array.Clear(vertices, vertexCount, length);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function used to mark unused vertices as degenerate.
|
||||
/// </summary>
|
||||
/// <param name="startIndex"></param>
|
||||
public void ClearUnusedVertices(int startIndex)
|
||||
{
|
||||
int length = this.vertices.Length - startIndex;
|
||||
|
||||
if (length > 0)
|
||||
Array.Clear(this.vertices, startIndex, length);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function used to mark unused vertices as degenerate an upload resulting data to the mesh.
|
||||
/// </summary>
|
||||
/// <param name="startIndex"></param>
|
||||
public void ClearUnusedVertices(int startIndex, bool updateMesh)
|
||||
{
|
||||
int length = this.vertices.Length - startIndex;
|
||||
|
||||
if (length > 0)
|
||||
Array.Clear(this.vertices, startIndex, length);
|
||||
|
||||
if (updateMesh && mesh != null)
|
||||
this.mesh.vertices = this.vertices;
|
||||
}
|
||||
|
||||
|
||||
public void SortGeometry (VertexSortingOrder order)
|
||||
{
|
||||
switch (order)
|
||||
{
|
||||
case VertexSortingOrder.Normal:
|
||||
// Do nothing
|
||||
break;
|
||||
case VertexSortingOrder.Reverse:
|
||||
int size = vertexCount / 4;
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
int src = i * 4;
|
||||
int dst = (size - i - 1) * 4;
|
||||
|
||||
if (src < dst)
|
||||
SwapVertexData(src, dst);
|
||||
|
||||
}
|
||||
break;
|
||||
//case VertexSortingOrder.Depth:
|
||||
// break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function to rearrange the quads of the text object to change their rendering order.
|
||||
/// </summary>
|
||||
/// <param name="sortingOrder"></param>
|
||||
public void SortGeometry(IList<int> sortingOrder)
|
||||
{
|
||||
// Make sure the sorting order array is not larger than the vertices array.
|
||||
int indexCount = sortingOrder.Count;
|
||||
|
||||
if (indexCount * 4 > vertices.Length) return;
|
||||
|
||||
int src_index;
|
||||
|
||||
for (int dst_index = 0; dst_index < indexCount; dst_index++)
|
||||
{
|
||||
src_index = sortingOrder[dst_index];
|
||||
|
||||
while (src_index < dst_index)
|
||||
{
|
||||
src_index = sortingOrder[src_index];
|
||||
}
|
||||
|
||||
// Swap items
|
||||
if (src_index != dst_index)
|
||||
SwapVertexData(src_index * 4, dst_index * 4);
|
||||
|
||||
//Debug.Log("Swap element [" + dst_index + "] with [" + src_index + "]. Vertex[" + dst_index + "] is " + vertices[dst_index * 4].z);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Method to swap the vertex attributes between src and dst quads.
|
||||
/// </summary>
|
||||
/// <param name="src">Index of the first vertex attribute of the source character / quad.</param>
|
||||
/// <param name="dst">Index of the first vertex attribute of the destination character / quad.</param>
|
||||
public void SwapVertexData(int src, int dst)
|
||||
{
|
||||
int src_Index = src; // * 4;
|
||||
int dst_Index = dst; // * 4;
|
||||
|
||||
// Swap vertices
|
||||
Vector3 vertex;
|
||||
vertex = vertices[dst_Index + 0];
|
||||
vertices[dst_Index + 0] = vertices[src_Index + 0];
|
||||
vertices[src_Index + 0] = vertex;
|
||||
|
||||
vertex = vertices[dst_Index + 1];
|
||||
vertices[dst_Index + 1] = vertices[src_Index + 1];
|
||||
vertices[src_Index + 1] = vertex;
|
||||
|
||||
vertex = vertices[dst_Index + 2];
|
||||
vertices[dst_Index + 2] = vertices[src_Index + 2];
|
||||
vertices[src_Index + 2] = vertex;
|
||||
|
||||
vertex = vertices[dst_Index + 3];
|
||||
vertices[dst_Index + 3] = vertices[src_Index + 3];
|
||||
vertices[src_Index + 3] = vertex;
|
||||
|
||||
|
||||
//Swap UVs0
|
||||
Vector2 uvs;
|
||||
uvs = uvs0[dst_Index + 0];
|
||||
uvs0[dst_Index + 0] = uvs0[src_Index + 0];
|
||||
uvs0[src_Index + 0] = uvs;
|
||||
|
||||
uvs = uvs0[dst_Index + 1];
|
||||
uvs0[dst_Index + 1] = uvs0[src_Index + 1];
|
||||
uvs0[src_Index + 1] = uvs;
|
||||
|
||||
uvs = uvs0[dst_Index + 2];
|
||||
uvs0[dst_Index + 2] = uvs0[src_Index + 2];
|
||||
uvs0[src_Index + 2] = uvs;
|
||||
|
||||
uvs = uvs0[dst_Index + 3];
|
||||
uvs0[dst_Index + 3] = uvs0[src_Index + 3];
|
||||
uvs0[src_Index + 3] = uvs;
|
||||
|
||||
// Swap UVs2
|
||||
uvs = uvs2[dst_Index + 0];
|
||||
uvs2[dst_Index + 0] = uvs2[src_Index + 0];
|
||||
uvs2[src_Index + 0] = uvs;
|
||||
|
||||
uvs = uvs2[dst_Index + 1];
|
||||
uvs2[dst_Index + 1] = uvs2[src_Index + 1];
|
||||
uvs2[src_Index + 1] = uvs;
|
||||
|
||||
uvs = uvs2[dst_Index + 2];
|
||||
uvs2[dst_Index + 2] = uvs2[src_Index + 2];
|
||||
uvs2[src_Index + 2] = uvs;
|
||||
|
||||
uvs = uvs2[dst_Index + 3];
|
||||
uvs2[dst_Index + 3] = uvs2[src_Index + 3];
|
||||
uvs2[src_Index + 3] = uvs;
|
||||
|
||||
// Vertex Colors
|
||||
Color32 color;
|
||||
color = colors32[dst_Index + 0];
|
||||
colors32[dst_Index + 0] = colors32[src_Index + 0];
|
||||
colors32[src_Index + 0] = color;
|
||||
|
||||
color = colors32[dst_Index + 1];
|
||||
colors32[dst_Index + 1] = colors32[src_Index + 1];
|
||||
colors32[src_Index + 1] = color;
|
||||
|
||||
color = colors32[dst_Index + 2];
|
||||
colors32[dst_Index + 2] = colors32[src_Index + 2];
|
||||
colors32[src_Index + 2] = color;
|
||||
|
||||
color = colors32[dst_Index + 3];
|
||||
colors32[dst_Index + 3] = colors32[src_Index + 3];
|
||||
colors32[src_Index + 3] = color;
|
||||
}
|
||||
|
||||
|
||||
//int Partition (int start, int end)
|
||||
//{
|
||||
// float pivot = vertices[end].z;
|
||||
|
||||
// int partitionIndex = start;
|
||||
// for (int i = start; i < end; i++)
|
||||
// {
|
||||
// if (vertices[i].z <= pivot)
|
||||
// {
|
||||
// Swap(vertices[i], vertices[partitionIndex]);
|
||||
// partitionIndex += 1;
|
||||
// }
|
||||
// }
|
||||
// Swap(vertices[partitionIndex], vertices[end]);
|
||||
// return partitionIndex;
|
||||
//}
|
||||
|
||||
|
||||
//void Swap(Vector3 a, Vector3 b)
|
||||
//{
|
||||
// Vector3 temp = a;
|
||||
// a = b;
|
||||
// b = a;
|
||||
//}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
fileFormatVersion: 2
|
||||
guid: e21bec35f48a44298911b25ead550ce3
|
||||
timeCreated: 1462398762
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,51 @@
|
|||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Events;
|
||||
|
||||
|
||||
namespace TMPro
|
||||
{
|
||||
|
||||
internal class TMP_ObjectPool<T> where T : new()
|
||||
{
|
||||
private readonly Stack<T> m_Stack = new Stack<T>();
|
||||
private readonly UnityAction<T> m_ActionOnGet;
|
||||
private readonly UnityAction<T> m_ActionOnRelease;
|
||||
|
||||
public int countAll { get; private set; }
|
||||
public int countActive { get { return countAll - countInactive; } }
|
||||
public int countInactive { get { return m_Stack.Count; } }
|
||||
|
||||
public TMP_ObjectPool(UnityAction<T> actionOnGet, UnityAction<T> actionOnRelease)
|
||||
{
|
||||
m_ActionOnGet = actionOnGet;
|
||||
m_ActionOnRelease = actionOnRelease;
|
||||
}
|
||||
|
||||
public T Get()
|
||||
{
|
||||
T element;
|
||||
if (m_Stack.Count == 0)
|
||||
{
|
||||
element = new T();
|
||||
countAll++;
|
||||
}
|
||||
else
|
||||
{
|
||||
element = m_Stack.Pop();
|
||||
}
|
||||
if (m_ActionOnGet != null)
|
||||
m_ActionOnGet(element);
|
||||
return element;
|
||||
}
|
||||
|
||||
public void Release(T element)
|
||||
{
|
||||
if (m_Stack.Count > 0 && ReferenceEquals(m_Stack.Peek(), element))
|
||||
Debug.LogError("Internal error. Trying to destroy object that is already released to pool.");
|
||||
if (m_ActionOnRelease != null)
|
||||
m_ActionOnRelease(element);
|
||||
m_Stack.Push(element);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
fileFormatVersion: 2
|
||||
guid: e69259f6ff914146ad610be5491eb44a
|
||||
timeCreated: 1458521389
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,238 @@
|
|||
#if UNITY_EDITOR
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
|
||||
|
||||
namespace TMPro
|
||||
{
|
||||
[System.Serializable]
|
||||
public class TMP_PackageResourceImporter
|
||||
{
|
||||
bool m_EssentialResourcesImported;
|
||||
bool m_ExamplesAndExtrasResourcesImported;
|
||||
internal bool m_IsImportingExamples;
|
||||
|
||||
public TMP_PackageResourceImporter() { }
|
||||
|
||||
public void OnDestroy()
|
||||
{
|
||||
}
|
||||
|
||||
public void OnGUI()
|
||||
{
|
||||
// Check if the resources state has changed.
|
||||
m_EssentialResourcesImported = File.Exists("Assets/TextMesh Pro/Resources/TMP Settings.asset");
|
||||
m_ExamplesAndExtrasResourcesImported = Directory.Exists("Assets/TextMesh Pro/Examples & Extras");
|
||||
|
||||
GUILayout.BeginVertical();
|
||||
{
|
||||
// Display options to import Essential resources
|
||||
GUILayout.BeginVertical(EditorStyles.helpBox);
|
||||
{
|
||||
GUILayout.Label("TMP Essentials", EditorStyles.boldLabel);
|
||||
GUILayout.Label("This appears to be the first time you access TextMesh Pro, as such we need to add resources to your project that are essential for using TextMesh Pro. These new resources will be placed at the root of your project in the \"TextMesh Pro\" folder.", new GUIStyle(EditorStyles.label) { wordWrap = true } );
|
||||
GUILayout.Space(5f);
|
||||
|
||||
GUI.enabled = !m_EssentialResourcesImported;
|
||||
if (GUILayout.Button("Import TMP Essentials"))
|
||||
{
|
||||
AssetDatabase.importPackageCompleted += ImportCallback;
|
||||
|
||||
string packageFullPath = GetPackageFullPath();
|
||||
AssetDatabase.ImportPackage(packageFullPath + "/Package Resources/TMP Essential Resources.unitypackage", false);
|
||||
}
|
||||
GUILayout.Space(5f);
|
||||
GUI.enabled = true;
|
||||
}
|
||||
GUILayout.EndVertical();
|
||||
|
||||
// Display options to import Examples & Extras
|
||||
GUILayout.BeginVertical(EditorStyles.helpBox);
|
||||
{
|
||||
GUILayout.Label("TMP Examples & Extras", EditorStyles.boldLabel);
|
||||
GUILayout.Label("The Examples & Extras package contains addition resources and examples that will make discovering and learning about TextMesh Pro's powerful features easier. These additional resources will be placed in the same folder as the TMP essential resources.", new GUIStyle(EditorStyles.label) { wordWrap = true });
|
||||
GUILayout.Space(5f);
|
||||
|
||||
GUI.enabled = m_EssentialResourcesImported && !m_ExamplesAndExtrasResourcesImported;
|
||||
if (GUILayout.Button("Import TMP Examples & Extras"))
|
||||
{
|
||||
// Set flag to get around importing scripts as per of this package which results in an assembly reload which in turn prevents / clears any callbacks.
|
||||
m_IsImportingExamples = true;
|
||||
|
||||
// Disable AssetDatabase refresh until examples have been imported.
|
||||
//AssetDatabase.DisallowAutoRefresh();
|
||||
|
||||
string packageFullPath = GetPackageFullPath();
|
||||
AssetDatabase.ImportPackage(packageFullPath + "/Package Resources/TMP Examples & Extras.unitypackage", false);
|
||||
}
|
||||
GUILayout.Space(5f);
|
||||
GUI.enabled = true;
|
||||
}
|
||||
GUILayout.EndVertical();
|
||||
}
|
||||
GUILayout.EndVertical();
|
||||
GUILayout.Space(5f);
|
||||
}
|
||||
|
||||
internal void RegisterResourceImportCallback()
|
||||
{
|
||||
AssetDatabase.importPackageCompleted += ImportCallback;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="packageName"></param>
|
||||
void ImportCallback(string packageName)
|
||||
{
|
||||
if (packageName == "TMP Essential Resources")
|
||||
{
|
||||
m_EssentialResourcesImported = true;
|
||||
TMPro_EventManager.ON_RESOURCES_LOADED();
|
||||
|
||||
#if UNITY_2018_3_OR_NEWER
|
||||
SettingsService.NotifySettingsProviderChanged();
|
||||
#endif
|
||||
}
|
||||
else if (packageName == "TMP Examples & Extras")
|
||||
{
|
||||
m_ExamplesAndExtrasResourcesImported = true;
|
||||
m_IsImportingExamples = false;
|
||||
//AssetDatabase.AllowAutoRefresh();
|
||||
}
|
||||
|
||||
Debug.Log("[" + packageName + "] have been imported.");
|
||||
|
||||
AssetDatabase.importPackageCompleted -= ImportCallback;
|
||||
}
|
||||
|
||||
static string GetPackageFullPath()
|
||||
{
|
||||
// Check for potential UPM package
|
||||
string packagePath = Path.GetFullPath("Packages/com.unity.textmeshpro");
|
||||
if (Directory.Exists(packagePath))
|
||||
{
|
||||
return packagePath;
|
||||
}
|
||||
|
||||
packagePath = Path.GetFullPath("Assets/..");
|
||||
if (Directory.Exists(packagePath))
|
||||
{
|
||||
// Search default location for development package
|
||||
if (Directory.Exists(packagePath + "/Assets/Packages/com.unity.TextMeshPro/Editor Resources"))
|
||||
{
|
||||
return packagePath + "/Assets/Packages/com.unity.TextMeshPro";
|
||||
}
|
||||
|
||||
// Search for default location of normal TextMesh Pro AssetStore package
|
||||
if (Directory.Exists(packagePath + "/Assets/TextMesh Pro/Editor Resources"))
|
||||
{
|
||||
return packagePath + "/Assets/TextMesh Pro";
|
||||
}
|
||||
|
||||
// Search for potential alternative locations in the user project
|
||||
string[] matchingPaths = Directory.GetDirectories(packagePath, "TextMesh Pro", SearchOption.AllDirectories);
|
||||
string path = ValidateLocation(matchingPaths, packagePath);
|
||||
if (path != null) return packagePath + path;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
static string ValidateLocation(string[] paths, string projectPath)
|
||||
{
|
||||
for (int i = 0; i < paths.Length; i++)
|
||||
{
|
||||
// Check if the Editor Resources folder exists.
|
||||
if (Directory.Exists(paths[i] + "/Editor Resources"))
|
||||
{
|
||||
string folderPath = paths[i].Replace(projectPath, "");
|
||||
folderPath = folderPath.TrimStart('\\', '/');
|
||||
return folderPath;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Imports the specified TMP resources.
|
||||
/// </summary>
|
||||
/// <param name="importEssentials">Should import the TMP Essential Resources.</param>
|
||||
/// <param name="importExamples">Should import the TMP Examples & Extras.</param>
|
||||
/// <param name="interactive">If interactive is true, an import package dialog will be opened, else all assets in the package will be imported into the current project silently.</param>
|
||||
public static void ImportResources(bool importEssentials, bool importExamples, bool interactive)
|
||||
{
|
||||
string packageFullPath = GetPackageFullPath();
|
||||
|
||||
if (importEssentials)
|
||||
AssetDatabase.ImportPackage(packageFullPath + "/Package Resources/TMP Essential Resources.unitypackage", interactive);
|
||||
|
||||
if (importExamples)
|
||||
AssetDatabase.ImportPackage(packageFullPath + "/Package Resources/TMP Examples & Extras.unitypackage", interactive);
|
||||
}
|
||||
}
|
||||
|
||||
public class TMP_PackageResourceImporterWindow : EditorWindow
|
||||
{
|
||||
[SerializeField]
|
||||
TMP_PackageResourceImporter m_ResourceImporter;
|
||||
|
||||
static TMP_PackageResourceImporterWindow m_ImporterWindow;
|
||||
|
||||
public static void ShowPackageImporterWindow()
|
||||
{
|
||||
if (m_ImporterWindow == null)
|
||||
{
|
||||
m_ImporterWindow = GetWindow<TMP_PackageResourceImporterWindow>();
|
||||
m_ImporterWindow.titleContent = new GUIContent("TMP Importer");
|
||||
m_ImporterWindow.Focus();
|
||||
}
|
||||
}
|
||||
|
||||
void OnEnable()
|
||||
{
|
||||
// Set Editor Window Size
|
||||
SetEditorWindowSize();
|
||||
|
||||
if (m_ResourceImporter == null)
|
||||
m_ResourceImporter = new TMP_PackageResourceImporter();
|
||||
|
||||
if (m_ResourceImporter.m_IsImportingExamples)
|
||||
m_ResourceImporter.RegisterResourceImportCallback();
|
||||
}
|
||||
|
||||
void OnDestroy()
|
||||
{
|
||||
m_ResourceImporter.OnDestroy();
|
||||
}
|
||||
|
||||
void OnGUI()
|
||||
{
|
||||
m_ResourceImporter.OnGUI();
|
||||
}
|
||||
|
||||
void OnInspectorUpdate()
|
||||
{
|
||||
Repaint();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Limits the minimum size of the editor window.
|
||||
/// </summary>
|
||||
void SetEditorWindowSize()
|
||||
{
|
||||
EditorWindow editorWindow = this;
|
||||
|
||||
Vector2 windowSize = new Vector2(640, 210);
|
||||
editorWindow.minSize = windowSize;
|
||||
editorWindow.maxSize = windowSize;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,16 @@
|
|||
fileFormatVersion: 2
|
||||
guid: cf1fe50a641faac4691bf49eb32ce333
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences:
|
||||
- m_PersistentViewDataDictionary: {instanceID: 0}
|
||||
- LightSkin: {fileID: 11400000, guid: 0c156a7b2f4d450da1716b1625b5441d, type: 2}
|
||||
- DarkSkin: {fileID: 11400000, guid: 9d345c3252c147c89e8b61a249a46a9d, type: 2}
|
||||
- TMPEssentials: {fileID: 102900000, guid: ce4ff17ca867d2b48b5c8a4181611901, type: 3}
|
||||
- TMPExamples: {fileID: 102900000, guid: bc00e25696e4132499f56528d3fed2e3, type: 3}
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,90 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
namespace TMPro
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class TMP_ResourceManager
|
||||
{
|
||||
private static readonly TMP_ResourceManager s_instance = new TMP_ResourceManager();
|
||||
|
||||
static TMP_ResourceManager() { }
|
||||
|
||||
// ======================================================
|
||||
// TEXT SETTINGS MANAGEMENT
|
||||
// ======================================================
|
||||
|
||||
private static TMP_Settings s_TextSettings;
|
||||
|
||||
internal static TMP_Settings GetTextSettings()
|
||||
{
|
||||
if (s_TextSettings == null)
|
||||
{
|
||||
// Try loading the TMP Settings from a Resources folder in the user project.
|
||||
s_TextSettings = Resources.Load<TMP_Settings>("TextSettings"); // ?? ScriptableObject.CreateInstance<TMP_Settings>();
|
||||
|
||||
#if UNITY_EDITOR
|
||||
if (s_TextSettings == null)
|
||||
{
|
||||
// Open TMP Resources Importer to enable the user to import the TMP Essential Resources and option TMP Examples & Extras
|
||||
TMP_PackageResourceImporterWindow.ShowPackageImporterWindow();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return s_TextSettings;
|
||||
}
|
||||
|
||||
// ======================================================
|
||||
// FONT ASSET MANAGEMENT - Fields, Properties and Functions
|
||||
// ======================================================
|
||||
|
||||
private static readonly List<TMP_FontAsset> s_FontAssetReferences = new List<TMP_FontAsset>();
|
||||
private static readonly Dictionary<int, TMP_FontAsset> s_FontAssetReferenceLookup = new Dictionary<int, TMP_FontAsset>();
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="fontAsset"></param>
|
||||
public static void AddFontAsset(TMP_FontAsset fontAsset)
|
||||
{
|
||||
int hashcode = fontAsset.hashCode;
|
||||
|
||||
if (s_FontAssetReferenceLookup.ContainsKey(hashcode))
|
||||
return;
|
||||
|
||||
s_FontAssetReferences.Add(fontAsset);
|
||||
s_FontAssetReferenceLookup.Add(hashcode, fontAsset);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="hashcode"></param>
|
||||
/// <param name="fontAsset"></param>
|
||||
/// <returns></returns>
|
||||
public static bool TryGetFontAsset(int hashcode, out TMP_FontAsset fontAsset)
|
||||
{
|
||||
fontAsset = null;
|
||||
|
||||
return s_FontAssetReferenceLookup.TryGetValue(hashcode, out fontAsset);
|
||||
}
|
||||
|
||||
|
||||
internal static void RebuildFontAssetCache(int instanceID)
|
||||
{
|
||||
// Iterate over loaded font assets to update affected font assets
|
||||
for (int i = 0; i < s_FontAssetReferences.Count; i++)
|
||||
{
|
||||
TMP_FontAsset fontAsset = s_FontAssetReferences[i];
|
||||
|
||||
if (fontAsset.FallbackSearchQueryLookup.Contains(instanceID))
|
||||
fontAsset.ReadFontAssetDefinition();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 4877f87131635e6408f8c44e5d86791e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,202 @@
|
|||
using System;
|
||||
using UnityEngine.Bindings;
|
||||
|
||||
|
||||
namespace TMPro
|
||||
{
|
||||
/// <summary>
|
||||
/// Rich Text Tags and Attribute definitions and their respective HashCode values.
|
||||
/// </summary>
|
||||
internal enum MarkupTag : int
|
||||
{
|
||||
// Rich Text Tags
|
||||
BOLD = 66, // <b>
|
||||
SLASH_BOLD = 1613, // </b>
|
||||
ITALIC = 73, // <i>
|
||||
SLASH_ITALIC = 1606, // </i>
|
||||
UNDERLINE = 85, // <u>
|
||||
SLASH_UNDERLINE = 1626, // </u>
|
||||
STRIKETHROUGH = 83, // <s>
|
||||
SLASH_STRIKETHROUGH = 1628, // </s>
|
||||
MARK = 2699125, // <mark>
|
||||
SLASH_MARK = 57644506, // </mark>
|
||||
SUBSCRIPT = 92132, // <sub>
|
||||
SLASH_SUBSCRIPT = 1770219, // </sub>
|
||||
SUPERSCRIPT = 92150, // <sup>
|
||||
SLASH_SUPERSCRIPT = 1770233, // </sup>
|
||||
COLOR = 81999901, // <color>
|
||||
SLASH_COLOR = 1909026194, // </color>
|
||||
ALPHA = 75165780, // <alpha>
|
||||
A = 65, // <a>
|
||||
SLASH_A = 1614, // </a>
|
||||
SIZE = 3061285, // <size>
|
||||
SLASH_SIZE = 58429962, // </size>
|
||||
SPRITE = -991527447, // <sprite>
|
||||
NO_BREAK = 2856657, // <nobr>
|
||||
SLASH_NO_BREAK = 57477502, // </nobr>
|
||||
STYLE = 100252951, // <style>
|
||||
SLASH_STYLE = 1927738392, // </style>
|
||||
FONT = 2586451, // <font>
|
||||
SLASH_FONT = 57747708, // </font>
|
||||
SLASH_MATERIAL = -1100708252, // </material>
|
||||
LINK = 2656128, // <link>
|
||||
SLASH_LINK = 57686191, // </link>
|
||||
FONT_WEIGHT = -1889896162, // <font-weight=xxx>
|
||||
SLASH_FONT_WEIGHT = -757976431, // </font-weight>
|
||||
NO_PARSE = -408011596, // <noparse>
|
||||
SLASH_NO_PARSE = -294095813, // </noparse>
|
||||
POSITION = 85420, // <pos>
|
||||
SLASH_POSITION = 1777699, // </pos>
|
||||
VERTICAL_OFFSET = 1952379995, // <voffset>
|
||||
SLASH_VERTICAL_OFFSET = -11107948, // </voffset>
|
||||
SPACE = 100083556, // <space>
|
||||
SLASH_SPACE = 1927873067, // </space>
|
||||
PAGE = 2808691, // <page>
|
||||
SLASH_PAGE = 58683868, // </page>
|
||||
ALIGN = 75138797, // <align>
|
||||
SLASH_ALIGN = 1916026786, // </align>
|
||||
WIDTH = 105793766, // <width>
|
||||
SLASH_WIDTH = 1923459625, // </width>
|
||||
GRADIENT = -1999759898, // <gradient>
|
||||
SLASH_GRADIENT = -1854491959, // </gradient>
|
||||
CHARACTER_SPACE = -1584382009, // <cspace>
|
||||
SLASH_CHARACTER_SPACE = -1394426712,// </cspace>
|
||||
MONOSPACE = -1340221943, // <mspace>
|
||||
SLASH_MONOSPACE = -1638865562, // </mspace>
|
||||
CLASS = 82115566, // <class>
|
||||
INDENT = -1514123076, // <indent>
|
||||
SLASH_INDENT = -1496889389, // </indent>
|
||||
LINE_INDENT = -844305121, // <line-indent>
|
||||
SLASH_LINE_INDENT = 93886352, // </line-indent>
|
||||
MARGIN = -1355614050, // <margin>
|
||||
SLASH_MARGIN = -1649644303, // </margin>
|
||||
MARGIN_LEFT = -272933656, // <margin-left>
|
||||
MARGIN_RIGHT = -447416589, // <margin-right>
|
||||
LINE_HEIGHT = -799081892, // <line-height>
|
||||
SLASH_LINE_HEIGHT = 200452819, // </line-height>
|
||||
ACTION = -1827519330, // <action>
|
||||
SLASH_ACTION = -1187217679, // </action>
|
||||
SCALE = 100553336, // <scale>
|
||||
SLASH_SCALE = 1928413879, // </scale>
|
||||
ROTATE = -1000007783, // <rotate>
|
||||
SLASH_ROTATE = -764695562, // </rotate>
|
||||
|
||||
LOWERCASE = -1506899689, // <lowercase>
|
||||
SLASH_LOWERCASE = -1451284584, // </lowercase>
|
||||
ALLCAPS = 218273952, // <allcaps>
|
||||
SLASH_ALLCAPS = -797437649, // </allcaps>
|
||||
UPPERCASE = -305409418, // <uppercase>
|
||||
SLASH_UPPERCASE = -582368199, // </uppercase>
|
||||
SMALLCAPS = -766062114, // <smallcaps>
|
||||
SLASH_SMALLCAPS = 199921873, // </smallcaps>
|
||||
|
||||
// Font Features
|
||||
LIGA = 2655971, // <liga>
|
||||
SLASH_LIGA = 57686604, // </liga>
|
||||
FRAC = 2598518, // <frac>
|
||||
SLASH_FRAC = 57774681, // </frac>
|
||||
|
||||
// Attributes
|
||||
NAME = 2875623, // <sprite name="Name of Sprite">
|
||||
INDEX = 84268030, // <sprite index=7>
|
||||
TINT = 2960519, // <tint=bool>
|
||||
ANIM = 2283339, // <anim="first frame, last frame, frame rate">
|
||||
MATERIAL = 825491659, // <font="Name of font asset" material="Name of material">
|
||||
HREF = 2535353, // <a href="url">text to be displayed.</a>
|
||||
ANGLE = 75347905, // <i angle="40">Italic Slant Angle</i>
|
||||
|
||||
// Named Colors
|
||||
RED = 91635,
|
||||
GREEN = 87065851,
|
||||
BLUE = 2457214,
|
||||
YELLOW = -882444668,
|
||||
ORANGE = -1108587920,
|
||||
BLACK = 81074727,
|
||||
WHITE = 105680263,
|
||||
PURPLE = -1250222130,
|
||||
|
||||
// Unicode Characters
|
||||
BR = 2256, // <br> Line Feed (LF) \u0A
|
||||
ZWSP = 3288238, // <zwsp> Zero Width Space \u200B
|
||||
NBSP = 2869039, // <nbsp> Non Breaking Space \u00A0
|
||||
SHY = 92674, // <SHY> Soft Hyphen \u00AD
|
||||
|
||||
// Alignment
|
||||
LEFT = 2660507, // <align=left>
|
||||
RIGHT = 99937376, // <align=right>
|
||||
CENTER = -1591113269, // <align=center>
|
||||
JUSTIFIED = 817091359, // <align=justified>
|
||||
FLUSH = 85552164, // <align=flush>
|
||||
|
||||
// Prefix and Unit suffix
|
||||
NONE = 2857034,
|
||||
PLUS = 43,
|
||||
MINUS = 45,
|
||||
PX = 2568,
|
||||
PLUS_PX = 49507,
|
||||
MINUS_PX = 47461,
|
||||
EM = 2216,
|
||||
PLUS_EM = 49091,
|
||||
MINUS_EM = 46789,
|
||||
PCT = 85031,
|
||||
PLUS_PCT = 1634348,
|
||||
MINUS_PCT = 1567082,
|
||||
PERCENTAGE = 37,
|
||||
PLUS_PERCENTAGE = 1454,
|
||||
MINUS_PERCENTAGE = 1512,
|
||||
|
||||
TRUE = 2932022,
|
||||
FALSE = 85422813,
|
||||
|
||||
INVALID = 1585415185,
|
||||
|
||||
NORMAL = -1183493901, // <style="Normal">
|
||||
DEFAULT = -620974005, // <font="Default">
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Defines the type of value used by a rich text tag or tag attribute.
|
||||
/// </summary>
|
||||
public enum TagValueType
|
||||
{
|
||||
None = 0x0,
|
||||
NumericalValue = 0x1,
|
||||
StringValue = 0x2,
|
||||
ColorValue = 0x4,
|
||||
}
|
||||
|
||||
public enum TagUnitType
|
||||
{
|
||||
Pixels = 0x0,
|
||||
FontUnits = 0x1,
|
||||
Percentage = 0x2,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Commonly referenced Unicode characters in the text generation process.
|
||||
/// </summary>
|
||||
internal static class CodePoint
|
||||
{
|
||||
public const uint SPACE = 0x20;
|
||||
public const uint DOUBLE_QUOTE = 0x22;
|
||||
public const uint NUMBER_SIGN = 0x23;
|
||||
public const uint PERCENTAGE = 0x25;
|
||||
public const uint PLUS = 0x2B;
|
||||
public const uint MINUS = 0x2D;
|
||||
public const uint PERIOD = 0x2E;
|
||||
|
||||
public const uint HYPHEN_MINUS = 0x2D;
|
||||
public const uint SOFT_HYPHEN = 0xAD;
|
||||
public const uint HYPHEN = 0x2010;
|
||||
public const uint NON_BREAKING_HYPHEN = 0x2011;
|
||||
public const uint ZERO_WIDTH_SPACE = 0x200B;
|
||||
public const uint RIGHT_SINGLE_QUOTATION = 0x2019;
|
||||
public const uint APOSTROPHE = 0x27;
|
||||
public const uint WORD_JOINER = 0x2060;
|
||||
public const uint HIGH_SURROGATE_START = 0xD800;
|
||||
public const uint HIGH_SURROGATE_END = 0xDBFF;
|
||||
public const uint LOW_SURROGATE_START = 0xDC00;
|
||||
public const uint LOW_SURROGATE_END = 0xDFFF;
|
||||
public const uint UNICODE_PLANE01_START = 0x10000;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: b458b2c7f196bdc4581b2f9fd6a5d931
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,31 @@
|
|||
using UnityEngine;
|
||||
using UnityEngine.Events;
|
||||
using UnityEngine.EventSystems;
|
||||
using System;
|
||||
|
||||
|
||||
namespace TMPro
|
||||
{
|
||||
|
||||
public class TMP_ScrollbarEventHandler : MonoBehaviour, IPointerClickHandler, ISelectHandler, IDeselectHandler
|
||||
{
|
||||
public bool isSelected;
|
||||
|
||||
public void OnPointerClick(PointerEventData eventData)
|
||||
{
|
||||
Debug.Log("Scrollbar click...");
|
||||
}
|
||||
|
||||
public void OnSelect(BaseEventData eventData)
|
||||
{
|
||||
Debug.Log("Scrollbar selected");
|
||||
isSelected = true;
|
||||
}
|
||||
|
||||
public void OnDeselect(BaseEventData eventData)
|
||||
{
|
||||
Debug.Log("Scrollbar De-Selected");
|
||||
isSelected = false;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 34e150112c1c42ac83170b52d898e322
|
||||
timeCreated: 1484171293
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,37 @@
|
|||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
|
||||
namespace TMPro
|
||||
{
|
||||
/// <summary>
|
||||
/// A simple component that can be added to a newly created object where inheriting from MaskableGraphic is needed.
|
||||
/// </summary>
|
||||
[RequireComponent(typeof(CanvasRenderer))]
|
||||
public class TMP_SelectionCaret : MaskableGraphic
|
||||
{
|
||||
/// <summary>
|
||||
/// Override to Cull function of MaskableGraphic to prevent Culling.
|
||||
/// </summary>
|
||||
/// <param name="clipRect"></param>
|
||||
/// <param name="validRect"></param>
|
||||
public override void Cull(Rect clipRect, bool validRect)
|
||||
{
|
||||
//Debug.Log("***** Cull (" + clipRect + ") Valid Rect: " + validRect + " Cull: " + canvasRenderer.cull + " *****");
|
||||
|
||||
if (validRect)
|
||||
{
|
||||
canvasRenderer.cull = false;
|
||||
CanvasUpdateRegistry.RegisterCanvasElementForGraphicRebuild(this);
|
||||
return;
|
||||
}
|
||||
|
||||
base.Cull(clipRect, validRect);
|
||||
}
|
||||
|
||||
protected override void UpdateGeometry()
|
||||
{
|
||||
// Function overridden as Caret and text Selection Highlight is controlled by the Input Field.
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
fileFormatVersion: 2
|
||||
guid: ca819640f53b48919bf7774744f7f15e
|
||||
timeCreated: 1477609203
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,520 @@
|
|||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
|
||||
#pragma warning disable 0649 // Disabled warnings related to serialized fields not assigned in this script but used in the editor.
|
||||
|
||||
namespace TMPro
|
||||
{
|
||||
/// <summary>
|
||||
/// Scaling options for the sprites
|
||||
/// </summary>
|
||||
//public enum SpriteRelativeScaling
|
||||
//{
|
||||
// RelativeToPrimary = 0x1,
|
||||
// RelativeToCurrent = 0x2,
|
||||
//}
|
||||
|
||||
[System.Serializable][ExcludeFromPresetAttribute]
|
||||
public class TMP_Settings : ScriptableObject
|
||||
{
|
||||
private static TMP_Settings s_Instance;
|
||||
|
||||
/// <summary>
|
||||
/// Returns the release version of the product.
|
||||
/// </summary>
|
||||
public static string version
|
||||
{
|
||||
get { return "1.4.0"; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Controls if Word Wrapping will be enabled on newly created text objects by default.
|
||||
/// </summary>
|
||||
public static bool enableWordWrapping
|
||||
{
|
||||
get { return instance.m_enableWordWrapping; }
|
||||
}
|
||||
[SerializeField]
|
||||
private bool m_enableWordWrapping;
|
||||
|
||||
/// <summary>
|
||||
/// Controls if Kerning is enabled on newly created text objects by default.
|
||||
/// </summary>
|
||||
public static bool enableKerning
|
||||
{
|
||||
get { return instance.m_enableKerning; }
|
||||
}
|
||||
[SerializeField]
|
||||
private bool m_enableKerning;
|
||||
|
||||
/// <summary>
|
||||
/// Controls if Extra Padding is enabled on newly created text objects by default.
|
||||
/// </summary>
|
||||
public static bool enableExtraPadding
|
||||
{
|
||||
get { return instance.m_enableExtraPadding; }
|
||||
}
|
||||
[SerializeField]
|
||||
private bool m_enableExtraPadding;
|
||||
|
||||
/// <summary>
|
||||
/// Controls if TintAllSprites is enabled on newly created text objects by default.
|
||||
/// </summary>
|
||||
public static bool enableTintAllSprites
|
||||
{
|
||||
get { return instance.m_enableTintAllSprites; }
|
||||
}
|
||||
[SerializeField]
|
||||
private bool m_enableTintAllSprites;
|
||||
|
||||
/// <summary>
|
||||
/// Controls if Escape Characters will be parsed in the Text Input Box on newly created text objects.
|
||||
/// </summary>
|
||||
public static bool enableParseEscapeCharacters
|
||||
{
|
||||
get { return instance.m_enableParseEscapeCharacters; }
|
||||
}
|
||||
[SerializeField]
|
||||
private bool m_enableParseEscapeCharacters;
|
||||
|
||||
/// <summary>
|
||||
/// Controls if Raycast Target is enabled by default on newly created text objects.
|
||||
/// </summary>
|
||||
public static bool enableRaycastTarget
|
||||
{
|
||||
get { return instance.m_EnableRaycastTarget; }
|
||||
}
|
||||
[SerializeField]
|
||||
private bool m_EnableRaycastTarget = true;
|
||||
|
||||
/// <summary>
|
||||
/// Determines if OpenType Font Features should be retrieved at runtime from the source font file.
|
||||
/// </summary>
|
||||
public static bool getFontFeaturesAtRuntime
|
||||
{
|
||||
get { return instance.m_GetFontFeaturesAtRuntime; }
|
||||
}
|
||||
[SerializeField]
|
||||
private bool m_GetFontFeaturesAtRuntime = true;
|
||||
|
||||
/// <summary>
|
||||
/// The character that will be used as a replacement for missing glyphs in a font asset.
|
||||
/// </summary>
|
||||
public static int missingGlyphCharacter
|
||||
{
|
||||
get { return instance.m_missingGlyphCharacter; }
|
||||
set { instance.m_missingGlyphCharacter = value; }
|
||||
}
|
||||
[SerializeField]
|
||||
private int m_missingGlyphCharacter;
|
||||
|
||||
/// <summary>
|
||||
/// Controls the display of warning message in the console.
|
||||
/// </summary>
|
||||
public static bool warningsDisabled
|
||||
{
|
||||
get { return instance.m_warningsDisabled; }
|
||||
}
|
||||
[SerializeField]
|
||||
private bool m_warningsDisabled;
|
||||
|
||||
/// <summary>
|
||||
/// Returns the Default Font Asset to be used by newly created text objects.
|
||||
/// </summary>
|
||||
public static TMP_FontAsset defaultFontAsset
|
||||
{
|
||||
get { return instance.m_defaultFontAsset; }
|
||||
}
|
||||
[SerializeField]
|
||||
private TMP_FontAsset m_defaultFontAsset;
|
||||
|
||||
/// <summary>
|
||||
/// The relative path to a Resources folder in the project.
|
||||
/// </summary>
|
||||
public static string defaultFontAssetPath
|
||||
{
|
||||
get { return instance.m_defaultFontAssetPath; }
|
||||
}
|
||||
[SerializeField]
|
||||
private string m_defaultFontAssetPath;
|
||||
|
||||
/// <summary>
|
||||
/// The Default Point Size of newly created text objects.
|
||||
/// </summary>
|
||||
public static float defaultFontSize
|
||||
{
|
||||
get { return instance.m_defaultFontSize; }
|
||||
}
|
||||
[SerializeField]
|
||||
private float m_defaultFontSize;
|
||||
|
||||
/// <summary>
|
||||
/// The multiplier used to computer the default Min point size when Text Auto Sizing is used.
|
||||
/// </summary>
|
||||
public static float defaultTextAutoSizingMinRatio
|
||||
{
|
||||
get { return instance.m_defaultAutoSizeMinRatio; }
|
||||
}
|
||||
[SerializeField]
|
||||
private float m_defaultAutoSizeMinRatio;
|
||||
|
||||
/// <summary>
|
||||
/// The multiplier used to computer the default Max point size when Text Auto Sizing is used.
|
||||
/// </summary>
|
||||
public static float defaultTextAutoSizingMaxRatio
|
||||
{
|
||||
get { return instance.m_defaultAutoSizeMaxRatio; }
|
||||
}
|
||||
[SerializeField]
|
||||
private float m_defaultAutoSizeMaxRatio;
|
||||
|
||||
/// <summary>
|
||||
/// The Default Size of the Text Container of a TextMeshPro object.
|
||||
/// </summary>
|
||||
public static Vector2 defaultTextMeshProTextContainerSize
|
||||
{
|
||||
get { return instance.m_defaultTextMeshProTextContainerSize; }
|
||||
}
|
||||
[SerializeField]
|
||||
private Vector2 m_defaultTextMeshProTextContainerSize;
|
||||
|
||||
/// <summary>
|
||||
/// The Default Width of the Text Container of a TextMeshProUI object.
|
||||
/// </summary>
|
||||
public static Vector2 defaultTextMeshProUITextContainerSize
|
||||
{
|
||||
get { return instance.m_defaultTextMeshProUITextContainerSize; }
|
||||
}
|
||||
[SerializeField]
|
||||
private Vector2 m_defaultTextMeshProUITextContainerSize;
|
||||
|
||||
/// <summary>
|
||||
/// Set the size of the text container of newly created text objects to match the size of the text.
|
||||
/// </summary>
|
||||
public static bool autoSizeTextContainer
|
||||
{
|
||||
get { return instance.m_autoSizeTextContainer; }
|
||||
}
|
||||
[SerializeField]
|
||||
private bool m_autoSizeTextContainer;
|
||||
|
||||
/// <summary>
|
||||
/// Disables InternalUpdate() calls when true. This can improve performance when the scale of the text object is static.
|
||||
/// </summary>
|
||||
public static bool isTextObjectScaleStatic
|
||||
{
|
||||
get { return instance.m_IsTextObjectScaleStatic; }
|
||||
set { instance.m_IsTextObjectScaleStatic = value; }
|
||||
}
|
||||
[SerializeField]
|
||||
private bool m_IsTextObjectScaleStatic;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Returns the list of Fallback Fonts defined in the TMP Settings file.
|
||||
/// </summary>
|
||||
public static List<TMP_FontAsset> fallbackFontAssets
|
||||
{
|
||||
get { return instance.m_fallbackFontAssets; }
|
||||
}
|
||||
[SerializeField]
|
||||
private List<TMP_FontAsset> m_fallbackFontAssets;
|
||||
|
||||
/// <summary>
|
||||
/// Controls whether or not TMP will create a matching material preset or use the default material of the fallback font asset.
|
||||
/// </summary>
|
||||
public static bool matchMaterialPreset
|
||||
{
|
||||
get { return instance.m_matchMaterialPreset; }
|
||||
}
|
||||
[SerializeField]
|
||||
private bool m_matchMaterialPreset;
|
||||
|
||||
/// <summary>
|
||||
/// The Default Sprite Asset to be used by default.
|
||||
/// </summary>
|
||||
public static TMP_SpriteAsset defaultSpriteAsset
|
||||
{
|
||||
get { return instance.m_defaultSpriteAsset; }
|
||||
}
|
||||
[SerializeField]
|
||||
private TMP_SpriteAsset m_defaultSpriteAsset;
|
||||
|
||||
/// <summary>
|
||||
/// The relative path to a Resources folder in the project.
|
||||
/// </summary>
|
||||
public static string defaultSpriteAssetPath
|
||||
{
|
||||
get { return instance.m_defaultSpriteAssetPath; }
|
||||
}
|
||||
[SerializeField]
|
||||
private string m_defaultSpriteAssetPath;
|
||||
|
||||
/// <summary>
|
||||
/// Determines if Emoji support is enabled in the Input Field TouchScreenKeyboard.
|
||||
/// </summary>
|
||||
public static bool enableEmojiSupport
|
||||
{
|
||||
get { return instance.m_enableEmojiSupport; }
|
||||
set { instance.m_enableEmojiSupport = value; }
|
||||
}
|
||||
[SerializeField]
|
||||
private bool m_enableEmojiSupport;
|
||||
|
||||
/// <summary>
|
||||
/// The unicode value of the sprite that will be used when the requested sprite is missing from the sprite asset and potential fallbacks.
|
||||
/// </summary>
|
||||
public static uint missingCharacterSpriteUnicode
|
||||
{
|
||||
get { return instance.m_MissingCharacterSpriteUnicode; }
|
||||
set { instance.m_MissingCharacterSpriteUnicode = value; }
|
||||
}
|
||||
[SerializeField]
|
||||
private uint m_MissingCharacterSpriteUnicode;
|
||||
|
||||
/// <summary>
|
||||
/// Determines if sprites will be scaled relative to the primary font asset assigned to the text object or relative to the current font asset.
|
||||
/// </summary>
|
||||
//public static SpriteRelativeScaling spriteRelativeScaling
|
||||
//{
|
||||
// get { return instance.m_SpriteRelativeScaling; }
|
||||
// set { instance.m_SpriteRelativeScaling = value; }
|
||||
//}
|
||||
//[SerializeField]
|
||||
//private SpriteRelativeScaling m_SpriteRelativeScaling = SpriteRelativeScaling.RelativeToCurrent;
|
||||
|
||||
/// <summary>
|
||||
/// The relative path to a Resources folder in the project that contains Color Gradient Presets.
|
||||
/// </summary>
|
||||
public static string defaultColorGradientPresetsPath
|
||||
{
|
||||
get { return instance.m_defaultColorGradientPresetsPath; }
|
||||
}
|
||||
[SerializeField]
|
||||
private string m_defaultColorGradientPresetsPath;
|
||||
|
||||
/// <summary>
|
||||
/// The Default Style Sheet used by the text objects.
|
||||
/// </summary>
|
||||
public static TMP_StyleSheet defaultStyleSheet
|
||||
{
|
||||
get { return instance.m_defaultStyleSheet; }
|
||||
}
|
||||
[SerializeField]
|
||||
private TMP_StyleSheet m_defaultStyleSheet;
|
||||
|
||||
/// <summary>
|
||||
/// The relative path to a Resources folder in the project that contains the TMP Style Sheets.
|
||||
/// </summary>
|
||||
public static string styleSheetsResourcePath
|
||||
{
|
||||
get { return instance.m_StyleSheetsResourcePath; }
|
||||
}
|
||||
[SerializeField]
|
||||
private string m_StyleSheetsResourcePath;
|
||||
|
||||
/// <summary>
|
||||
/// Text file that contains the leading characters used for line breaking for Asian languages.
|
||||
/// </summary>
|
||||
public static TextAsset leadingCharacters
|
||||
{
|
||||
get { return instance.m_leadingCharacters; }
|
||||
}
|
||||
[SerializeField]
|
||||
private TextAsset m_leadingCharacters;
|
||||
|
||||
/// <summary>
|
||||
/// Text file that contains the following characters used for line breaking for Asian languages.
|
||||
/// </summary>
|
||||
public static TextAsset followingCharacters
|
||||
{
|
||||
get { return instance.m_followingCharacters; }
|
||||
}
|
||||
[SerializeField]
|
||||
private TextAsset m_followingCharacters;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static LineBreakingTable linebreakingRules
|
||||
{
|
||||
get
|
||||
{
|
||||
if (instance.m_linebreakingRules == null)
|
||||
LoadLinebreakingRules();
|
||||
|
||||
return instance.m_linebreakingRules;
|
||||
}
|
||||
}
|
||||
[SerializeField]
|
||||
private LineBreakingTable m_linebreakingRules;
|
||||
|
||||
// TODO : Potential new feature to explore where multiple font assets share the same atlas texture.
|
||||
//internal static TMP_DynamicAtlasTextureGroup managedAtlasTextures
|
||||
//{
|
||||
// get
|
||||
// {
|
||||
// if (instance.m_DynamicAtlasTextureGroup == null)
|
||||
// {
|
||||
// instance.m_DynamicAtlasTextureGroup = TMP_DynamicAtlasTextureGroup.CreateDynamicAtlasTextureGroup();
|
||||
// }
|
||||
|
||||
// return instance.m_DynamicAtlasTextureGroup;
|
||||
// }
|
||||
//}
|
||||
//[SerializeField]
|
||||
//private TMP_DynamicAtlasTextureGroup m_DynamicAtlasTextureGroup;
|
||||
|
||||
/// <summary>
|
||||
/// Determines if Modern or Traditional line breaking rules should be used for Korean text.
|
||||
/// </summary>
|
||||
public static bool useModernHangulLineBreakingRules
|
||||
{
|
||||
get { return instance.m_UseModernHangulLineBreakingRules; }
|
||||
set { instance.m_UseModernHangulLineBreakingRules = value; }
|
||||
}
|
||||
[SerializeField]
|
||||
private bool m_UseModernHangulLineBreakingRules;
|
||||
|
||||
/// <summary>
|
||||
/// Get a singleton instance of the settings class.
|
||||
/// </summary>
|
||||
public static TMP_Settings instance
|
||||
{
|
||||
get
|
||||
{
|
||||
if (TMP_Settings.s_Instance == null)
|
||||
{
|
||||
TMP_Settings.s_Instance = Resources.Load<TMP_Settings>("TMP Settings");
|
||||
|
||||
#if UNITY_EDITOR
|
||||
// Make sure TextMesh Pro UPM packages resources have been added to the user project
|
||||
if (TMP_Settings.s_Instance == null)
|
||||
{
|
||||
// Open TMP Resources Importer
|
||||
TMP_PackageResourceImporterWindow.ShowPackageImporterWindow();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return TMP_Settings.s_Instance;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Static Function to load the TMP Settings file.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static TMP_Settings LoadDefaultSettings()
|
||||
{
|
||||
if (s_Instance == null)
|
||||
{
|
||||
// Load settings from TMP_Settings file
|
||||
TMP_Settings settings = Resources.Load<TMP_Settings>("TMP Settings");
|
||||
if (settings != null)
|
||||
s_Instance = settings;
|
||||
}
|
||||
|
||||
return s_Instance;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Returns the Sprite Asset defined in the TMP Settings file.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static TMP_Settings GetSettings()
|
||||
{
|
||||
if (TMP_Settings.instance == null) return null;
|
||||
|
||||
return TMP_Settings.instance;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Returns the Font Asset defined in the TMP Settings file.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static TMP_FontAsset GetFontAsset()
|
||||
{
|
||||
if (TMP_Settings.instance == null) return null;
|
||||
|
||||
return TMP_Settings.instance.m_defaultFontAsset;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Returns the Sprite Asset defined in the TMP Settings file.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static TMP_SpriteAsset GetSpriteAsset()
|
||||
{
|
||||
if (TMP_Settings.instance == null) return null;
|
||||
|
||||
return TMP_Settings.instance.m_defaultSpriteAsset;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Returns the Style Sheet defined in the TMP Settings file.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static TMP_StyleSheet GetStyleSheet()
|
||||
{
|
||||
if (TMP_Settings.instance == null) return null;
|
||||
|
||||
return TMP_Settings.instance.m_defaultStyleSheet;
|
||||
}
|
||||
|
||||
|
||||
public static void LoadLinebreakingRules()
|
||||
{
|
||||
//Debug.Log("Loading Line Breaking Rules for Asian Languages.");
|
||||
|
||||
if (TMP_Settings.instance == null) return;
|
||||
|
||||
if (s_Instance.m_linebreakingRules == null)
|
||||
s_Instance.m_linebreakingRules = new LineBreakingTable();
|
||||
|
||||
s_Instance.m_linebreakingRules.leadingCharacters = GetCharacters(s_Instance.m_leadingCharacters);
|
||||
s_Instance.m_linebreakingRules.followingCharacters = GetCharacters(s_Instance.m_followingCharacters);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Get the characters from the line breaking files
|
||||
/// </summary>
|
||||
/// <param name="file"></param>
|
||||
/// <returns></returns>
|
||||
private static Dictionary<int, char> GetCharacters(TextAsset file)
|
||||
{
|
||||
Dictionary<int, char> dict = new Dictionary<int, char>();
|
||||
string text = file.text;
|
||||
|
||||
for (int i = 0; i < text.Length; i++)
|
||||
{
|
||||
char c = text[i];
|
||||
// Check to make sure we don't include duplicates
|
||||
if (dict.ContainsKey((int)c) == false)
|
||||
{
|
||||
dict.Add((int)c, c);
|
||||
//Debug.Log("Adding [" + (int)c + "] to dictionary.");
|
||||
}
|
||||
//else
|
||||
// Debug.Log("Character [" + text[i] + "] is a duplicate.");
|
||||
}
|
||||
|
||||
return dict;
|
||||
}
|
||||
|
||||
|
||||
public class LineBreakingTable
|
||||
{
|
||||
public Dictionary<int, char> leadingCharacters;
|
||||
public Dictionary<int, char> followingCharacters;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 2705215ac5b84b70bacc50632be6e391
|
||||
timeCreated: 1457654851
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,603 @@
|
|||
using UnityEngine;
|
||||
using System.Linq;
|
||||
using System.Collections;
|
||||
|
||||
|
||||
namespace TMPro
|
||||
{
|
||||
public static class ShaderUtilities
|
||||
{
|
||||
// Shader Property IDs
|
||||
public static int ID_MainTex;
|
||||
|
||||
public static int ID_FaceTex;
|
||||
public static int ID_FaceColor;
|
||||
public static int ID_FaceDilate;
|
||||
public static int ID_Shininess;
|
||||
|
||||
public static int ID_UnderlayColor;
|
||||
public static int ID_UnderlayOffsetX;
|
||||
public static int ID_UnderlayOffsetY;
|
||||
public static int ID_UnderlayDilate;
|
||||
public static int ID_UnderlaySoftness;
|
||||
|
||||
/// <summary>
|
||||
/// Property ID for the _UnderlayOffset shader property used by URP and HDRP shaders
|
||||
/// </summary>
|
||||
public static int ID_UnderlayOffset;
|
||||
|
||||
/// <summary>
|
||||
/// Property ID for the _UnderlayIsoPerimeter shader property used by URP and HDRP shaders
|
||||
/// </summary>
|
||||
public static int ID_UnderlayIsoPerimeter;
|
||||
|
||||
public static int ID_WeightNormal;
|
||||
public static int ID_WeightBold;
|
||||
|
||||
public static int ID_OutlineTex;
|
||||
public static int ID_OutlineWidth;
|
||||
public static int ID_OutlineSoftness;
|
||||
public static int ID_OutlineColor;
|
||||
|
||||
public static int ID_Outline2Color;
|
||||
public static int ID_Outline2Width;
|
||||
|
||||
public static int ID_Padding;
|
||||
public static int ID_GradientScale;
|
||||
public static int ID_ScaleX;
|
||||
public static int ID_ScaleY;
|
||||
public static int ID_PerspectiveFilter;
|
||||
public static int ID_Sharpness;
|
||||
|
||||
public static int ID_TextureWidth;
|
||||
public static int ID_TextureHeight;
|
||||
|
||||
public static int ID_BevelAmount;
|
||||
|
||||
public static int ID_GlowColor;
|
||||
public static int ID_GlowOffset;
|
||||
public static int ID_GlowPower;
|
||||
public static int ID_GlowOuter;
|
||||
public static int ID_GlowInner;
|
||||
|
||||
public static int ID_LightAngle;
|
||||
|
||||
public static int ID_EnvMap;
|
||||
public static int ID_EnvMatrix;
|
||||
public static int ID_EnvMatrixRotation;
|
||||
|
||||
//public static int ID_MaskID;
|
||||
public static int ID_MaskCoord;
|
||||
public static int ID_ClipRect;
|
||||
public static int ID_MaskSoftnessX;
|
||||
public static int ID_MaskSoftnessY;
|
||||
public static int ID_VertexOffsetX;
|
||||
public static int ID_VertexOffsetY;
|
||||
public static int ID_UseClipRect;
|
||||
|
||||
public static int ID_StencilID;
|
||||
public static int ID_StencilOp;
|
||||
public static int ID_StencilComp;
|
||||
public static int ID_StencilReadMask;
|
||||
public static int ID_StencilWriteMask;
|
||||
|
||||
public static int ID_ShaderFlags;
|
||||
public static int ID_ScaleRatio_A;
|
||||
public static int ID_ScaleRatio_B;
|
||||
public static int ID_ScaleRatio_C;
|
||||
|
||||
public static string Keyword_Bevel = "BEVEL_ON";
|
||||
public static string Keyword_Glow = "GLOW_ON";
|
||||
public static string Keyword_Underlay = "UNDERLAY_ON";
|
||||
public static string Keyword_Ratios = "RATIOS_OFF";
|
||||
//public static string Keyword_MASK_OFF = "MASK_OFF";
|
||||
public static string Keyword_MASK_SOFT = "MASK_SOFT";
|
||||
public static string Keyword_MASK_HARD = "MASK_HARD";
|
||||
public static string Keyword_MASK_TEX = "MASK_TEX";
|
||||
public static string Keyword_Outline = "OUTLINE_ON";
|
||||
|
||||
public static string ShaderTag_ZTestMode = "unity_GUIZTestMode";
|
||||
public static string ShaderTag_CullMode = "_CullMode";
|
||||
|
||||
private static float m_clamp = 1.0f;
|
||||
public static bool isInitialized = false;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Returns a reference to the mobile distance field shader.
|
||||
/// </summary>
|
||||
internal static Shader ShaderRef_MobileSDF
|
||||
{
|
||||
get
|
||||
{
|
||||
if (k_ShaderRef_MobileSDF == null)
|
||||
k_ShaderRef_MobileSDF = Shader.Find("TextMeshPro/Mobile/Distance Field");
|
||||
|
||||
return k_ShaderRef_MobileSDF;
|
||||
}
|
||||
}
|
||||
static Shader k_ShaderRef_MobileSDF;
|
||||
|
||||
/// <summary>
|
||||
/// Returns a reference to the mobile bitmap shader.
|
||||
/// </summary>
|
||||
internal static Shader ShaderRef_MobileBitmap
|
||||
{
|
||||
get
|
||||
{
|
||||
if (k_ShaderRef_MobileBitmap == null)
|
||||
k_ShaderRef_MobileBitmap = Shader.Find("TextMeshPro/Mobile/Bitmap");
|
||||
|
||||
return k_ShaderRef_MobileBitmap;
|
||||
}
|
||||
}
|
||||
static Shader k_ShaderRef_MobileBitmap;
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
static ShaderUtilities()
|
||||
{
|
||||
GetShaderPropertyIDs();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static void GetShaderPropertyIDs()
|
||||
{
|
||||
if (isInitialized == false)
|
||||
{
|
||||
//Debug.Log("Getting Shader property IDs");
|
||||
isInitialized = true;
|
||||
|
||||
ID_MainTex = Shader.PropertyToID("_MainTex");
|
||||
|
||||
ID_FaceTex = Shader.PropertyToID("_FaceTex");
|
||||
ID_FaceColor = Shader.PropertyToID("_FaceColor");
|
||||
ID_FaceDilate = Shader.PropertyToID("_FaceDilate");
|
||||
ID_Shininess = Shader.PropertyToID("_FaceShininess");
|
||||
|
||||
ID_UnderlayColor = Shader.PropertyToID("_UnderlayColor");
|
||||
ID_UnderlayOffsetX = Shader.PropertyToID("_UnderlayOffsetX");
|
||||
ID_UnderlayOffsetY = Shader.PropertyToID("_UnderlayOffsetY");
|
||||
ID_UnderlayDilate = Shader.PropertyToID("_UnderlayDilate");
|
||||
ID_UnderlaySoftness = Shader.PropertyToID("_UnderlaySoftness");
|
||||
|
||||
ID_UnderlayOffset = Shader.PropertyToID("_UnderlayOffset");
|
||||
ID_UnderlayIsoPerimeter = Shader.PropertyToID("_UnderlayIsoPerimeter");
|
||||
|
||||
ID_WeightNormal = Shader.PropertyToID("_WeightNormal");
|
||||
ID_WeightBold = Shader.PropertyToID("_WeightBold");
|
||||
|
||||
ID_OutlineTex = Shader.PropertyToID("_OutlineTex");
|
||||
ID_OutlineWidth = Shader.PropertyToID("_OutlineWidth");
|
||||
ID_OutlineSoftness = Shader.PropertyToID("_OutlineSoftness");
|
||||
ID_OutlineColor = Shader.PropertyToID("_OutlineColor");
|
||||
|
||||
ID_Outline2Color = Shader.PropertyToID("_Outline2Color");
|
||||
ID_Outline2Width = Shader.PropertyToID("_Outline2Width");
|
||||
|
||||
ID_Padding = Shader.PropertyToID("_Padding");
|
||||
ID_GradientScale = Shader.PropertyToID("_GradientScale");
|
||||
ID_ScaleX = Shader.PropertyToID("_ScaleX");
|
||||
ID_ScaleY = Shader.PropertyToID("_ScaleY");
|
||||
ID_PerspectiveFilter = Shader.PropertyToID("_PerspectiveFilter");
|
||||
ID_Sharpness = Shader.PropertyToID("_Sharpness");
|
||||
|
||||
ID_TextureWidth = Shader.PropertyToID("_TextureWidth");
|
||||
ID_TextureHeight = Shader.PropertyToID("_TextureHeight");
|
||||
|
||||
ID_BevelAmount = Shader.PropertyToID("_Bevel");
|
||||
|
||||
ID_LightAngle = Shader.PropertyToID("_LightAngle");
|
||||
|
||||
ID_EnvMap = Shader.PropertyToID("_Cube");
|
||||
ID_EnvMatrix = Shader.PropertyToID("_EnvMatrix");
|
||||
ID_EnvMatrixRotation = Shader.PropertyToID("_EnvMatrixRotation");
|
||||
|
||||
|
||||
ID_GlowColor = Shader.PropertyToID("_GlowColor");
|
||||
ID_GlowOffset = Shader.PropertyToID("_GlowOffset");
|
||||
ID_GlowPower = Shader.PropertyToID("_GlowPower");
|
||||
ID_GlowOuter = Shader.PropertyToID("_GlowOuter");
|
||||
ID_GlowInner = Shader.PropertyToID("_GlowInner");
|
||||
|
||||
//ID_MaskID = Shader.PropertyToID("_MaskID");
|
||||
ID_MaskCoord = Shader.PropertyToID("_MaskCoord");
|
||||
ID_ClipRect = Shader.PropertyToID("_ClipRect");
|
||||
ID_UseClipRect = Shader.PropertyToID("_UseClipRect");
|
||||
ID_MaskSoftnessX = Shader.PropertyToID("_MaskSoftnessX");
|
||||
ID_MaskSoftnessY = Shader.PropertyToID("_MaskSoftnessY");
|
||||
ID_VertexOffsetX = Shader.PropertyToID("_VertexOffsetX");
|
||||
ID_VertexOffsetY = Shader.PropertyToID("_VertexOffsetY");
|
||||
|
||||
ID_StencilID = Shader.PropertyToID("_Stencil");
|
||||
ID_StencilOp = Shader.PropertyToID("_StencilOp");
|
||||
ID_StencilComp = Shader.PropertyToID("_StencilComp");
|
||||
ID_StencilReadMask = Shader.PropertyToID("_StencilReadMask");
|
||||
ID_StencilWriteMask = Shader.PropertyToID("_StencilWriteMask");
|
||||
|
||||
ID_ShaderFlags = Shader.PropertyToID("_ShaderFlags");
|
||||
ID_ScaleRatio_A = Shader.PropertyToID("_ScaleRatioA");
|
||||
ID_ScaleRatio_B = Shader.PropertyToID("_ScaleRatioB");
|
||||
ID_ScaleRatio_C = Shader.PropertyToID("_ScaleRatioC");
|
||||
|
||||
// Set internal shader references
|
||||
if (k_ShaderRef_MobileSDF == null)
|
||||
k_ShaderRef_MobileSDF = Shader.Find("TextMeshPro/Mobile/Distance Field");
|
||||
|
||||
if (k_ShaderRef_MobileBitmap == null)
|
||||
k_ShaderRef_MobileBitmap = Shader.Find("TextMeshPro/Mobile/Bitmap");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Scale Ratios to ensure property ranges are optimum in Material Editor
|
||||
public static void UpdateShaderRatios(Material mat)
|
||||
{
|
||||
//Debug.Log("UpdateShaderRatios() called.");
|
||||
|
||||
float ratio_A = 1;
|
||||
float ratio_B = 1;
|
||||
float ratio_C = 1;
|
||||
|
||||
bool isRatioEnabled = !mat.shaderKeywords.Contains(Keyword_Ratios);
|
||||
|
||||
if (!mat.HasProperty(ID_GradientScale) || !mat.HasProperty(ID_FaceDilate))
|
||||
return;
|
||||
|
||||
// Compute Ratio A
|
||||
float scale = mat.GetFloat(ID_GradientScale);
|
||||
float faceDilate = mat.GetFloat(ID_FaceDilate);
|
||||
float outlineThickness = mat.GetFloat(ID_OutlineWidth);
|
||||
float outlineSoftness = mat.GetFloat(ID_OutlineSoftness);
|
||||
|
||||
float weight = Mathf.Max(mat.GetFloat(ID_WeightNormal), mat.GetFloat(ID_WeightBold)) / 4.0f;
|
||||
|
||||
float t = Mathf.Max(1, weight + faceDilate + outlineThickness + outlineSoftness);
|
||||
|
||||
ratio_A = isRatioEnabled ? (scale - m_clamp) / (scale * t) : 1;
|
||||
|
||||
//float ratio_A_old = mat.GetFloat(ID_ScaleRatio_A);
|
||||
|
||||
// Only set the ratio if it has changed.
|
||||
//if (ratio_A != ratio_A_old)
|
||||
mat.SetFloat(ID_ScaleRatio_A, ratio_A);
|
||||
|
||||
// Compute Ratio B
|
||||
if (mat.HasProperty(ID_GlowOffset))
|
||||
{
|
||||
float glowOffset = mat.GetFloat(ID_GlowOffset);
|
||||
float glowOuter = mat.GetFloat(ID_GlowOuter);
|
||||
|
||||
float range = (weight + faceDilate) * (scale - m_clamp);
|
||||
|
||||
t = Mathf.Max(1, glowOffset + glowOuter);
|
||||
|
||||
ratio_B = isRatioEnabled ? Mathf.Max(0, scale - m_clamp - range) / (scale * t) : 1;
|
||||
//float ratio_B_old = mat.GetFloat(ID_ScaleRatio_B);
|
||||
|
||||
// Only set the ratio if it has changed.
|
||||
//if (ratio_B != ratio_B_old)
|
||||
mat.SetFloat(ID_ScaleRatio_B, ratio_B);
|
||||
}
|
||||
|
||||
// Compute Ratio C
|
||||
if (mat.HasProperty(ID_UnderlayOffsetX))
|
||||
{
|
||||
float underlayOffsetX = mat.GetFloat(ID_UnderlayOffsetX);
|
||||
float underlayOffsetY = mat.GetFloat(ID_UnderlayOffsetY);
|
||||
float underlayDilate = mat.GetFloat(ID_UnderlayDilate);
|
||||
float underlaySoftness = mat.GetFloat(ID_UnderlaySoftness);
|
||||
|
||||
float range = (weight + faceDilate) * (scale - m_clamp);
|
||||
|
||||
t = Mathf.Max(1, Mathf.Max(Mathf.Abs(underlayOffsetX), Mathf.Abs(underlayOffsetY)) + underlayDilate + underlaySoftness);
|
||||
|
||||
ratio_C = isRatioEnabled ? Mathf.Max(0, scale - m_clamp - range) / (scale * t) : 1;
|
||||
//float ratio_C_old = mat.GetFloat(ID_ScaleRatio_C);
|
||||
|
||||
// Only set the ratio if it has changed.
|
||||
//if (ratio_C != ratio_C_old)
|
||||
mat.SetFloat(ID_ScaleRatio_C, ratio_C);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Function to calculate padding required for Outline Width & Dilation for proper text alignment
|
||||
public static Vector4 GetFontExtent(Material material)
|
||||
{
|
||||
// Revised implementation where style no longer affects alignment
|
||||
return Vector4.zero;
|
||||
|
||||
/*
|
||||
if (material == null || !material.HasProperty(ShaderUtilities.ID_GradientScale))
|
||||
return Vector4.zero; // We are using an non SDF Shader.
|
||||
|
||||
float scaleRatioA = material.GetFloat(ID_ScaleRatio_A);
|
||||
float faceDilate = material.GetFloat(ID_FaceDilate) * scaleRatioA;
|
||||
float outlineThickness = material.GetFloat(ID_OutlineWidth) * scaleRatioA;
|
||||
|
||||
float extent = Mathf.Min(1, faceDilate + outlineThickness);
|
||||
extent *= material.GetFloat(ID_GradientScale);
|
||||
|
||||
return new Vector4(extent, extent, extent, extent);
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
// Function to check if Masking is enabled
|
||||
public static bool IsMaskingEnabled(Material material)
|
||||
{
|
||||
if (material == null || !material.HasProperty(ShaderUtilities.ID_ClipRect))
|
||||
return false;
|
||||
|
||||
if (material.shaderKeywords.Contains(ShaderUtilities.Keyword_MASK_SOFT) || material.shaderKeywords.Contains(ShaderUtilities.Keyword_MASK_HARD) || material.shaderKeywords.Contains(ShaderUtilities.Keyword_MASK_TEX))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Function to determine how much extra padding is required as a result of material properties like dilate, outline thickness, softness, glow, etc...
|
||||
public static float GetPadding(Material material, bool enableExtraPadding, bool isBold)
|
||||
{
|
||||
//Debug.Log("GetPadding() called.");
|
||||
|
||||
if (isInitialized == false)
|
||||
GetShaderPropertyIDs();
|
||||
|
||||
// Return if Material is null
|
||||
if (material == null) return 0;
|
||||
|
||||
int extraPadding = enableExtraPadding ? 4 : 0;
|
||||
|
||||
// Check if we are using a non Distance Field Shader
|
||||
if (material.HasProperty(ID_GradientScale) == false)
|
||||
{
|
||||
if (material.HasProperty(ID_Padding))
|
||||
extraPadding += (int)material.GetFloat(ID_Padding);
|
||||
|
||||
return extraPadding + 1.0f;
|
||||
}
|
||||
|
||||
Vector4 padding = Vector4.zero;
|
||||
Vector4 maxPadding = Vector4.zero;
|
||||
|
||||
//float weight = 0;
|
||||
float faceDilate = 0;
|
||||
float faceSoftness = 0;
|
||||
float outlineThickness = 0;
|
||||
float scaleRatio_A = 0;
|
||||
float scaleRatio_B = 0;
|
||||
float scaleRatio_C = 0;
|
||||
|
||||
float glowOffset = 0;
|
||||
float glowOuter = 0;
|
||||
|
||||
float uniformPadding = 0;
|
||||
// Iterate through each of the assigned materials to find the max values to set the padding.
|
||||
|
||||
// Update Shader Ratios prior to computing padding
|
||||
UpdateShaderRatios(material);
|
||||
|
||||
string[] shaderKeywords = material.shaderKeywords;
|
||||
|
||||
if (material.HasProperty(ID_ScaleRatio_A))
|
||||
scaleRatio_A = material.GetFloat(ID_ScaleRatio_A);
|
||||
|
||||
//weight = 0; // Mathf.Max(material.GetFloat(ID_WeightNormal), material.GetFloat(ID_WeightBold)) / 2.0f * scaleRatio_A;
|
||||
|
||||
if (material.HasProperty(ID_FaceDilate))
|
||||
faceDilate = material.GetFloat(ID_FaceDilate) * scaleRatio_A;
|
||||
|
||||
if (material.HasProperty(ID_OutlineSoftness))
|
||||
faceSoftness = material.GetFloat(ID_OutlineSoftness) * scaleRatio_A;
|
||||
|
||||
if (material.HasProperty(ID_OutlineWidth))
|
||||
outlineThickness = material.GetFloat(ID_OutlineWidth) * scaleRatio_A;
|
||||
|
||||
uniformPadding = outlineThickness + faceSoftness + faceDilate;
|
||||
|
||||
// Glow padding contribution
|
||||
if (material.HasProperty(ID_GlowOffset) && shaderKeywords.Contains(Keyword_Glow)) // Generates GC
|
||||
{
|
||||
if (material.HasProperty(ID_ScaleRatio_B))
|
||||
scaleRatio_B = material.GetFloat(ID_ScaleRatio_B);
|
||||
|
||||
glowOffset = material.GetFloat(ID_GlowOffset) * scaleRatio_B;
|
||||
glowOuter = material.GetFloat(ID_GlowOuter) * scaleRatio_B;
|
||||
}
|
||||
|
||||
uniformPadding = Mathf.Max(uniformPadding, faceDilate + glowOffset + glowOuter);
|
||||
|
||||
// Underlay padding contribution
|
||||
if (material.HasProperty(ID_UnderlaySoftness) && shaderKeywords.Contains(Keyword_Underlay)) // Generates GC
|
||||
{
|
||||
if (material.HasProperty(ID_ScaleRatio_C))
|
||||
scaleRatio_C = material.GetFloat(ID_ScaleRatio_C);
|
||||
|
||||
float offsetX = 0;
|
||||
float offsetY = 0;
|
||||
float dilate = 0;
|
||||
float softness = 0;
|
||||
|
||||
if (material.HasProperty(ID_UnderlayOffset))
|
||||
{
|
||||
Vector2 underlayOffset = material.GetVector(ID_UnderlayOffset);
|
||||
offsetX = underlayOffset.x;
|
||||
offsetY = underlayOffset.y;
|
||||
|
||||
dilate = material.GetFloat(ID_UnderlayIsoPerimeter);
|
||||
softness = material.GetFloat(ID_UnderlaySoftness);
|
||||
}
|
||||
else if (material.HasProperty(ID_UnderlayOffsetX))
|
||||
{
|
||||
|
||||
offsetX = material.GetFloat(ID_UnderlayOffsetX) * scaleRatio_C;
|
||||
offsetY = material.GetFloat(ID_UnderlayOffsetY) * scaleRatio_C;
|
||||
dilate = material.GetFloat(ID_UnderlayDilate) * scaleRatio_C;
|
||||
softness = material.GetFloat(ID_UnderlaySoftness) * scaleRatio_C;
|
||||
}
|
||||
|
||||
padding.x = Mathf.Max(padding.x, faceDilate + dilate + softness - offsetX);
|
||||
padding.y = Mathf.Max(padding.y, faceDilate + dilate + softness - offsetY);
|
||||
padding.z = Mathf.Max(padding.z, faceDilate + dilate + softness + offsetX);
|
||||
padding.w = Mathf.Max(padding.w, faceDilate + dilate + softness + offsetY);
|
||||
}
|
||||
|
||||
padding.x = Mathf.Max(padding.x, uniformPadding);
|
||||
padding.y = Mathf.Max(padding.y, uniformPadding);
|
||||
padding.z = Mathf.Max(padding.z, uniformPadding);
|
||||
padding.w = Mathf.Max(padding.w, uniformPadding);
|
||||
|
||||
padding.x += extraPadding;
|
||||
padding.y += extraPadding;
|
||||
padding.z += extraPadding;
|
||||
padding.w += extraPadding;
|
||||
|
||||
padding.x = Mathf.Min(padding.x, 1);
|
||||
padding.y = Mathf.Min(padding.y, 1);
|
||||
padding.z = Mathf.Min(padding.z, 1);
|
||||
padding.w = Mathf.Min(padding.w, 1);
|
||||
|
||||
maxPadding.x = maxPadding.x < padding.x ? padding.x : maxPadding.x;
|
||||
maxPadding.y = maxPadding.y < padding.y ? padding.y : maxPadding.y;
|
||||
maxPadding.z = maxPadding.z < padding.z ? padding.z : maxPadding.z;
|
||||
maxPadding.w = maxPadding.w < padding.w ? padding.w : maxPadding.w;
|
||||
|
||||
float gradientScale = material.GetFloat(ID_GradientScale);
|
||||
padding *= gradientScale;
|
||||
|
||||
// Set UniformPadding to the maximum value of any of its components.
|
||||
uniformPadding = Mathf.Max(padding.x, padding.y);
|
||||
uniformPadding = Mathf.Max(padding.z, uniformPadding);
|
||||
uniformPadding = Mathf.Max(padding.w, uniformPadding);
|
||||
|
||||
return uniformPadding + 1.25f;
|
||||
}
|
||||
|
||||
|
||||
// Function to determine how much extra padding is required as a result of material properties like dilate, outline thickness, softness, glow, etc...
|
||||
public static float GetPadding(Material[] materials, bool enableExtraPadding, bool isBold)
|
||||
{
|
||||
//Debug.Log("GetPadding() called.");
|
||||
|
||||
if (isInitialized == false)
|
||||
GetShaderPropertyIDs();
|
||||
|
||||
// Return if Material is null
|
||||
if (materials == null) return 0;
|
||||
|
||||
int extraPadding = enableExtraPadding ? 4 : 0;
|
||||
|
||||
// Check if we are using a Bitmap Shader
|
||||
if (materials[0].HasProperty(ID_Padding))
|
||||
return extraPadding + materials[0].GetFloat(ID_Padding);
|
||||
|
||||
Vector4 padding = Vector4.zero;
|
||||
Vector4 maxPadding = Vector4.zero;
|
||||
|
||||
float faceDilate = 0;
|
||||
float faceSoftness = 0;
|
||||
float outlineThickness = 0;
|
||||
float scaleRatio_A = 0;
|
||||
float scaleRatio_B = 0;
|
||||
float scaleRatio_C = 0;
|
||||
|
||||
float glowOffset = 0;
|
||||
float glowOuter = 0;
|
||||
|
||||
float uniformPadding = 0;
|
||||
// Iterate through each of the assigned materials to find the max values to set the padding.
|
||||
for (int i = 0; i < materials.Length; i++)
|
||||
{
|
||||
// Update Shader Ratios prior to computing padding
|
||||
ShaderUtilities.UpdateShaderRatios(materials[i]);
|
||||
|
||||
string[] shaderKeywords = materials[i].shaderKeywords;
|
||||
|
||||
if (materials[i].HasProperty(ShaderUtilities.ID_ScaleRatio_A))
|
||||
scaleRatio_A = materials[i].GetFloat(ShaderUtilities.ID_ScaleRatio_A);
|
||||
|
||||
if (materials[i].HasProperty(ShaderUtilities.ID_FaceDilate))
|
||||
faceDilate = materials[i].GetFloat(ShaderUtilities.ID_FaceDilate) * scaleRatio_A;
|
||||
|
||||
if (materials[i].HasProperty(ShaderUtilities.ID_OutlineSoftness))
|
||||
faceSoftness = materials[i].GetFloat(ShaderUtilities.ID_OutlineSoftness) * scaleRatio_A;
|
||||
|
||||
if (materials[i].HasProperty(ShaderUtilities.ID_OutlineWidth))
|
||||
outlineThickness = materials[i].GetFloat(ShaderUtilities.ID_OutlineWidth) * scaleRatio_A;
|
||||
|
||||
uniformPadding = outlineThickness + faceSoftness + faceDilate;
|
||||
|
||||
// Glow padding contribution
|
||||
if (materials[i].HasProperty(ShaderUtilities.ID_GlowOffset) && shaderKeywords.Contains(ShaderUtilities.Keyword_Glow))
|
||||
{
|
||||
if (materials[i].HasProperty(ShaderUtilities.ID_ScaleRatio_B))
|
||||
scaleRatio_B = materials[i].GetFloat(ShaderUtilities.ID_ScaleRatio_B);
|
||||
|
||||
glowOffset = materials[i].GetFloat(ShaderUtilities.ID_GlowOffset) * scaleRatio_B;
|
||||
glowOuter = materials[i].GetFloat(ShaderUtilities.ID_GlowOuter) * scaleRatio_B;
|
||||
}
|
||||
|
||||
uniformPadding = Mathf.Max(uniformPadding, faceDilate + glowOffset + glowOuter);
|
||||
|
||||
// Underlay padding contribution
|
||||
if (materials[i].HasProperty(ShaderUtilities.ID_UnderlaySoftness) && shaderKeywords.Contains(ShaderUtilities.Keyword_Underlay))
|
||||
{
|
||||
if (materials[i].HasProperty(ShaderUtilities.ID_ScaleRatio_C))
|
||||
scaleRatio_C = materials[i].GetFloat(ShaderUtilities.ID_ScaleRatio_C);
|
||||
|
||||
float offsetX = materials[i].GetFloat(ShaderUtilities.ID_UnderlayOffsetX) * scaleRatio_C;
|
||||
float offsetY = materials[i].GetFloat(ShaderUtilities.ID_UnderlayOffsetY) * scaleRatio_C;
|
||||
float dilate = materials[i].GetFloat(ShaderUtilities.ID_UnderlayDilate) * scaleRatio_C;
|
||||
float softness = materials[i].GetFloat(ShaderUtilities.ID_UnderlaySoftness) * scaleRatio_C;
|
||||
|
||||
padding.x = Mathf.Max(padding.x, faceDilate + dilate + softness - offsetX);
|
||||
padding.y = Mathf.Max(padding.y, faceDilate + dilate + softness - offsetY);
|
||||
padding.z = Mathf.Max(padding.z, faceDilate + dilate + softness + offsetX);
|
||||
padding.w = Mathf.Max(padding.w, faceDilate + dilate + softness + offsetY);
|
||||
}
|
||||
|
||||
padding.x = Mathf.Max(padding.x, uniformPadding);
|
||||
padding.y = Mathf.Max(padding.y, uniformPadding);
|
||||
padding.z = Mathf.Max(padding.z, uniformPadding);
|
||||
padding.w = Mathf.Max(padding.w, uniformPadding);
|
||||
|
||||
padding.x += extraPadding;
|
||||
padding.y += extraPadding;
|
||||
padding.z += extraPadding;
|
||||
padding.w += extraPadding;
|
||||
|
||||
padding.x = Mathf.Min(padding.x, 1);
|
||||
padding.y = Mathf.Min(padding.y, 1);
|
||||
padding.z = Mathf.Min(padding.z, 1);
|
||||
padding.w = Mathf.Min(padding.w, 1);
|
||||
|
||||
maxPadding.x = maxPadding.x < padding.x ? padding.x : maxPadding.x;
|
||||
maxPadding.y = maxPadding.y < padding.y ? padding.y : maxPadding.y;
|
||||
maxPadding.z = maxPadding.z < padding.z ? padding.z : maxPadding.z;
|
||||
maxPadding.w = maxPadding.w < padding.w ? padding.w : maxPadding.w;
|
||||
|
||||
}
|
||||
|
||||
float gradientScale = materials[0].GetFloat(ShaderUtilities.ID_GradientScale);
|
||||
padding *= gradientScale;
|
||||
|
||||
// Set UniformPadding to the maximum value of any of its components.
|
||||
uniformPadding = Mathf.Max(padding.x, padding.y);
|
||||
uniformPadding = Mathf.Max(padding.z, uniformPadding);
|
||||
uniformPadding = Mathf.Max(padding.w, uniformPadding);
|
||||
|
||||
return uniformPadding + 0.25f;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
fileFormatVersion: 2
|
||||
guid: fea49a0730244a98bf1087f7ca9410a8
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,31 @@
|
|||
using UnityEngine;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
|
||||
namespace TMPro
|
||||
{
|
||||
|
||||
// Class which contains the Sprite Info for each sprite contained in the sprite asset.
|
||||
[Serializable]
|
||||
public class TMP_Sprite : TMP_TextElement_Legacy
|
||||
{
|
||||
//public int fileID;
|
||||
//public int id;
|
||||
public string name;
|
||||
public int hashCode;
|
||||
public int unicode;
|
||||
//public float x;
|
||||
//public float y;
|
||||
//public float width;
|
||||
//public float height;
|
||||
public Vector2 pivot;
|
||||
//public float xOffset; // Pivot X
|
||||
//public float yOffset; // Pivot Y
|
||||
//public float xAdvance;
|
||||
//public float scale;
|
||||
|
||||
public Sprite sprite;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 968a09f153574430a6e15ae975145768
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,157 @@
|
|||
using UnityEngine;
|
||||
using UnityEngine.TextCore;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace TMPro
|
||||
{
|
||||
[DisallowMultipleComponent]
|
||||
public class TMP_SpriteAnimator : MonoBehaviour
|
||||
{
|
||||
private Dictionary<int, bool> m_animations = new Dictionary<int, bool>(16);
|
||||
//private bool isPlaying = false;
|
||||
|
||||
private TMP_Text m_TextComponent;
|
||||
|
||||
|
||||
void Awake()
|
||||
{
|
||||
m_TextComponent = GetComponent<TMP_Text>();
|
||||
}
|
||||
|
||||
|
||||
void OnEnable()
|
||||
{
|
||||
//m_playAnimations = true;
|
||||
}
|
||||
|
||||
|
||||
void OnDisable()
|
||||
{
|
||||
//m_playAnimations = false;
|
||||
}
|
||||
|
||||
|
||||
public void StopAllAnimations()
|
||||
{
|
||||
StopAllCoroutines();
|
||||
m_animations.Clear();
|
||||
}
|
||||
|
||||
|
||||
public void DoSpriteAnimation(int currentCharacter, TMP_SpriteAsset spriteAsset, int start, int end, int framerate)
|
||||
{
|
||||
bool isPlaying;
|
||||
|
||||
// Need to add tracking of coroutines that have been lunched for this text object.
|
||||
if (!m_animations.TryGetValue(currentCharacter, out isPlaying))
|
||||
{
|
||||
StartCoroutine(DoSpriteAnimationInternal(currentCharacter, spriteAsset, start, end, framerate));
|
||||
m_animations.Add(currentCharacter, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
IEnumerator DoSpriteAnimationInternal(int currentCharacter, TMP_SpriteAsset spriteAsset, int start, int end, int framerate)
|
||||
{
|
||||
if (m_TextComponent == null) yield break;
|
||||
|
||||
// We yield otherwise this gets called before the sprite has rendered.
|
||||
yield return null;
|
||||
|
||||
int currentFrame = start;
|
||||
|
||||
// Make sure end frame does not exceed the number of sprites in the sprite asset.
|
||||
if (end > spriteAsset.spriteCharacterTable.Count)
|
||||
end = spriteAsset.spriteCharacterTable.Count - 1;
|
||||
|
||||
// Get a reference to the current character's info
|
||||
TMP_CharacterInfo charInfo = m_TextComponent.textInfo.characterInfo[currentCharacter];
|
||||
|
||||
int materialIndex = charInfo.materialReferenceIndex;
|
||||
int vertexIndex = charInfo.vertexIndex;
|
||||
|
||||
TMP_MeshInfo meshInfo = m_TextComponent.textInfo.meshInfo[materialIndex];
|
||||
|
||||
float baseSpriteScale = spriteAsset.spriteCharacterTable[start].scale * spriteAsset.spriteCharacterTable[start].glyph.scale;
|
||||
|
||||
float elapsedTime = 0;
|
||||
float targetTime = 1f / Mathf.Abs(framerate);
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (elapsedTime > targetTime)
|
||||
{
|
||||
elapsedTime = 0;
|
||||
|
||||
// Return if sprite was truncated or replaced by the Ellipsis character.
|
||||
char character = m_TextComponent.textInfo.characterInfo[currentCharacter].character;
|
||||
if (character == 0x03 || character == 0x2026)
|
||||
{
|
||||
m_animations.Remove(currentCharacter);
|
||||
yield break;
|
||||
}
|
||||
|
||||
// Get a reference to the current sprite
|
||||
TMP_SpriteCharacter spriteCharacter = spriteAsset.spriteCharacterTable[currentFrame];
|
||||
|
||||
// Update the vertices for the new sprite
|
||||
Vector3[] vertices = meshInfo.vertices;
|
||||
|
||||
Vector2 origin = new Vector2(charInfo.origin, charInfo.baseLine);
|
||||
|
||||
float spriteScale = charInfo.scale / baseSpriteScale * spriteCharacter.scale * spriteCharacter.glyph.scale;
|
||||
|
||||
Vector3 bl = new Vector3(origin.x + spriteCharacter.glyph.metrics.horizontalBearingX * spriteScale, origin.y + (spriteCharacter.glyph.metrics.horizontalBearingY - spriteCharacter.glyph.metrics.height) * spriteScale);
|
||||
Vector3 tl = new Vector3(bl.x, origin.y + spriteCharacter.glyph.metrics.horizontalBearingY * spriteScale);
|
||||
Vector3 tr = new Vector3(origin.x + (spriteCharacter.glyph.metrics.horizontalBearingX + spriteCharacter.glyph.metrics.width) * spriteScale, tl.y);
|
||||
Vector3 br = new Vector3(tr.x, bl.y);
|
||||
|
||||
vertices[vertexIndex + 0] = bl;
|
||||
vertices[vertexIndex + 1] = tl;
|
||||
vertices[vertexIndex + 2] = tr;
|
||||
vertices[vertexIndex + 3] = br;
|
||||
|
||||
// Update the UV to point to the new sprite
|
||||
Vector2[] uvs0 = meshInfo.uvs0;
|
||||
|
||||
Vector2 uv0 = new Vector2((float)spriteCharacter.glyph.glyphRect.x / spriteAsset.spriteSheet.width, (float)spriteCharacter.glyph.glyphRect.y / spriteAsset.spriteSheet.height);
|
||||
Vector2 uv1 = new Vector2(uv0.x, (float)(spriteCharacter.glyph.glyphRect.y + spriteCharacter.glyph.glyphRect.height) / spriteAsset.spriteSheet.height);
|
||||
Vector2 uv2 = new Vector2((float)(spriteCharacter.glyph.glyphRect.x + spriteCharacter.glyph.glyphRect.width) / spriteAsset.spriteSheet.width, uv1.y);
|
||||
Vector2 uv3 = new Vector2(uv2.x, uv0.y);
|
||||
|
||||
uvs0[vertexIndex + 0] = uv0;
|
||||
uvs0[vertexIndex + 1] = uv1;
|
||||
uvs0[vertexIndex + 2] = uv2;
|
||||
uvs0[vertexIndex + 3] = uv3;
|
||||
|
||||
// Update the modified vertex attributes
|
||||
meshInfo.mesh.vertices = vertices;
|
||||
meshInfo.mesh.uv = uvs0;
|
||||
m_TextComponent.UpdateGeometry(meshInfo.mesh, materialIndex);
|
||||
|
||||
|
||||
if (framerate > 0)
|
||||
{
|
||||
if (currentFrame < end)
|
||||
currentFrame += 1;
|
||||
else
|
||||
currentFrame = start;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (currentFrame > start)
|
||||
currentFrame -= 1;
|
||||
else
|
||||
currentFrame = end;
|
||||
}
|
||||
}
|
||||
|
||||
elapsedTime += Time.deltaTime;
|
||||
|
||||
yield return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 6366ee97f6b541449155028b9487355a
|
||||
timeCreated: 1471590333
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,587 @@
|
|||
using UnityEngine;
|
||||
using UnityEngine.TextCore;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
|
||||
namespace TMPro
|
||||
{
|
||||
[ExcludeFromPresetAttribute]
|
||||
public class TMP_SpriteAsset : TMP_Asset
|
||||
{
|
||||
internal Dictionary<int, int> m_NameLookup;
|
||||
internal Dictionary<uint, int> m_GlyphIndexLookup;
|
||||
|
||||
/// <summary>
|
||||
/// The version of the sprite asset class.
|
||||
/// Version 1.1.0 updates the asset data structure to be compatible with new font asset structure.
|
||||
/// </summary>
|
||||
public string version
|
||||
{
|
||||
get { return m_Version; }
|
||||
internal set { m_Version = value; }
|
||||
}
|
||||
[SerializeField]
|
||||
private string m_Version;
|
||||
|
||||
/// <summary>
|
||||
/// Information about the sprite asset's face.
|
||||
/// </summary>
|
||||
public FaceInfo faceInfo
|
||||
{
|
||||
get { return m_FaceInfo; }
|
||||
internal set { m_FaceInfo = value; }
|
||||
}
|
||||
[SerializeField]
|
||||
internal FaceInfo m_FaceInfo;
|
||||
|
||||
// The texture which contains the sprites.
|
||||
public Texture spriteSheet;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public List<TMP_SpriteCharacter> spriteCharacterTable
|
||||
{
|
||||
get
|
||||
{
|
||||
if (m_GlyphIndexLookup == null)
|
||||
UpdateLookupTables();
|
||||
|
||||
return m_SpriteCharacterTable;
|
||||
}
|
||||
internal set { m_SpriteCharacterTable = value; }
|
||||
}
|
||||
[SerializeField]
|
||||
private List<TMP_SpriteCharacter> m_SpriteCharacterTable = new List<TMP_SpriteCharacter>();
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Dictionary used to lookup sprite characters by their unicode value.
|
||||
/// </summary>
|
||||
public Dictionary<uint, TMP_SpriteCharacter> spriteCharacterLookupTable
|
||||
{
|
||||
get
|
||||
{
|
||||
if (m_SpriteCharacterLookup == null)
|
||||
UpdateLookupTables();
|
||||
|
||||
return m_SpriteCharacterLookup;
|
||||
}
|
||||
internal set { m_SpriteCharacterLookup = value; }
|
||||
}
|
||||
internal Dictionary<uint, TMP_SpriteCharacter> m_SpriteCharacterLookup;
|
||||
|
||||
public List<TMP_SpriteGlyph> spriteGlyphTable
|
||||
{
|
||||
get { return m_SpriteGlyphTable; }
|
||||
internal set { m_SpriteGlyphTable = value; }
|
||||
}
|
||||
[SerializeField]
|
||||
private List<TMP_SpriteGlyph> m_SpriteGlyphTable = new List<TMP_SpriteGlyph>();
|
||||
|
||||
internal Dictionary<uint, TMP_SpriteGlyph> m_SpriteGlyphLookup;
|
||||
|
||||
// List which contains the SpriteInfo for the sprites contained in the sprite sheet.
|
||||
public List<TMP_Sprite> spriteInfoList;
|
||||
|
||||
/// <summary>
|
||||
/// List which contains the Fallback font assets for this font.
|
||||
/// </summary>
|
||||
[SerializeField]
|
||||
public List<TMP_SpriteAsset> fallbackSpriteAssets;
|
||||
|
||||
internal bool m_IsSpriteAssetLookupTablesDirty = false;
|
||||
|
||||
|
||||
void Awake()
|
||||
{
|
||||
// Check version number of sprite asset to see if it needs to be upgraded.
|
||||
if (this.material != null && string.IsNullOrEmpty(m_Version))
|
||||
UpgradeSpriteAsset();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Create a material for the sprite asset.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
Material GetDefaultSpriteMaterial()
|
||||
{
|
||||
//isEditingAsset = true;
|
||||
ShaderUtilities.GetShaderPropertyIDs();
|
||||
|
||||
// Add a new material
|
||||
Shader shader = Shader.Find("TextMeshPro/Sprite");
|
||||
Material tempMaterial = new Material(shader);
|
||||
tempMaterial.SetTexture(ShaderUtilities.ID_MainTex, spriteSheet);
|
||||
tempMaterial.hideFlags = HideFlags.HideInHierarchy;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
UnityEditor.AssetDatabase.AddObjectToAsset(tempMaterial, this);
|
||||
UnityEditor.AssetDatabase.ImportAsset(UnityEditor.AssetDatabase.GetAssetPath(this));
|
||||
#endif
|
||||
//isEditingAsset = false;
|
||||
|
||||
return tempMaterial;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function to update the sprite name and unicode lookup tables.
|
||||
/// This function should be called when a sprite's name or unicode value changes or when a new sprite is added.
|
||||
/// </summary>
|
||||
public void UpdateLookupTables()
|
||||
{
|
||||
//Debug.Log("Updating [" + this.name + "] Lookup tables.");
|
||||
|
||||
// Check version number of sprite asset to see if it needs to be upgraded.
|
||||
if (this.material != null && string.IsNullOrEmpty(m_Version))
|
||||
UpgradeSpriteAsset();
|
||||
|
||||
// Initialize / Clear glyph index lookup dictionary.
|
||||
if (m_GlyphIndexLookup == null)
|
||||
m_GlyphIndexLookup = new Dictionary<uint, int>();
|
||||
else
|
||||
m_GlyphIndexLookup.Clear();
|
||||
|
||||
//
|
||||
if (m_SpriteGlyphLookup == null)
|
||||
m_SpriteGlyphLookup = new Dictionary<uint, TMP_SpriteGlyph>();
|
||||
else
|
||||
m_SpriteGlyphLookup.Clear();
|
||||
|
||||
// Initialize SpriteGlyphLookup
|
||||
for (int i = 0; i < m_SpriteGlyphTable.Count; i++)
|
||||
{
|
||||
TMP_SpriteGlyph spriteGlyph = m_SpriteGlyphTable[i];
|
||||
uint glyphIndex = spriteGlyph.index;
|
||||
|
||||
if (m_GlyphIndexLookup.ContainsKey(glyphIndex) == false)
|
||||
m_GlyphIndexLookup.Add(glyphIndex, i);
|
||||
|
||||
if (m_SpriteGlyphLookup.ContainsKey(glyphIndex) == false)
|
||||
m_SpriteGlyphLookup.Add(glyphIndex, spriteGlyph);
|
||||
}
|
||||
|
||||
// Initialize name lookup
|
||||
if (m_NameLookup == null)
|
||||
m_NameLookup = new Dictionary<int, int>();
|
||||
else
|
||||
m_NameLookup.Clear();
|
||||
|
||||
|
||||
// Initialize character lookup
|
||||
if (m_SpriteCharacterLookup == null)
|
||||
m_SpriteCharacterLookup = new Dictionary<uint, TMP_SpriteCharacter>();
|
||||
else
|
||||
m_SpriteCharacterLookup.Clear();
|
||||
|
||||
|
||||
// Populate Sprite Character lookup tables
|
||||
for (int i = 0; i < m_SpriteCharacterTable.Count; i++)
|
||||
{
|
||||
TMP_SpriteCharacter spriteCharacter = m_SpriteCharacterTable[i];
|
||||
|
||||
// Make sure sprite character is valid
|
||||
if (spriteCharacter == null)
|
||||
continue;
|
||||
|
||||
uint glyphIndex = spriteCharacter.glyphIndex;
|
||||
|
||||
// Lookup the glyph for this character
|
||||
if (m_SpriteGlyphLookup.ContainsKey(glyphIndex) == false)
|
||||
continue;
|
||||
|
||||
// Assign glyph and text asset to this character
|
||||
spriteCharacter.glyph = m_SpriteGlyphLookup[glyphIndex];
|
||||
spriteCharacter.textAsset = this;
|
||||
|
||||
int nameHashCode = m_SpriteCharacterTable[i].hashCode;
|
||||
|
||||
if (m_NameLookup.ContainsKey(nameHashCode) == false)
|
||||
m_NameLookup.Add(nameHashCode, i);
|
||||
|
||||
uint unicode = m_SpriteCharacterTable[i].unicode;
|
||||
|
||||
if (unicode != 0xFFFE && m_SpriteCharacterLookup.ContainsKey(unicode) == false)
|
||||
m_SpriteCharacterLookup.Add(unicode, spriteCharacter);
|
||||
}
|
||||
|
||||
m_IsSpriteAssetLookupTablesDirty = false;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function which returns the sprite index using the hashcode of the name
|
||||
/// </summary>
|
||||
/// <param name="hashCode"></param>
|
||||
/// <returns></returns>
|
||||
public int GetSpriteIndexFromHashcode(int hashCode)
|
||||
{
|
||||
if (m_NameLookup == null)
|
||||
UpdateLookupTables();
|
||||
|
||||
int index;
|
||||
|
||||
if (m_NameLookup.TryGetValue(hashCode, out index))
|
||||
return index;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Returns the index of the sprite for the given unicode value.
|
||||
/// </summary>
|
||||
/// <param name="unicode"></param>
|
||||
/// <returns></returns>
|
||||
public int GetSpriteIndexFromUnicode (uint unicode)
|
||||
{
|
||||
if (m_SpriteCharacterLookup == null)
|
||||
UpdateLookupTables();
|
||||
|
||||
TMP_SpriteCharacter spriteCharacter;
|
||||
|
||||
if (m_SpriteCharacterLookup.TryGetValue(unicode, out spriteCharacter))
|
||||
return (int)spriteCharacter.glyphIndex;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Returns the index of the sprite for the given name.
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <returns></returns>
|
||||
public int GetSpriteIndexFromName (string name)
|
||||
{
|
||||
if (m_NameLookup == null)
|
||||
UpdateLookupTables();
|
||||
|
||||
int hashCode = TMP_TextUtilities.GetSimpleHashCode(name);
|
||||
|
||||
return GetSpriteIndexFromHashcode(hashCode);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Used to keep track of which Sprite Assets have been searched.
|
||||
/// </summary>
|
||||
private static HashSet<int> k_searchedSpriteAssets;
|
||||
|
||||
/// <summary>
|
||||
/// Search through the given sprite asset and its fallbacks for the specified sprite matching the given unicode character.
|
||||
/// </summary>
|
||||
/// <param name="spriteAsset">The font asset to search for the given character.</param>
|
||||
/// <param name="unicode">The character to find.</param>
|
||||
/// <param name="glyph">out parameter containing the glyph for the specified character (if found).</param>
|
||||
/// <returns></returns>
|
||||
public static TMP_SpriteAsset SearchForSpriteByUnicode(TMP_SpriteAsset spriteAsset, uint unicode, bool includeFallbacks, out int spriteIndex)
|
||||
{
|
||||
// Check to make sure sprite asset is not null
|
||||
if (spriteAsset == null) { spriteIndex = -1; return null; }
|
||||
|
||||
// Get sprite index for the given unicode
|
||||
spriteIndex = spriteAsset.GetSpriteIndexFromUnicode(unicode);
|
||||
if (spriteIndex != -1)
|
||||
return spriteAsset;
|
||||
|
||||
// Initialize list to track instance of Sprite Assets that have already been searched.
|
||||
if (k_searchedSpriteAssets == null)
|
||||
k_searchedSpriteAssets = new HashSet<int>();
|
||||
else
|
||||
k_searchedSpriteAssets.Clear();
|
||||
|
||||
// Get instance ID of sprite asset and add to list.
|
||||
int id = spriteAsset.GetInstanceID();
|
||||
k_searchedSpriteAssets.Add(id);
|
||||
|
||||
// Search potential fallback sprite assets if includeFallbacks is true.
|
||||
if (includeFallbacks && spriteAsset.fallbackSpriteAssets != null && spriteAsset.fallbackSpriteAssets.Count > 0)
|
||||
return SearchForSpriteByUnicodeInternal(spriteAsset.fallbackSpriteAssets, unicode, true, out spriteIndex);
|
||||
|
||||
// Search default sprite asset potentially assigned in the TMP Settings.
|
||||
if (includeFallbacks && TMP_Settings.defaultSpriteAsset != null)
|
||||
return SearchForSpriteByUnicodeInternal(TMP_Settings.defaultSpriteAsset, unicode, true, out spriteIndex);
|
||||
|
||||
spriteIndex = -1;
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Search through the given list of sprite assets and fallbacks for a sprite whose unicode value matches the target unicode.
|
||||
/// </summary>
|
||||
/// <param name="spriteAssets"></param>
|
||||
/// <param name="unicode"></param>
|
||||
/// <param name="includeFallbacks"></param>
|
||||
/// <param name="spriteIndex"></param>
|
||||
/// <returns></returns>
|
||||
private static TMP_SpriteAsset SearchForSpriteByUnicodeInternal(List<TMP_SpriteAsset> spriteAssets, uint unicode, bool includeFallbacks, out int spriteIndex)
|
||||
{
|
||||
for (int i = 0; i < spriteAssets.Count; i++)
|
||||
{
|
||||
TMP_SpriteAsset temp = spriteAssets[i];
|
||||
if (temp == null) continue;
|
||||
|
||||
int id = temp.GetInstanceID();
|
||||
|
||||
// Skip sprite asset if it has already been searched.
|
||||
if (k_searchedSpriteAssets.Add(id) == false)
|
||||
continue;
|
||||
|
||||
temp = SearchForSpriteByUnicodeInternal(temp, unicode, includeFallbacks, out spriteIndex);
|
||||
|
||||
if (temp != null)
|
||||
return temp;
|
||||
}
|
||||
|
||||
spriteIndex = -1;
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Search the given sprite asset and fallbacks for a sprite whose unicode value matches the target unicode.
|
||||
/// </summary>
|
||||
/// <param name="spriteAsset"></param>
|
||||
/// <param name="unicode"></param>
|
||||
/// <param name="includeFallbacks"></param>
|
||||
/// <param name="spriteIndex"></param>
|
||||
/// <returns></returns>
|
||||
private static TMP_SpriteAsset SearchForSpriteByUnicodeInternal(TMP_SpriteAsset spriteAsset, uint unicode, bool includeFallbacks, out int spriteIndex)
|
||||
{
|
||||
// Get sprite index for the given unicode
|
||||
spriteIndex = spriteAsset.GetSpriteIndexFromUnicode(unicode);
|
||||
|
||||
if (spriteIndex != -1)
|
||||
return spriteAsset;
|
||||
|
||||
if (includeFallbacks && spriteAsset.fallbackSpriteAssets != null && spriteAsset.fallbackSpriteAssets.Count > 0)
|
||||
return SearchForSpriteByUnicodeInternal(spriteAsset.fallbackSpriteAssets, unicode, true, out spriteIndex);
|
||||
|
||||
spriteIndex = -1;
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Search the given sprite asset and fallbacks for a sprite whose hash code value of its name matches the target hash code.
|
||||
/// </summary>
|
||||
/// <param name="spriteAsset">The Sprite Asset to search for the given sprite whose name matches the hashcode value</param>
|
||||
/// <param name="hashCode">The hash code value matching the name of the sprite</param>
|
||||
/// <param name="includeFallbacks">Include fallback sprite assets in the search</param>
|
||||
/// <param name="spriteIndex">The index of the sprite matching the provided hash code</param>
|
||||
/// <returns>The Sprite Asset that contains the sprite</returns>
|
||||
public static TMP_SpriteAsset SearchForSpriteByHashCode(TMP_SpriteAsset spriteAsset, int hashCode, bool includeFallbacks, out int spriteIndex)
|
||||
{
|
||||
// Make sure sprite asset is not null
|
||||
if (spriteAsset == null) { spriteIndex = -1; return null; }
|
||||
|
||||
spriteIndex = spriteAsset.GetSpriteIndexFromHashcode(hashCode);
|
||||
if (spriteIndex != -1)
|
||||
return spriteAsset;
|
||||
|
||||
// Initialize or clear list to Sprite Assets that have already been searched.
|
||||
if (k_searchedSpriteAssets == null)
|
||||
k_searchedSpriteAssets = new HashSet<int>();
|
||||
else
|
||||
k_searchedSpriteAssets.Clear();
|
||||
|
||||
int id = spriteAsset.instanceID;
|
||||
|
||||
// Add to list of font assets already searched.
|
||||
k_searchedSpriteAssets.Add(id);
|
||||
|
||||
TMP_SpriteAsset tempSpriteAsset;
|
||||
|
||||
// Search potential fallbacks assigned to local sprite asset.
|
||||
if (includeFallbacks && spriteAsset.fallbackSpriteAssets != null && spriteAsset.fallbackSpriteAssets.Count > 0)
|
||||
{
|
||||
tempSpriteAsset = SearchForSpriteByHashCodeInternal(spriteAsset.fallbackSpriteAssets, hashCode, true, out spriteIndex);
|
||||
|
||||
if (spriteIndex != -1)
|
||||
return tempSpriteAsset;
|
||||
}
|
||||
|
||||
// Search default sprite asset potentially assigned in the TMP Settings.
|
||||
if (includeFallbacks && TMP_Settings.defaultSpriteAsset != null)
|
||||
{
|
||||
tempSpriteAsset = SearchForSpriteByHashCodeInternal(TMP_Settings.defaultSpriteAsset, hashCode, true, out spriteIndex);
|
||||
|
||||
if (spriteIndex != -1)
|
||||
return tempSpriteAsset;
|
||||
}
|
||||
|
||||
// Clear search list since we are now looking for the missing sprite character.
|
||||
k_searchedSpriteAssets.Clear();
|
||||
|
||||
uint missingSpriteCharacterUnicode = TMP_Settings.missingCharacterSpriteUnicode;
|
||||
|
||||
// Get sprite index for the given unicode
|
||||
spriteIndex = spriteAsset.GetSpriteIndexFromUnicode(missingSpriteCharacterUnicode);
|
||||
if (spriteIndex != -1)
|
||||
return spriteAsset;
|
||||
|
||||
// Add current sprite asset to list of assets already searched.
|
||||
k_searchedSpriteAssets.Add(id);
|
||||
|
||||
// Search for the missing sprite character in the local sprite asset and potential fallbacks.
|
||||
if (includeFallbacks && spriteAsset.fallbackSpriteAssets != null && spriteAsset.fallbackSpriteAssets.Count > 0)
|
||||
{
|
||||
tempSpriteAsset = SearchForSpriteByUnicodeInternal(spriteAsset.fallbackSpriteAssets, missingSpriteCharacterUnicode, true, out spriteIndex);
|
||||
|
||||
if (spriteIndex != -1)
|
||||
return tempSpriteAsset;
|
||||
}
|
||||
|
||||
// Search for the missing sprite character in the default sprite asset and potential fallbacks.
|
||||
if (includeFallbacks && TMP_Settings.defaultSpriteAsset != null)
|
||||
{
|
||||
tempSpriteAsset = SearchForSpriteByUnicodeInternal(TMP_Settings.defaultSpriteAsset, missingSpriteCharacterUnicode, true, out spriteIndex);
|
||||
if (spriteIndex != -1)
|
||||
return tempSpriteAsset;
|
||||
}
|
||||
|
||||
spriteIndex = -1;
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Search through the given list of sprite assets and fallbacks for a sprite whose hash code value of its name matches the target hash code.
|
||||
/// </summary>
|
||||
/// <param name="spriteAssets"></param>
|
||||
/// <param name="hashCode"></param>
|
||||
/// <param name="searchFallbacks"></param>
|
||||
/// <param name="spriteIndex"></param>
|
||||
/// <returns></returns>
|
||||
private static TMP_SpriteAsset SearchForSpriteByHashCodeInternal(List<TMP_SpriteAsset> spriteAssets, int hashCode, bool searchFallbacks, out int spriteIndex)
|
||||
{
|
||||
// Search through the list of sprite assets
|
||||
for (int i = 0; i < spriteAssets.Count; i++)
|
||||
{
|
||||
TMP_SpriteAsset temp = spriteAssets[i];
|
||||
if (temp == null) continue;
|
||||
|
||||
int id = temp.instanceID;
|
||||
|
||||
// Skip sprite asset if it has already been searched.
|
||||
if (k_searchedSpriteAssets.Add(id) == false)
|
||||
continue;
|
||||
|
||||
temp = SearchForSpriteByHashCodeInternal(temp, hashCode, searchFallbacks, out spriteIndex);
|
||||
|
||||
if (temp != null)
|
||||
return temp;
|
||||
}
|
||||
|
||||
spriteIndex = -1;
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Search through the given sprite asset and fallbacks for a sprite whose hash code value of its name matches the target hash code.
|
||||
/// </summary>
|
||||
/// <param name="spriteAsset"></param>
|
||||
/// <param name="hashCode"></param>
|
||||
/// <param name="searchFallbacks"></param>
|
||||
/// <param name="spriteIndex"></param>
|
||||
/// <returns></returns>
|
||||
private static TMP_SpriteAsset SearchForSpriteByHashCodeInternal(TMP_SpriteAsset spriteAsset, int hashCode, bool searchFallbacks, out int spriteIndex)
|
||||
{
|
||||
// Get the sprite for the given hash code.
|
||||
spriteIndex = spriteAsset.GetSpriteIndexFromHashcode(hashCode);
|
||||
if (spriteIndex != -1)
|
||||
return spriteAsset;
|
||||
|
||||
if (searchFallbacks && spriteAsset.fallbackSpriteAssets != null && spriteAsset.fallbackSpriteAssets.Count > 0)
|
||||
return SearchForSpriteByHashCodeInternal(spriteAsset.fallbackSpriteAssets, hashCode, true, out spriteIndex);
|
||||
|
||||
spriteIndex = -1;
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Sort the sprite glyph table by glyph index.
|
||||
/// </summary>
|
||||
public void SortGlyphTable()
|
||||
{
|
||||
if (m_SpriteGlyphTable == null || m_SpriteGlyphTable.Count == 0) return;
|
||||
|
||||
m_SpriteGlyphTable = m_SpriteGlyphTable.OrderBy(item => item.index).ToList();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sort the sprite character table by Unicode values.
|
||||
/// </summary>
|
||||
internal void SortCharacterTable()
|
||||
{
|
||||
if (m_SpriteCharacterTable != null && m_SpriteCharacterTable.Count > 0)
|
||||
m_SpriteCharacterTable = m_SpriteCharacterTable.OrderBy(c => c.unicode).ToList();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sort both sprite glyph and character tables.
|
||||
/// </summary>
|
||||
internal void SortGlyphAndCharacterTables()
|
||||
{
|
||||
SortGlyphTable();
|
||||
SortCharacterTable();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Internal method used to upgrade sprite asset.
|
||||
/// </summary>
|
||||
private void UpgradeSpriteAsset()
|
||||
{
|
||||
m_Version = "1.1.0";
|
||||
|
||||
Debug.Log("Upgrading sprite asset [" + this.name + "] to version " + m_Version + ".", this);
|
||||
|
||||
// Convert legacy glyph and character tables to new format
|
||||
m_SpriteCharacterTable.Clear();
|
||||
m_SpriteGlyphTable.Clear();
|
||||
|
||||
for (int i = 0; i < spriteInfoList.Count; i++)
|
||||
{
|
||||
TMP_Sprite oldSprite = spriteInfoList[i];
|
||||
|
||||
TMP_SpriteGlyph spriteGlyph = new TMP_SpriteGlyph();
|
||||
spriteGlyph.index = (uint)i;
|
||||
spriteGlyph.sprite = oldSprite.sprite;
|
||||
spriteGlyph.metrics = new GlyphMetrics(oldSprite.width, oldSprite.height, oldSprite.xOffset, oldSprite.yOffset, oldSprite.xAdvance);
|
||||
spriteGlyph.glyphRect = new GlyphRect((int)oldSprite.x, (int)oldSprite.y, (int)oldSprite.width, (int)oldSprite.height);
|
||||
|
||||
spriteGlyph.scale = 1.0f;
|
||||
spriteGlyph.atlasIndex = 0;
|
||||
|
||||
m_SpriteGlyphTable.Add(spriteGlyph);
|
||||
|
||||
TMP_SpriteCharacter spriteCharacter = new TMP_SpriteCharacter();
|
||||
spriteCharacter.glyph = spriteGlyph;
|
||||
spriteCharacter.unicode = oldSprite.unicode == 0x0 ? 0xFFFE : (uint)oldSprite.unicode;
|
||||
spriteCharacter.name = oldSprite.name;
|
||||
spriteCharacter.scale = oldSprite.scale;
|
||||
|
||||
m_SpriteCharacterTable.Add(spriteCharacter);
|
||||
}
|
||||
|
||||
// Clear legacy glyph info list.
|
||||
//spriteInfoList.Clear();
|
||||
|
||||
UpdateLookupTables();
|
||||
|
||||
#if UNITY_EDITOR
|
||||
UnityEditor.EditorUtility.SetDirty(this);
|
||||
UnityEditor.AssetDatabase.SaveAssets();
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 84a92b25f83d49b9bc132d206b370281
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {fileID: 2800000, guid: ec7c645d93308c04d8840982af12101e, type: 3}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,70 @@
|
|||
using UnityEngine;
|
||||
using System.Collections.Generic;
|
||||
|
||||
|
||||
namespace TMPro.SpriteAssetUtilities
|
||||
{
|
||||
public enum SpriteAssetImportFormats { None = 0, TexturePackerJsonArray = 0x1 };
|
||||
|
||||
public class TexturePacker_JsonArray
|
||||
{
|
||||
[System.Serializable]
|
||||
public struct SpriteFrame
|
||||
{
|
||||
public float x;
|
||||
public float y;
|
||||
public float w;
|
||||
public float h;
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
string s = "x: " + x.ToString("f2") + " y: " + y.ToString("f2") + " h: " + h.ToString("f2") + " w: " + w.ToString("f2");
|
||||
return s;
|
||||
}
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
public struct SpriteSize
|
||||
{
|
||||
public float w;
|
||||
public float h;
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
string s = "w: " + w.ToString("f2") + " h: " + h.ToString("f2");
|
||||
return s;
|
||||
}
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
public struct Frame
|
||||
{
|
||||
public string filename;
|
||||
public SpriteFrame frame;
|
||||
public bool rotated;
|
||||
public bool trimmed;
|
||||
public SpriteFrame spriteSourceSize;
|
||||
public SpriteSize sourceSize;
|
||||
public Vector2 pivot;
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
public struct Meta
|
||||
{
|
||||
public string app;
|
||||
public string version;
|
||||
public string image;
|
||||
public string format;
|
||||
public SpriteSize size;
|
||||
public float scale;
|
||||
public string smartupdate;
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
public class SpriteDataObject
|
||||
{
|
||||
public List<Frame> frames;
|
||||
public Meta meta;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
fileFormatVersion: 2
|
||||
guid: e4e0b1de1aee400d81ed4273141e7823
|
||||
timeCreated: 1480042510
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,106 @@
|
|||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace TMPro
|
||||
{
|
||||
/// <summary>
|
||||
/// A basic element of text representing a pictograph, image, sprite or emoji.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class TMP_SpriteCharacter : TMP_TextElement
|
||||
{
|
||||
/// <summary>
|
||||
/// The name of the sprite element.
|
||||
/// </summary>
|
||||
public string name
|
||||
{
|
||||
get { return m_Name; }
|
||||
set
|
||||
{
|
||||
if (value == m_Name)
|
||||
return;
|
||||
|
||||
m_Name = value;
|
||||
m_HashCode = TMP_TextParsingUtilities.GetHashCodeCaseSensitive(m_Name);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The hashcode value which is computed from the name of the sprite element.
|
||||
/// This value is read-only and updated when the name of the text sprite is changed.
|
||||
/// </summary>
|
||||
public int hashCode { get { return m_HashCode; } }
|
||||
|
||||
|
||||
// =============================================
|
||||
// Private backing fields for public properties.
|
||||
// =============================================
|
||||
|
||||
[SerializeField]
|
||||
private string m_Name;
|
||||
|
||||
[SerializeField]
|
||||
private int m_HashCode;
|
||||
|
||||
|
||||
// ********************
|
||||
// CONSTRUCTORS
|
||||
// ********************
|
||||
|
||||
/// <summary>
|
||||
/// Default constructor.
|
||||
/// </summary>
|
||||
public TMP_SpriteCharacter()
|
||||
{
|
||||
m_ElementType = TextElementType.Sprite;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor for new sprite character.
|
||||
/// </summary>
|
||||
/// <param name="unicode">Unicode value of the sprite character.</param>
|
||||
/// <param name="glyph">Glyph used by the sprite character.</param>
|
||||
public TMP_SpriteCharacter(uint unicode, TMP_SpriteGlyph glyph)
|
||||
{
|
||||
m_ElementType = TextElementType.Sprite;
|
||||
|
||||
this.unicode = unicode;
|
||||
this.glyphIndex = glyph.index;
|
||||
this.glyph = glyph;
|
||||
this.scale = 1.0f;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor for new sprite character.
|
||||
/// </summary>
|
||||
/// <param name="unicode">Unicode value of the sprite character.</param>
|
||||
/// <param name="spriteAsset">Sprite Asset used by this sprite character.</param>
|
||||
/// <param name="glyph">Glyph used by the sprite character.</param>
|
||||
public TMP_SpriteCharacter(uint unicode, TMP_SpriteAsset spriteAsset, TMP_SpriteGlyph glyph)
|
||||
{
|
||||
m_ElementType = TextElementType.Sprite;
|
||||
|
||||
this.unicode = unicode;
|
||||
this.textAsset = spriteAsset;
|
||||
this.glyph = glyph;
|
||||
this.glyphIndex = glyph.index;
|
||||
this.scale = 1.0f;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="unicode"></param>
|
||||
/// <param name="glyphIndex"></param>
|
||||
internal TMP_SpriteCharacter(uint unicode, uint glyphIndex)
|
||||
{
|
||||
m_ElementType = TextElementType.Sprite;
|
||||
|
||||
this.unicode = unicode;
|
||||
this.textAsset = null;
|
||||
this.glyph = null;
|
||||
this.glyphIndex = glyphIndex;
|
||||
this.scale = 1.0f;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 202d758d102b6854a9710c8b93db742c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,61 @@
|
|||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEngine.TextCore;
|
||||
|
||||
namespace TMPro
|
||||
{
|
||||
/// <summary>
|
||||
/// The visual representation of the sprite character using this glyph.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class TMP_SpriteGlyph : Glyph
|
||||
{
|
||||
/// <summary>
|
||||
/// An optional reference to the underlying sprite used to create this glyph.
|
||||
/// </summary>
|
||||
public Sprite sprite;
|
||||
|
||||
|
||||
// ********************
|
||||
// CONSTRUCTORS
|
||||
// ********************
|
||||
|
||||
public TMP_SpriteGlyph() { }
|
||||
|
||||
/// <summary>
|
||||
/// Constructor for new sprite glyph.
|
||||
/// </summary>
|
||||
/// <param name="index">Index of the sprite glyph.</param>
|
||||
/// <param name="metrics">Metrics which define the position of the glyph in the context of text layout.</param>
|
||||
/// <param name="glyphRect">GlyphRect which defines the coordinates of the glyph in the atlas texture.</param>
|
||||
/// <param name="scale">Scale of the glyph.</param>
|
||||
/// <param name="atlasIndex">Index of the atlas texture that contains the glyph.</param>
|
||||
public TMP_SpriteGlyph(uint index, GlyphMetrics metrics, GlyphRect glyphRect, float scale, int atlasIndex)
|
||||
{
|
||||
this.index = index;
|
||||
this.metrics = metrics;
|
||||
this.glyphRect = glyphRect;
|
||||
this.scale = scale;
|
||||
this.atlasIndex = atlasIndex;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor for new sprite glyph.
|
||||
/// </summary>
|
||||
/// <param name="index">>Index of the sprite glyph.</param>
|
||||
/// <param name="metrics">Metrics which define the position of the glyph in the context of text layout.</param>
|
||||
/// <param name="glyphRect">GlyphRect which defines the coordinates of the glyph in the atlas texture.</param>
|
||||
/// <param name="scale">Scale of the glyph.</param>
|
||||
/// <param name="atlasIndex">Index of the atlas texture that contains the glyph.</param>
|
||||
/// <param name="sprite">A reference to the Unity Sprite representing this sprite glyph.</param>
|
||||
public TMP_SpriteGlyph(uint index, GlyphMetrics metrics, GlyphRect glyphRect, float scale, int atlasIndex, Sprite sprite)
|
||||
{
|
||||
this.index = index;
|
||||
this.metrics = metrics;
|
||||
this.glyphRect = glyphRect;
|
||||
this.scale = scale;
|
||||
this.atlasIndex = atlasIndex;
|
||||
this.sprite = sprite;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 5b5c6a576605b3c4aab7d27193785f27
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,129 @@
|
|||
using UnityEngine;
|
||||
using System.Collections;
|
||||
|
||||
#pragma warning disable 0649 // Disabled warnings.
|
||||
|
||||
namespace TMPro
|
||||
{
|
||||
[System.Serializable]
|
||||
public class TMP_Style
|
||||
{
|
||||
public static TMP_Style NormalStyle
|
||||
{
|
||||
get
|
||||
{
|
||||
if (k_NormalStyle == null)
|
||||
k_NormalStyle = new TMP_Style("Normal", string.Empty, string.Empty);
|
||||
|
||||
return k_NormalStyle;
|
||||
}
|
||||
}
|
||||
internal static TMP_Style k_NormalStyle;
|
||||
|
||||
// PUBLIC PROPERTIES
|
||||
|
||||
/// <summary>
|
||||
/// The name identifying this style. ex. <style="name">.
|
||||
/// </summary>
|
||||
public string name
|
||||
{ get { return m_Name; } set { if (value != m_Name) m_Name = value; } }
|
||||
|
||||
/// <summary>
|
||||
/// The hash code corresponding to the name of this style.
|
||||
/// </summary>
|
||||
public int hashCode
|
||||
{ get { return m_HashCode; } set { if (value != m_HashCode) m_HashCode = value; } }
|
||||
|
||||
/// <summary>
|
||||
/// The initial definition of the style. ex. <b> <u>.
|
||||
/// </summary>
|
||||
public string styleOpeningDefinition
|
||||
{ get { return m_OpeningDefinition; } }
|
||||
|
||||
/// <summary>
|
||||
/// The closing definition of the style. ex. </b> </u>.
|
||||
/// </summary>
|
||||
public string styleClosingDefinition
|
||||
{ get { return m_ClosingDefinition; } }
|
||||
|
||||
|
||||
public int[] styleOpeningTagArray
|
||||
{ get { return m_OpeningTagArray; } }
|
||||
|
||||
|
||||
public int[] styleClosingTagArray
|
||||
{ get { return m_ClosingTagArray; } }
|
||||
|
||||
|
||||
// PRIVATE FIELDS
|
||||
[SerializeField]
|
||||
private string m_Name;
|
||||
|
||||
[SerializeField]
|
||||
private int m_HashCode;
|
||||
|
||||
[SerializeField]
|
||||
private string m_OpeningDefinition;
|
||||
|
||||
[SerializeField]
|
||||
private string m_ClosingDefinition;
|
||||
|
||||
[SerializeField]
|
||||
private int[] m_OpeningTagArray;
|
||||
|
||||
[SerializeField]
|
||||
private int[] m_ClosingTagArray;
|
||||
|
||||
[SerializeField]
|
||||
internal uint[] m_OpeningTagUnicodeArray;
|
||||
|
||||
[SerializeField]
|
||||
internal uint[] m_ClosingTagUnicodeArray;
|
||||
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
/// <param name="styleName">Name of the style.</param>
|
||||
/// <param name="styleOpeningDefinition">Style opening definition.</param>
|
||||
/// <param name="styleClosingDefinition">Style closing definition.</param>
|
||||
internal TMP_Style(string styleName, string styleOpeningDefinition, string styleClosingDefinition)
|
||||
{
|
||||
m_Name = styleName;
|
||||
m_HashCode = TMP_TextParsingUtilities.GetHashCode(styleName);
|
||||
m_OpeningDefinition = styleOpeningDefinition;
|
||||
m_ClosingDefinition = styleClosingDefinition;
|
||||
|
||||
RefreshStyle();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function to update the content of the int[] resulting from changes to OpeningDefinition & ClosingDefinition.
|
||||
/// </summary>
|
||||
public void RefreshStyle()
|
||||
{
|
||||
m_HashCode = TMP_TextParsingUtilities.GetHashCode(m_Name);
|
||||
|
||||
int s1 = m_OpeningDefinition.Length;
|
||||
m_OpeningTagArray = new int[s1];
|
||||
m_OpeningTagUnicodeArray = new uint[s1];
|
||||
|
||||
for (int i = 0; i < s1; i++)
|
||||
{
|
||||
m_OpeningTagArray[i] = m_OpeningDefinition[i];
|
||||
m_OpeningTagUnicodeArray[i] = m_OpeningDefinition[i];
|
||||
}
|
||||
|
||||
int s2 = m_ClosingDefinition.Length;
|
||||
m_ClosingTagArray = new int[s2];
|
||||
m_ClosingTagUnicodeArray = new uint[s2];
|
||||
|
||||
for (int i = 0; i < s2; i++)
|
||||
{
|
||||
m_ClosingTagArray[i] = m_ClosingDefinition[i];
|
||||
m_ClosingTagUnicodeArray[i] = m_ClosingDefinition[i];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 30bed781e402439ab8ce4e3357708115
|
||||
timeCreated: 1432681409
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,109 @@
|
|||
using UnityEngine;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
|
||||
namespace TMPro
|
||||
{
|
||||
|
||||
[Serializable][ExcludeFromPresetAttribute]
|
||||
public class TMP_StyleSheet : ScriptableObject
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
internal List<TMP_Style> styles
|
||||
{
|
||||
get { return m_StyleList; }
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
private List<TMP_Style> m_StyleList = new List<TMP_Style>(1);
|
||||
private Dictionary<int, TMP_Style> m_StyleLookupDictionary;
|
||||
|
||||
private void Reset()
|
||||
{
|
||||
LoadStyleDictionaryInternal();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the Style for the given hash code value.
|
||||
/// </summary>
|
||||
/// <param name="hashCode">Hash code of the style.</param>
|
||||
/// <returns>The style matching the hash code.</returns>
|
||||
public TMP_Style GetStyle(int hashCode)
|
||||
{
|
||||
if (m_StyleLookupDictionary == null)
|
||||
LoadStyleDictionaryInternal();
|
||||
|
||||
TMP_Style style;
|
||||
|
||||
if (m_StyleLookupDictionary.TryGetValue(hashCode, out style))
|
||||
return style;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the Style for the given name.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of the style.</param>
|
||||
/// <returns>The style if found.</returns>
|
||||
public TMP_Style GetStyle(string name)
|
||||
{
|
||||
if (m_StyleLookupDictionary == null)
|
||||
LoadStyleDictionaryInternal();
|
||||
|
||||
int hashCode = TMP_TextParsingUtilities.GetHashCode(name);
|
||||
TMP_Style style;
|
||||
|
||||
if (m_StyleLookupDictionary.TryGetValue(hashCode, out style))
|
||||
return style;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Function to refresh the Style Dictionary.
|
||||
/// </summary>
|
||||
public void RefreshStyles()
|
||||
{
|
||||
LoadStyleDictionaryInternal();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
private void LoadStyleDictionaryInternal()
|
||||
{
|
||||
if (m_StyleLookupDictionary == null)
|
||||
m_StyleLookupDictionary = new Dictionary<int, TMP_Style>();
|
||||
else
|
||||
m_StyleLookupDictionary.Clear();
|
||||
|
||||
// Read Styles from style list and store them into dictionary for faster access.
|
||||
for (int i = 0; i < m_StyleList.Count; i++)
|
||||
{
|
||||
m_StyleList[i].RefreshStyle();
|
||||
|
||||
if (!m_StyleLookupDictionary.ContainsKey(m_StyleList[i].hashCode))
|
||||
m_StyleLookupDictionary.Add(m_StyleList[i].hashCode, m_StyleList[i]);
|
||||
}
|
||||
|
||||
// Add Normal Style if it does not already exists
|
||||
int normalStyleHashCode = TMP_TextParsingUtilities.GetHashCode("Normal");
|
||||
if (!m_StyleLookupDictionary.ContainsKey(normalStyleHashCode))
|
||||
{
|
||||
TMP_Style style = new TMP_Style("Normal", string.Empty, string.Empty);
|
||||
m_StyleList.Add(style);
|
||||
m_StyleLookupDictionary.Add(normalStyleHashCode, style);
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
//// Event to update objects when styles are changed in the editor.
|
||||
TMPro_EventManager.ON_TEXT_STYLE_PROPERTY_CHANGED(true);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
fileFormatVersion: 2
|
||||
guid: ab2114bdc8544297b417dfefe9f1e410
|
||||
timeCreated: 1436650317
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences:
|
||||
- StyleSheet: {fileID: 11400000, guid: cab1ac28c8e6be24e995befe0c36d7c1, type: 2}
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,640 @@
|
|||
using UnityEngine;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using Object = UnityEngine.Object;
|
||||
|
||||
#pragma warning disable 0109 // Disable warning due to conflict between Unity Editor DLL and Runtime DLL related to .renderer property being available in one but not the other.
|
||||
|
||||
namespace TMPro
|
||||
{
|
||||
[RequireComponent(typeof(MeshRenderer))]
|
||||
[ExecuteAlways]
|
||||
public class TMP_SubMesh : MonoBehaviour
|
||||
{
|
||||
/// <summary>
|
||||
/// The TMP Font Asset assigned to this sub text object.
|
||||
/// </summary>
|
||||
public TMP_FontAsset fontAsset
|
||||
{
|
||||
get { return m_fontAsset; }
|
||||
set { m_fontAsset = value; }
|
||||
}
|
||||
[SerializeField]
|
||||
private TMP_FontAsset m_fontAsset;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// The TMP Sprite Asset assigned to this sub text object.
|
||||
/// </summary>
|
||||
public TMP_SpriteAsset spriteAsset
|
||||
{
|
||||
get { return m_spriteAsset; }
|
||||
set { m_spriteAsset = value; }
|
||||
}
|
||||
[SerializeField]
|
||||
private TMP_SpriteAsset m_spriteAsset;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// The material to be assigned to this object. Returns an instance of the material.
|
||||
/// </summary>
|
||||
public Material material
|
||||
{
|
||||
// Return a new Instance of the Material if none exists. Otherwise return the current Material Instance.
|
||||
get { return GetMaterial(m_sharedMaterial); }
|
||||
|
||||
// Assign new font material
|
||||
set
|
||||
{
|
||||
if (m_sharedMaterial.GetInstanceID() == value.GetInstanceID())
|
||||
return;
|
||||
|
||||
m_sharedMaterial = m_material = value;
|
||||
|
||||
m_padding = GetPaddingForMaterial();
|
||||
|
||||
SetVerticesDirty();
|
||||
SetMaterialDirty();
|
||||
}
|
||||
}
|
||||
[SerializeField]
|
||||
private Material m_material;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// The material to be assigned to this text object.
|
||||
/// </summary>
|
||||
public Material sharedMaterial
|
||||
{
|
||||
get { return m_sharedMaterial; }
|
||||
set { SetSharedMaterial(value); }
|
||||
}
|
||||
[SerializeField]
|
||||
private Material m_sharedMaterial;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// The fallback material created from the properties of the fallback source material.
|
||||
/// </summary>
|
||||
public Material fallbackMaterial
|
||||
{
|
||||
get { return m_fallbackMaterial; }
|
||||
set
|
||||
{
|
||||
if (m_fallbackMaterial == value) return;
|
||||
|
||||
if (m_fallbackMaterial != null && m_fallbackMaterial != value)
|
||||
TMP_MaterialManager.ReleaseFallbackMaterial(m_fallbackMaterial);
|
||||
|
||||
m_fallbackMaterial = value;
|
||||
TMP_MaterialManager.AddFallbackMaterialReference(m_fallbackMaterial);
|
||||
|
||||
SetSharedMaterial(m_fallbackMaterial);
|
||||
}
|
||||
}
|
||||
private Material m_fallbackMaterial;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// The source material used by the fallback font
|
||||
/// </summary>
|
||||
public Material fallbackSourceMaterial
|
||||
{
|
||||
get { return m_fallbackSourceMaterial; }
|
||||
set { m_fallbackSourceMaterial = value; }
|
||||
}
|
||||
private Material m_fallbackSourceMaterial;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Is the text object using the default font asset material.
|
||||
/// </summary>
|
||||
public bool isDefaultMaterial
|
||||
{
|
||||
get { return m_isDefaultMaterial; }
|
||||
set { m_isDefaultMaterial = value; }
|
||||
}
|
||||
[SerializeField]
|
||||
private bool m_isDefaultMaterial;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Padding value resulting for the property settings on the material.
|
||||
/// </summary>
|
||||
public float padding
|
||||
{
|
||||
get { return m_padding; }
|
||||
set { m_padding = value; }
|
||||
}
|
||||
[SerializeField]
|
||||
private float m_padding;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// The Mesh Renderer of this text sub object.
|
||||
/// </summary>
|
||||
public new Renderer renderer
|
||||
{
|
||||
get { if (m_renderer == null) m_renderer = GetComponent<Renderer>();
|
||||
|
||||
return m_renderer;
|
||||
}
|
||||
}
|
||||
[SerializeField]
|
||||
private Renderer m_renderer;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// The MeshFilter of this text sub object.
|
||||
/// </summary>
|
||||
public MeshFilter meshFilter
|
||||
{
|
||||
get
|
||||
{
|
||||
if (m_meshFilter == null)
|
||||
{
|
||||
m_meshFilter = GetComponent<MeshFilter>();
|
||||
|
||||
if (m_meshFilter == null)
|
||||
{
|
||||
m_meshFilter = gameObject.AddComponent<MeshFilter>();
|
||||
m_meshFilter.hideFlags = HideFlags.HideInInspector | HideFlags.HideAndDontSave;
|
||||
}
|
||||
}
|
||||
|
||||
return m_meshFilter;
|
||||
}
|
||||
}
|
||||
private MeshFilter m_meshFilter;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// The Mesh of this text sub object.
|
||||
/// </summary>
|
||||
public Mesh mesh
|
||||
{
|
||||
get
|
||||
{
|
||||
if (m_mesh == null)
|
||||
{
|
||||
m_mesh = new Mesh();
|
||||
m_mesh.hideFlags = HideFlags.HideAndDontSave;
|
||||
}
|
||||
|
||||
return m_mesh;
|
||||
}
|
||||
set { m_mesh = value; }
|
||||
}
|
||||
private Mesh m_mesh;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
//public BoxCollider boxCollider
|
||||
//{
|
||||
// get
|
||||
// {
|
||||
// if (m_boxCollider == null)
|
||||
// {
|
||||
// //
|
||||
// m_boxCollider = GetComponent<BoxCollider>();
|
||||
// if (m_boxCollider == null)
|
||||
// {
|
||||
// m_boxCollider = gameObject.AddComponent<BoxCollider>();
|
||||
// gameObject.AddComponent<Rigidbody>();
|
||||
// }
|
||||
// }
|
||||
|
||||
// return m_boxCollider;
|
||||
// }
|
||||
//}
|
||||
//[SerializeField]
|
||||
//private BoxCollider m_boxCollider;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Reference to the parent Text Component.
|
||||
/// </summary>
|
||||
public TMP_Text textComponent
|
||||
{
|
||||
get
|
||||
{
|
||||
if (m_TextComponent == null)
|
||||
m_TextComponent = GetComponentInParent<TextMeshPro>();
|
||||
|
||||
return m_TextComponent;
|
||||
}
|
||||
}
|
||||
[SerializeField]
|
||||
private TextMeshPro m_TextComponent;
|
||||
|
||||
[NonSerialized]
|
||||
private bool m_isRegisteredForEvents;
|
||||
|
||||
|
||||
public static TMP_SubMesh AddSubTextObject(TextMeshPro textComponent, MaterialReference materialReference)
|
||||
{
|
||||
GameObject go = new GameObject("TMP SubMesh [" + materialReference.material.name + "]", typeof(TMP_SubMesh));
|
||||
go.hideFlags = HideFlags.DontSave;
|
||||
|
||||
TMP_SubMesh subMesh = go.GetComponent<TMP_SubMesh>();
|
||||
|
||||
go.transform.SetParent(textComponent.transform, false);
|
||||
go.transform.localPosition = Vector3.zero;
|
||||
go.transform.localRotation = Quaternion.identity;
|
||||
go.transform.localScale = Vector3.one;
|
||||
go.layer = textComponent.gameObject.layer;
|
||||
|
||||
subMesh.m_TextComponent = textComponent;
|
||||
subMesh.m_fontAsset = materialReference.fontAsset;
|
||||
subMesh.m_spriteAsset = materialReference.spriteAsset;
|
||||
subMesh.m_isDefaultMaterial = materialReference.isDefaultMaterial;
|
||||
subMesh.SetSharedMaterial(materialReference.material);
|
||||
|
||||
subMesh.renderer.sortingLayerID = textComponent.renderer.sortingLayerID;
|
||||
subMesh.renderer.sortingOrder = textComponent.renderer.sortingOrder;
|
||||
|
||||
return subMesh;
|
||||
}
|
||||
|
||||
|
||||
void OnEnable()
|
||||
{
|
||||
//Debug.Log("***** OnEnable() called on object ID " + GetInstanceID() + "]. Parent Text Object ID [" + (textComponent == null ? "" : textComponent.GetInstanceID().ToString()) + "] *****");
|
||||
|
||||
// Register Callbacks for various events.
|
||||
if (!m_isRegisteredForEvents)
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
TMPro_EventManager.MATERIAL_PROPERTY_EVENT.Add(ON_MATERIAL_PROPERTY_CHANGED);
|
||||
TMPro_EventManager.FONT_PROPERTY_EVENT.Add(ON_FONT_PROPERTY_CHANGED);
|
||||
//TMPro_EventManager.TEXTMESHPRO_PROPERTY_EVENT.Add(ON_TEXTMESHPRO_PROPERTY_CHANGED);
|
||||
TMPro_EventManager.DRAG_AND_DROP_MATERIAL_EVENT.Add(ON_DRAG_AND_DROP_MATERIAL);
|
||||
//TMPro_EventManager.TEXT_STYLE_PROPERTY_EVENT.Add(ON_TEXT_STYLE_CHANGED);
|
||||
TMPro_EventManager.SPRITE_ASSET_PROPERTY_EVENT.Add(ON_SPRITE_ASSET_PROPERTY_CHANGED);
|
||||
//TMPro_EventManager.TMP_SETTINGS_PROPERTY_EVENT.Add(ON_TMP_SETTINGS_CHANGED);
|
||||
#endif
|
||||
|
||||
m_isRegisteredForEvents = true;
|
||||
}
|
||||
|
||||
// Update HideFlags on previously created sub text objects.
|
||||
if (hideFlags != HideFlags.DontSave)
|
||||
hideFlags = HideFlags.DontSave;
|
||||
|
||||
// Make the geometry visible when the object is enabled.
|
||||
meshFilter.sharedMesh = mesh;
|
||||
|
||||
// Update _ClipRect values
|
||||
if (m_sharedMaterial != null)
|
||||
m_sharedMaterial.SetVector(ShaderUtilities.ID_ClipRect, new Vector4(-32767, -32767, 32767, 32767));
|
||||
}
|
||||
|
||||
|
||||
void OnDisable()
|
||||
{
|
||||
//Debug.Log("***** OnDisable() called on Sub Object ID [" + GetInstanceID() + "]. Parent Text Object ID [" + textComponent.GetInstanceID() + "] *****");
|
||||
|
||||
// Hide the geometry when the object is disabled.
|
||||
m_meshFilter.sharedMesh = null;
|
||||
|
||||
if (m_fallbackMaterial != null)
|
||||
{
|
||||
TMP_MaterialManager.ReleaseFallbackMaterial(m_fallbackMaterial);
|
||||
m_fallbackMaterial = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void OnDestroy()
|
||||
{
|
||||
//Debug.Log("***** OnDestroy() called on Sub Object ID [" + GetInstanceID() + "]. Parent Text Object ID [" + textComponent.GetInstanceID() + "] *****");
|
||||
|
||||
// Destroy Mesh
|
||||
if (m_mesh != null) DestroyImmediate(m_mesh);
|
||||
|
||||
if (m_fallbackMaterial != null)
|
||||
{
|
||||
TMP_MaterialManager.ReleaseFallbackMaterial(m_fallbackMaterial);
|
||||
m_fallbackMaterial = null;
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
// Unregister the event this object was listening to
|
||||
TMPro_EventManager.MATERIAL_PROPERTY_EVENT.Remove(ON_MATERIAL_PROPERTY_CHANGED);
|
||||
TMPro_EventManager.FONT_PROPERTY_EVENT.Remove(ON_FONT_PROPERTY_CHANGED);
|
||||
//TMPro_EventManager.TEXTMESHPRO_PROPERTY_EVENT.Remove(ON_TEXTMESHPRO_PROPERTY_CHANGED);
|
||||
TMPro_EventManager.DRAG_AND_DROP_MATERIAL_EVENT.Remove(ON_DRAG_AND_DROP_MATERIAL);
|
||||
//TMPro_EventManager.TEXT_STYLE_PROPERTY_EVENT.Remove(ON_TEXT_STYLE_CHANGED);
|
||||
TMPro_EventManager.SPRITE_ASSET_PROPERTY_EVENT.Remove(ON_SPRITE_ASSET_PROPERTY_CHANGED);
|
||||
//TMPro_EventManager.TMP_SETTINGS_PROPERTY_EVENT.Remove(ON_TMP_SETTINGS_CHANGED);
|
||||
#endif
|
||||
m_isRegisteredForEvents = false;
|
||||
|
||||
// Notify parent text object
|
||||
if (m_TextComponent != null)
|
||||
{
|
||||
m_TextComponent.havePropertiesChanged = true;
|
||||
m_TextComponent.SetAllDirty();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if UNITY_EDITOR
|
||||
// Event received when custom material editor properties are changed.
|
||||
void ON_MATERIAL_PROPERTY_CHANGED(bool isChanged, Material mat)
|
||||
{
|
||||
//Debug.Log("*** ON_MATERIAL_PROPERTY_CHANGED ***");
|
||||
if (m_sharedMaterial == null)
|
||||
return;
|
||||
|
||||
int targetMaterialID = mat.GetInstanceID();
|
||||
int sharedMaterialID = m_sharedMaterial.GetInstanceID();
|
||||
int fallbackSourceMaterialID = m_fallbackSourceMaterial == null ? 0 : m_fallbackSourceMaterial.GetInstanceID();
|
||||
|
||||
// Sync culling with parent text object
|
||||
bool hasCullModeProperty = m_sharedMaterial.HasProperty(ShaderUtilities.ShaderTag_CullMode);
|
||||
float cullMode = 0;
|
||||
|
||||
if (hasCullModeProperty)
|
||||
{
|
||||
cullMode = textComponent.fontSharedMaterial.GetFloat(ShaderUtilities.ShaderTag_CullMode);
|
||||
m_sharedMaterial.SetFloat(ShaderUtilities.ShaderTag_CullMode, cullMode);
|
||||
}
|
||||
|
||||
// Filter events and return if the affected material is not this object's material.
|
||||
if (targetMaterialID != sharedMaterialID)
|
||||
{
|
||||
// Check if event applies to the source fallback material
|
||||
if (m_fallbackMaterial != null && fallbackSourceMaterialID == targetMaterialID && TMP_Settings.matchMaterialPreset)
|
||||
{
|
||||
TMP_MaterialManager.CopyMaterialPresetProperties(mat, m_fallbackMaterial);
|
||||
|
||||
// Re-sync culling with parent text object
|
||||
if (hasCullModeProperty)
|
||||
m_fallbackMaterial.SetFloat(ShaderUtilities.ShaderTag_CullMode, cullMode);
|
||||
}
|
||||
else
|
||||
return;
|
||||
}
|
||||
|
||||
m_padding = GetPaddingForMaterial();
|
||||
|
||||
m_TextComponent.havePropertiesChanged = true;
|
||||
m_TextComponent.SetVerticesDirty();
|
||||
}
|
||||
|
||||
|
||||
// Event to Track Material Changed resulting from Drag-n-drop.
|
||||
void ON_DRAG_AND_DROP_MATERIAL(GameObject obj, Material currentMaterial, Material newMaterial)
|
||||
{
|
||||
// Check if event applies to this current object
|
||||
#if UNITY_2018_2_OR_NEWER
|
||||
if (obj == gameObject || UnityEditor.PrefabUtility.GetCorrespondingObjectFromSource(gameObject) == obj)
|
||||
#else
|
||||
if (obj == gameObject || UnityEditor.PrefabUtility.GetPrefabParent(gameObject) == obj)
|
||||
#endif
|
||||
{
|
||||
if (!m_isDefaultMaterial) return;
|
||||
|
||||
// Make sure we have a valid reference to the renderer.
|
||||
if (m_renderer == null) m_renderer = GetComponent<Renderer>();
|
||||
|
||||
UnityEditor.Undo.RecordObject(this, "Material Assignment");
|
||||
UnityEditor.Undo.RecordObject(m_renderer, "Material Assignment");
|
||||
|
||||
SetSharedMaterial(newMaterial);
|
||||
m_TextComponent.havePropertiesChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Event received when font asset properties are changed in Font Inspector
|
||||
void ON_SPRITE_ASSET_PROPERTY_CHANGED(bool isChanged, UnityEngine.Object obj)
|
||||
{
|
||||
//if (spriteSheet != null && (obj as TMP_SpriteAsset == m_spriteAsset || obj as Texture2D == m_spriteAsset.spriteSheet))
|
||||
//{
|
||||
if (m_TextComponent != null)
|
||||
{
|
||||
m_TextComponent.havePropertiesChanged = true;
|
||||
//m_TextComponent.SetVerticesDirty();
|
||||
}
|
||||
|
||||
//}
|
||||
}
|
||||
|
||||
// Event received when font asset properties are changed in Font Inspector
|
||||
void ON_FONT_PROPERTY_CHANGED(bool isChanged, Object fontAsset)
|
||||
{
|
||||
if (m_fontAsset != null && fontAsset.GetInstanceID() == m_fontAsset.GetInstanceID())
|
||||
{
|
||||
// Copy Normal and Bold Weight
|
||||
if (m_fallbackMaterial != null)
|
||||
{
|
||||
if (TMP_Settings.matchMaterialPreset)
|
||||
{
|
||||
TMP_MaterialManager.ReleaseFallbackMaterial(m_fallbackMaterial);
|
||||
TMP_MaterialManager.CleanupFallbackMaterials();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Event received when the TMP Settings are changed.
|
||||
/// </summary>
|
||||
void ON_TMP_SETTINGS_CHANGED()
|
||||
{
|
||||
// //Debug.Log("TMP Setting have changed.");
|
||||
// //SetVerticesDirty();
|
||||
// SetMaterialDirty();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
public void DestroySelf()
|
||||
{
|
||||
Destroy(this.gameObject, 1f);
|
||||
}
|
||||
|
||||
// Function called internally when a new material is assigned via the fontMaterial property.
|
||||
Material GetMaterial(Material mat)
|
||||
{
|
||||
// Check in case Object is disabled. If so, we don't have a valid reference to the Renderer.
|
||||
// This can occur when the Duplicate Material Context menu is used on an inactive object.
|
||||
if (m_renderer == null)
|
||||
m_renderer = GetComponent<Renderer>();
|
||||
|
||||
// Create Instance Material only if the new material is not the same instance previously used.
|
||||
if (m_material == null || m_material.GetInstanceID() != mat.GetInstanceID())
|
||||
m_material = CreateMaterialInstance(mat);
|
||||
|
||||
m_sharedMaterial = m_material;
|
||||
|
||||
// Compute and Set new padding values for this new material.
|
||||
m_padding = GetPaddingForMaterial();
|
||||
|
||||
SetVerticesDirty();
|
||||
SetMaterialDirty();
|
||||
|
||||
return m_sharedMaterial;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Method used to create an instance of the material
|
||||
/// </summary>
|
||||
/// <param name="source"></param>
|
||||
/// <returns></returns>
|
||||
Material CreateMaterialInstance(Material source)
|
||||
{
|
||||
Material mat = new Material(source);
|
||||
mat.shaderKeywords = source.shaderKeywords;
|
||||
mat.name += " (Instance)";
|
||||
|
||||
return mat;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Method returning the shared material assigned to the text object.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
Material GetSharedMaterial()
|
||||
{
|
||||
if (m_renderer == null)
|
||||
m_renderer = GetComponent<Renderer>();
|
||||
|
||||
return m_renderer.sharedMaterial;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Method to set the shared material.
|
||||
/// </summary>
|
||||
/// <param name="mat"></param>
|
||||
void SetSharedMaterial(Material mat)
|
||||
{
|
||||
//Debug.Log("*** SetSharedMaterial() *** FRAME (" + Time.frameCount + ")");
|
||||
|
||||
// Assign new material.
|
||||
m_sharedMaterial = mat;
|
||||
|
||||
// Compute and Set new padding values for this new material.
|
||||
m_padding = GetPaddingForMaterial();
|
||||
|
||||
SetMaterialDirty();
|
||||
|
||||
#if UNITY_EDITOR
|
||||
if (m_sharedMaterial != null)
|
||||
gameObject.name = "TMP SubMesh [" + m_sharedMaterial.name + "]";
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function called when the padding value for the material needs to be re-calculated.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public float GetPaddingForMaterial()
|
||||
{
|
||||
float padding = ShaderUtilities.GetPadding(m_sharedMaterial, m_TextComponent.extraPadding, m_TextComponent.isUsingBold);
|
||||
|
||||
return padding;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function to update the padding values of the object.
|
||||
/// </summary>
|
||||
/// <param name="isExtraPadding"></param>
|
||||
/// <param name="isBold"></param>
|
||||
public void UpdateMeshPadding(bool isExtraPadding, bool isUsingBold)
|
||||
{
|
||||
m_padding = ShaderUtilities.GetPadding(m_sharedMaterial, isExtraPadding, isUsingBold);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public void SetVerticesDirty()
|
||||
{
|
||||
if (!this.enabled)
|
||||
return;
|
||||
|
||||
// This is called on the parent TextMeshPro component.
|
||||
if (m_TextComponent != null)
|
||||
{
|
||||
m_TextComponent.havePropertiesChanged = true;
|
||||
m_TextComponent.SetVerticesDirty();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public void SetMaterialDirty()
|
||||
{
|
||||
//if (!this.enabled)
|
||||
// return;
|
||||
|
||||
UpdateMaterial();
|
||||
|
||||
//m_materialDirty = true;
|
||||
//TMP_UpdateRegistry.RegisterCanvasElementForGraphicRebuild((ICanvasElement)this);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
protected void UpdateMaterial()
|
||||
{
|
||||
//Debug.Log("*** STO - UpdateMaterial() *** FRAME (" + Time.frameCount + ")");
|
||||
|
||||
if (renderer == null || m_sharedMaterial == null) return;
|
||||
|
||||
m_renderer.sharedMaterial = m_sharedMaterial;
|
||||
|
||||
// Special handling to keep the Culling of the material in sync with parent text object
|
||||
if (m_sharedMaterial.HasProperty(ShaderUtilities.ShaderTag_CullMode))
|
||||
{
|
||||
float cullMode = textComponent.fontSharedMaterial.GetFloat(ShaderUtilities.ShaderTag_CullMode);
|
||||
m_sharedMaterial.SetFloat(ShaderUtilities.ShaderTag_CullMode, cullMode);
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
if (m_sharedMaterial != null && gameObject.name != "TMP SubMesh [" + m_sharedMaterial.name + "]")
|
||||
gameObject.name = "TMP SubMesh [" + m_sharedMaterial.name + "]";
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
//public void UpdateColliders(int vertexCount)
|
||||
//{
|
||||
// if (this.boxCollider == null) return;
|
||||
|
||||
// Vector2 bl = TMP_Math.MAX_16BIT;
|
||||
// Vector2 tr = TMP_Math.MIN_16BIT;
|
||||
// // Compute the bounds of the sub text object mesh (excluding the transform position).
|
||||
// for (int i = 0; i < vertexCount; i++)
|
||||
// {
|
||||
// bl.x = Mathf.Min(bl.x, m_mesh.vertices[i].x);
|
||||
// bl.y = Mathf.Min(bl.y, m_mesh.vertices[i].y);
|
||||
|
||||
// tr.x = Mathf.Max(tr.x, m_mesh.vertices[i].x);
|
||||
// tr.y = Mathf.Max(tr.y, m_mesh.vertices[i].y);
|
||||
// }
|
||||
|
||||
// Vector3 center = (bl + tr) / 2;
|
||||
// Vector3 size = tr - bl;
|
||||
// size.z = .1f;
|
||||
// this.boxCollider.center = center;
|
||||
// this.boxCollider.size = size;
|
||||
//}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 07994bfe8b0e4adb97d706de5dea48d5
|
||||
timeCreated: 1454709708
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,851 @@
|
|||
using UnityEngine;
|
||||
using UnityEngine.Rendering;
|
||||
using UnityEngine.UI;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Object = UnityEngine.Object;
|
||||
|
||||
#pragma warning disable 0414 // Disabled a few warnings related to serialized variables not used in this script but used in the editor.
|
||||
|
||||
namespace TMPro
|
||||
{
|
||||
[ExecuteAlways]
|
||||
[RequireComponent(typeof(CanvasRenderer))]
|
||||
public class TMP_SubMeshUI : MaskableGraphic
|
||||
{
|
||||
/// <summary>
|
||||
/// The TMP Font Asset assigned to this sub text object.
|
||||
/// </summary>
|
||||
public TMP_FontAsset fontAsset
|
||||
{
|
||||
get { return m_fontAsset; }
|
||||
set { m_fontAsset = value; }
|
||||
}
|
||||
[SerializeField]
|
||||
private TMP_FontAsset m_fontAsset;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// The TMP Sprite Asset assigned to this sub text object.
|
||||
/// </summary>
|
||||
public TMP_SpriteAsset spriteAsset
|
||||
{
|
||||
get { return m_spriteAsset; }
|
||||
set { m_spriteAsset = value; }
|
||||
}
|
||||
[SerializeField]
|
||||
private TMP_SpriteAsset m_spriteAsset;
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public override Texture mainTexture
|
||||
{
|
||||
get
|
||||
{
|
||||
if (this.sharedMaterial != null)
|
||||
return this.sharedMaterial.GetTexture(ShaderUtilities.ID_MainTex);
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// The material to be assigned to this object. Returns an instance of the material.
|
||||
/// </summary>
|
||||
public override Material material
|
||||
{
|
||||
// Return a new Instance of the Material if none exists. Otherwise return the current Material Instance.
|
||||
get { return GetMaterial(m_sharedMaterial); }
|
||||
|
||||
// Assign new font material
|
||||
set
|
||||
{
|
||||
if (m_sharedMaterial != null && m_sharedMaterial.GetInstanceID() == value.GetInstanceID())
|
||||
return;
|
||||
|
||||
m_sharedMaterial = m_material = value;
|
||||
|
||||
m_padding = GetPaddingForMaterial();
|
||||
|
||||
SetVerticesDirty();
|
||||
SetMaterialDirty();
|
||||
}
|
||||
}
|
||||
[SerializeField]
|
||||
private Material m_material;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// The material to be assigned to this text object.
|
||||
/// </summary>
|
||||
public Material sharedMaterial
|
||||
{
|
||||
get { return m_sharedMaterial; }
|
||||
set { SetSharedMaterial(value); }
|
||||
}
|
||||
[SerializeField]
|
||||
private Material m_sharedMaterial;
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public Material fallbackMaterial
|
||||
{
|
||||
get { return m_fallbackMaterial; }
|
||||
set
|
||||
{
|
||||
if (m_fallbackMaterial == value) return;
|
||||
|
||||
if (m_fallbackMaterial != null && m_fallbackMaterial != value)
|
||||
TMP_MaterialManager.ReleaseFallbackMaterial(m_fallbackMaterial);
|
||||
|
||||
m_fallbackMaterial = value;
|
||||
TMP_MaterialManager.AddFallbackMaterialReference(m_fallbackMaterial);
|
||||
|
||||
SetSharedMaterial(m_fallbackMaterial);
|
||||
}
|
||||
}
|
||||
private Material m_fallbackMaterial;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// The source material used by the fallback font
|
||||
/// </summary>
|
||||
public Material fallbackSourceMaterial
|
||||
{
|
||||
get { return m_fallbackSourceMaterial; }
|
||||
set { m_fallbackSourceMaterial = value; }
|
||||
}
|
||||
private Material m_fallbackSourceMaterial;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Get the material that will be used for rendering.
|
||||
/// </summary>
|
||||
public override Material materialForRendering
|
||||
{
|
||||
get
|
||||
{
|
||||
return TMP_MaterialManager.GetMaterialForRendering(this, m_sharedMaterial);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Is the text object using the default font asset material.
|
||||
/// </summary>
|
||||
public bool isDefaultMaterial
|
||||
{
|
||||
get { return m_isDefaultMaterial; }
|
||||
set { m_isDefaultMaterial = value; }
|
||||
}
|
||||
[SerializeField]
|
||||
private bool m_isDefaultMaterial;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Padding value resulting for the property settings on the material.
|
||||
/// </summary>
|
||||
public float padding
|
||||
{
|
||||
get { return m_padding; }
|
||||
set { m_padding = value; }
|
||||
}
|
||||
[SerializeField]
|
||||
private float m_padding;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// The Mesh of this text sub object.
|
||||
/// </summary>
|
||||
public Mesh mesh
|
||||
{
|
||||
get
|
||||
{
|
||||
if (m_mesh == null)
|
||||
{
|
||||
m_mesh = new Mesh();
|
||||
m_mesh.hideFlags = HideFlags.HideAndDontSave;
|
||||
}
|
||||
|
||||
return m_mesh;
|
||||
}
|
||||
set { m_mesh = value; }
|
||||
}
|
||||
private Mesh m_mesh;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Reference to the parent Text Component.
|
||||
/// </summary>
|
||||
public TMP_Text textComponent
|
||||
{
|
||||
get
|
||||
{
|
||||
if (m_TextComponent == null)
|
||||
m_TextComponent = GetComponentInParent<TextMeshProUGUI>();
|
||||
|
||||
return m_TextComponent;
|
||||
}
|
||||
}
|
||||
[SerializeField]
|
||||
private TextMeshProUGUI m_TextComponent;
|
||||
|
||||
|
||||
[System.NonSerialized]
|
||||
private bool m_isRegisteredForEvents;
|
||||
private bool m_materialDirty;
|
||||
[SerializeField]
|
||||
private int m_materialReferenceIndex;
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function to add a new sub text object.
|
||||
/// </summary>
|
||||
/// <param name="textComponent"></param>
|
||||
/// <param name="materialReference"></param>
|
||||
/// <returns></returns>
|
||||
public static TMP_SubMeshUI AddSubTextObject(TextMeshProUGUI textComponent, MaterialReference materialReference)
|
||||
{
|
||||
GameObject go = new GameObject("TMP UI SubObject [" + materialReference.material.name + "]", typeof(RectTransform));
|
||||
go.hideFlags = HideFlags.DontSave;
|
||||
|
||||
go.transform.SetParent(textComponent.transform, false);
|
||||
go.transform.SetAsFirstSibling();
|
||||
go.layer = textComponent.gameObject.layer;
|
||||
|
||||
RectTransform rectTransform = go.GetComponent<RectTransform>();
|
||||
rectTransform.anchorMin = Vector2.zero;
|
||||
rectTransform.anchorMax = Vector2.one;
|
||||
rectTransform.sizeDelta = Vector2.zero;
|
||||
rectTransform.pivot = textComponent.rectTransform.pivot;
|
||||
|
||||
LayoutElement layoutElement = go.AddComponent<LayoutElement>();
|
||||
layoutElement.ignoreLayout = true;
|
||||
|
||||
TMP_SubMeshUI subMesh = go.AddComponent<TMP_SubMeshUI>();
|
||||
|
||||
//subMesh.canvasRenderer = subMesh.canvasRenderer;
|
||||
subMesh.m_TextComponent = textComponent;
|
||||
|
||||
subMesh.m_materialReferenceIndex = materialReference.index;
|
||||
subMesh.m_fontAsset = materialReference.fontAsset;
|
||||
subMesh.m_spriteAsset = materialReference.spriteAsset;
|
||||
subMesh.m_isDefaultMaterial = materialReference.isDefaultMaterial;
|
||||
subMesh.SetSharedMaterial(materialReference.material);
|
||||
|
||||
return subMesh;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
protected override void OnEnable()
|
||||
{
|
||||
//Debug.Log("*** SubObject OnEnable() ***");
|
||||
|
||||
// Register Callbacks for various events.
|
||||
if (!m_isRegisteredForEvents)
|
||||
{
|
||||
|
||||
#if UNITY_EDITOR
|
||||
TMPro_EventManager.MATERIAL_PROPERTY_EVENT.Add(ON_MATERIAL_PROPERTY_CHANGED);
|
||||
TMPro_EventManager.FONT_PROPERTY_EVENT.Add(ON_FONT_PROPERTY_CHANGED);
|
||||
//TMPro_EventManager.TEXTMESHPRO_PROPERTY_EVENT.Add(ON_TEXTMESHPRO_PROPERTY_CHANGED);
|
||||
TMPro_EventManager.DRAG_AND_DROP_MATERIAL_EVENT.Add(ON_DRAG_AND_DROP_MATERIAL);
|
||||
//TMPro_EventManager.TEXT_STYLE_PROPERTY_EVENT.Add(ON_TEXT_STYLE_CHANGED);
|
||||
TMPro_EventManager.SPRITE_ASSET_PROPERTY_EVENT.Add(ON_SPRITE_ASSET_PROPERTY_CHANGED);
|
||||
//TMPro_EventManager.TMP_SETTINGS_PROPERTY_EVENT.Add(ON_TMP_SETTINGS_CHANGED);
|
||||
#endif
|
||||
|
||||
m_isRegisteredForEvents = true;
|
||||
}
|
||||
|
||||
// Update HideFlags on previously created sub text objects.
|
||||
if (hideFlags != HideFlags.DontSave)
|
||||
hideFlags = HideFlags.DontSave;
|
||||
|
||||
m_ShouldRecalculateStencil = true;
|
||||
RecalculateClipping();
|
||||
RecalculateMasking();
|
||||
|
||||
//SetAllDirty();
|
||||
}
|
||||
|
||||
|
||||
protected override void OnDisable()
|
||||
{
|
||||
//Debug.Log("*** SubObject OnDisable() ***");
|
||||
base.OnDisable();
|
||||
|
||||
// if (m_MaskMaterial != null)
|
||||
// {
|
||||
// TMP_MaterialManager.ReleaseStencilMaterial(m_MaskMaterial);
|
||||
// m_MaskMaterial = null;
|
||||
// }
|
||||
|
||||
if (m_fallbackMaterial != null)
|
||||
{
|
||||
TMP_MaterialManager.ReleaseFallbackMaterial(m_fallbackMaterial);
|
||||
m_fallbackMaterial = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected override void OnDestroy()
|
||||
{
|
||||
//Debug.Log("*** OnDestroy() ***");
|
||||
|
||||
// Destroy Mesh
|
||||
if (m_mesh != null) DestroyImmediate(m_mesh);
|
||||
|
||||
if (m_MaskMaterial != null)
|
||||
TMP_MaterialManager.ReleaseStencilMaterial(m_MaskMaterial);
|
||||
|
||||
if (m_fallbackMaterial != null)
|
||||
{
|
||||
TMP_MaterialManager.ReleaseFallbackMaterial(m_fallbackMaterial);
|
||||
m_fallbackMaterial = null;
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
// Unregister the event this object was listening to
|
||||
TMPro_EventManager.MATERIAL_PROPERTY_EVENT.Remove(ON_MATERIAL_PROPERTY_CHANGED);
|
||||
TMPro_EventManager.FONT_PROPERTY_EVENT.Remove(ON_FONT_PROPERTY_CHANGED);
|
||||
//TMPro_EventManager.TEXTMESHPRO_PROPERTY_EVENT.Remove(ON_TEXTMESHPRO_PROPERTY_CHANGED);
|
||||
TMPro_EventManager.DRAG_AND_DROP_MATERIAL_EVENT.Remove(ON_DRAG_AND_DROP_MATERIAL);
|
||||
//TMPro_EventManager.TEXT_STYLE_PROPERTY_EVENT.Remove(ON_TEXT_STYLE_CHANGED);
|
||||
TMPro_EventManager.SPRITE_ASSET_PROPERTY_EVENT.Remove(ON_SPRITE_ASSET_PROPERTY_CHANGED);
|
||||
//TMPro_EventManager.TMP_SETTINGS_PROPERTY_EVENT.Remove(ON_TMP_SETTINGS_CHANGED);
|
||||
#endif
|
||||
|
||||
m_isRegisteredForEvents = false;
|
||||
|
||||
RecalculateClipping();
|
||||
|
||||
// Notify parent text object
|
||||
if (m_TextComponent != null)
|
||||
{
|
||||
m_TextComponent.havePropertiesChanged = true;
|
||||
m_TextComponent.SetAllDirty();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if UNITY_EDITOR
|
||||
// Event received when custom material editor properties are changed.
|
||||
void ON_MATERIAL_PROPERTY_CHANGED(bool isChanged, Material mat)
|
||||
{
|
||||
//Debug.Log("*** ON_MATERIAL_PROPERTY_CHANGED ***");
|
||||
if (m_sharedMaterial == null)
|
||||
return;
|
||||
|
||||
int targetMaterialID = mat.GetInstanceID();
|
||||
int sharedMaterialID = m_sharedMaterial.GetInstanceID();
|
||||
int maskingMaterialID = m_MaskMaterial == null ? 0 : m_MaskMaterial.GetInstanceID();
|
||||
int fallbackSourceMaterialID = m_fallbackSourceMaterial == null ? 0 : m_fallbackSourceMaterial.GetInstanceID();
|
||||
|
||||
// Sync culling with parent text object
|
||||
bool hasCullModeProperty = m_sharedMaterial.HasProperty(ShaderUtilities.ShaderTag_CullMode);
|
||||
float cullMode = 0;
|
||||
|
||||
if (hasCullModeProperty)
|
||||
{
|
||||
cullMode = textComponent.fontSharedMaterial.GetFloat(ShaderUtilities.ShaderTag_CullMode);
|
||||
m_sharedMaterial.SetFloat(ShaderUtilities.ShaderTag_CullMode, cullMode);
|
||||
}
|
||||
|
||||
// Filter events and return if the affected material is not this object's material.
|
||||
if (m_fallbackMaterial != null && fallbackSourceMaterialID == targetMaterialID && TMP_Settings.matchMaterialPreset)
|
||||
{
|
||||
TMP_MaterialManager.CopyMaterialPresetProperties(mat, m_fallbackMaterial);
|
||||
|
||||
// Re-sync culling with parent text object
|
||||
m_fallbackMaterial.SetFloat(ShaderUtilities.ShaderTag_CullMode, cullMode);
|
||||
}
|
||||
|
||||
// Make sure material properties are synchronized between the assigned material and masking material.
|
||||
if (m_MaskMaterial != null)
|
||||
{
|
||||
UnityEditor.Undo.RecordObject(m_MaskMaterial, "Material Property Changes");
|
||||
UnityEditor.Undo.RecordObject(m_sharedMaterial, "Material Property Changes");
|
||||
|
||||
if (targetMaterialID == sharedMaterialID)
|
||||
{
|
||||
//Debug.Log("Copy base material properties to masking material if not null.");
|
||||
float stencilID = m_MaskMaterial.GetFloat(ShaderUtilities.ID_StencilID);
|
||||
float stencilComp = m_MaskMaterial.GetFloat(ShaderUtilities.ID_StencilComp);
|
||||
m_MaskMaterial.CopyPropertiesFromMaterial(mat);
|
||||
m_MaskMaterial.shaderKeywords = mat.shaderKeywords;
|
||||
|
||||
m_MaskMaterial.SetFloat(ShaderUtilities.ID_StencilID, stencilID);
|
||||
m_MaskMaterial.SetFloat(ShaderUtilities.ID_StencilComp, stencilComp);
|
||||
}
|
||||
else if (targetMaterialID == maskingMaterialID)
|
||||
{
|
||||
// Update the padding
|
||||
GetPaddingForMaterial(mat);
|
||||
|
||||
m_sharedMaterial.CopyPropertiesFromMaterial(mat);
|
||||
m_sharedMaterial.shaderKeywords = mat.shaderKeywords;
|
||||
m_sharedMaterial.SetFloat(ShaderUtilities.ID_StencilID, 0);
|
||||
m_sharedMaterial.SetFloat(ShaderUtilities.ID_StencilComp, 8);
|
||||
}
|
||||
else if (fallbackSourceMaterialID == targetMaterialID)
|
||||
{
|
||||
float stencilID = m_MaskMaterial.GetFloat(ShaderUtilities.ID_StencilID);
|
||||
float stencilComp = m_MaskMaterial.GetFloat(ShaderUtilities.ID_StencilComp);
|
||||
m_MaskMaterial.CopyPropertiesFromMaterial(m_fallbackMaterial);
|
||||
m_MaskMaterial.shaderKeywords = m_fallbackMaterial.shaderKeywords;
|
||||
|
||||
m_MaskMaterial.SetFloat(ShaderUtilities.ID_StencilID, stencilID);
|
||||
m_MaskMaterial.SetFloat(ShaderUtilities.ID_StencilComp, stencilComp);
|
||||
}
|
||||
|
||||
// Re-sync culling with parent text object
|
||||
if (hasCullModeProperty)
|
||||
m_MaskMaterial.SetFloat(ShaderUtilities.ShaderTag_CullMode, cullMode);
|
||||
}
|
||||
|
||||
m_padding = GetPaddingForMaterial();
|
||||
|
||||
SetVerticesDirty();
|
||||
m_ShouldRecalculateStencil = true;
|
||||
RecalculateClipping();
|
||||
RecalculateMasking();
|
||||
}
|
||||
|
||||
|
||||
// Event to Track Material Changed resulting from Drag-n-drop.
|
||||
void ON_DRAG_AND_DROP_MATERIAL(GameObject obj, Material currentMaterial, Material newMaterial)
|
||||
{
|
||||
// Check if event applies to this current object
|
||||
#if UNITY_2018_2_OR_NEWER
|
||||
if (obj == gameObject || UnityEditor.PrefabUtility.GetCorrespondingObjectFromSource(gameObject) == obj)
|
||||
#else
|
||||
if (obj == gameObject || UnityEditor.PrefabUtility.GetPrefabParent(gameObject) == obj)
|
||||
#endif
|
||||
{
|
||||
if (!m_isDefaultMaterial) return;
|
||||
|
||||
// Make sure we have a valid reference to the renderer.
|
||||
//if (m_canvasRenderer == null) m_canvasRenderer = GetComponent<CanvasRenderer>();
|
||||
|
||||
UnityEditor.Undo.RecordObject(this, "Material Assignment");
|
||||
UnityEditor.Undo.RecordObject(canvasRenderer, "Material Assignment");
|
||||
|
||||
SetSharedMaterial(newMaterial);
|
||||
m_TextComponent.havePropertiesChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Event received when font asset properties are changed in Font Inspector
|
||||
void ON_SPRITE_ASSET_PROPERTY_CHANGED(bool isChanged, UnityEngine.Object obj)
|
||||
{
|
||||
//if (spriteSheet != null && (obj as TMP_SpriteAsset == m_spriteAsset || obj as Texture2D == m_spriteAsset.spriteSheet))
|
||||
//{
|
||||
if (m_TextComponent != null)
|
||||
{
|
||||
m_TextComponent.havePropertiesChanged = true;
|
||||
//m_TextComponent.SetVerticesDirty();
|
||||
}
|
||||
|
||||
//}
|
||||
}
|
||||
|
||||
// Event received when font asset properties are changed in Font Inspector
|
||||
void ON_FONT_PROPERTY_CHANGED(bool isChanged, Object fontAsset)
|
||||
{
|
||||
if (m_fontAsset != null && fontAsset.GetInstanceID() == m_fontAsset.GetInstanceID())
|
||||
{
|
||||
// Copy Normal and Bold Weight
|
||||
if (m_fallbackMaterial != null)
|
||||
{
|
||||
if (TMP_Settings.matchMaterialPreset)
|
||||
{
|
||||
TMP_MaterialManager.ReleaseFallbackMaterial(m_fallbackMaterial);
|
||||
TMP_MaterialManager.CleanupFallbackMaterials();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Event received when the TMP Settings are changed.
|
||||
/// </summary>
|
||||
void ON_TMP_SETTINGS_CHANGED()
|
||||
{
|
||||
//Debug.Log("TMP Setting have changed.");
|
||||
//SetVerticesDirty();
|
||||
//SetMaterialDirty();
|
||||
}
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
protected override void OnTransformParentChanged()
|
||||
{
|
||||
if (!this.IsActive())
|
||||
return;
|
||||
|
||||
m_ShouldRecalculateStencil = true;
|
||||
RecalculateClipping();
|
||||
RecalculateMasking();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function returning the modified material for masking if necessary.
|
||||
/// </summary>
|
||||
/// <param name="baseMaterial"></param>
|
||||
/// <returns></returns>
|
||||
public override Material GetModifiedMaterial(Material baseMaterial)
|
||||
{
|
||||
Material mat = baseMaterial;
|
||||
|
||||
if (m_ShouldRecalculateStencil)
|
||||
{
|
||||
var rootCanvas = MaskUtilities.FindRootSortOverrideCanvas(transform);
|
||||
m_StencilValue = maskable ? MaskUtilities.GetStencilDepth(transform, rootCanvas) : 0;
|
||||
m_ShouldRecalculateStencil = false;
|
||||
}
|
||||
|
||||
if (m_StencilValue > 0)
|
||||
{
|
||||
var maskMat = StencilMaterial.Add(mat, (1 << m_StencilValue) - 1, StencilOp.Keep, CompareFunction.Equal, ColorWriteMask.All, (1 << m_StencilValue) - 1, 0);
|
||||
StencilMaterial.Remove(m_MaskMaterial);
|
||||
m_MaskMaterial = maskMat;
|
||||
mat = m_MaskMaterial;
|
||||
}
|
||||
|
||||
return mat;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function called when the padding value for the material needs to be re-calculated.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public float GetPaddingForMaterial()
|
||||
{
|
||||
float padding = ShaderUtilities.GetPadding(m_sharedMaterial, m_TextComponent.extraPadding, m_TextComponent.isUsingBold);
|
||||
|
||||
return padding;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function called when the padding value for the material needs to be re-calculated.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public float GetPaddingForMaterial(Material mat)
|
||||
{
|
||||
float padding = ShaderUtilities.GetPadding(mat, m_TextComponent.extraPadding, m_TextComponent.isUsingBold);
|
||||
|
||||
return padding;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="isExtraPadding"></param>
|
||||
/// <param name="isBold"></param>
|
||||
public void UpdateMeshPadding(bool isExtraPadding, bool isUsingBold)
|
||||
{
|
||||
m_padding = ShaderUtilities.GetPadding(m_sharedMaterial, isExtraPadding, isUsingBold);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public override void SetAllDirty()
|
||||
{
|
||||
//SetLayoutDirty();
|
||||
//SetVerticesDirty();
|
||||
//SetMaterialDirty();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public override void SetVerticesDirty()
|
||||
{
|
||||
if (!this.IsActive())
|
||||
return;
|
||||
|
||||
// This is called on the parent TextMeshPro component.
|
||||
if (m_TextComponent != null)
|
||||
{
|
||||
m_TextComponent.havePropertiesChanged = true;
|
||||
m_TextComponent.SetVerticesDirty();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public override void SetLayoutDirty()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public override void SetMaterialDirty()
|
||||
{
|
||||
//Debug.Log("*** STO-UI - SetMaterialDirty() *** FRAME (" + Time.frameCount + ")");
|
||||
|
||||
//if (!this.IsActive())
|
||||
// return;
|
||||
|
||||
m_materialDirty = true;
|
||||
|
||||
UpdateMaterial();
|
||||
|
||||
if (m_OnDirtyMaterialCallback != null)
|
||||
m_OnDirtyMaterialCallback();
|
||||
|
||||
//TMP_ITextElementUpdateManager.RegisterTextElementForGraphicRebuild(this);
|
||||
|
||||
//TMP_UpdateRegistry.RegisterCanvasElementForGraphicRebuild((ICanvasElement)this);
|
||||
//m_TextComponent.SetMaterialDirty();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public void SetPivotDirty()
|
||||
{
|
||||
if (!this.IsActive())
|
||||
return;
|
||||
|
||||
this.rectTransform.pivot = m_TextComponent.rectTransform.pivot;
|
||||
}
|
||||
|
||||
Transform GetRootCanvasTransform()
|
||||
{
|
||||
if (m_RootCanvasTransform == null)
|
||||
m_RootCanvasTransform = m_TextComponent.canvas.rootCanvas.transform;
|
||||
|
||||
return m_RootCanvasTransform;
|
||||
}
|
||||
private Transform m_RootCanvasTransform;
|
||||
|
||||
/// <summary>
|
||||
/// Override Cull function as this is handled by the parent text object.
|
||||
/// </summary>
|
||||
/// <param name="clipRect"></param>
|
||||
/// <param name="validRect"></param>
|
||||
public override void Cull(Rect clipRect, bool validRect)
|
||||
{
|
||||
// Do nothing as this functionality is handled by the parent text object.
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
protected override void UpdateGeometry()
|
||||
{
|
||||
// Need to override to prevent Unity from changing the geometry of the object.
|
||||
//Debug.Log("UpdateGeometry()");
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="update"></param>
|
||||
public override void Rebuild(CanvasUpdate update)
|
||||
{
|
||||
if (update == CanvasUpdate.PreRender)
|
||||
{
|
||||
if (!m_materialDirty) return;
|
||||
|
||||
UpdateMaterial();
|
||||
m_materialDirty = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function to update the material from the parent text object.
|
||||
/// </summary>
|
||||
public void RefreshMaterial()
|
||||
{
|
||||
UpdateMaterial();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
protected override void UpdateMaterial()
|
||||
{
|
||||
//Debug.Log("*** STO-UI - UpdateMaterial() *** FRAME (" + Time.frameCount + ")");
|
||||
|
||||
if (m_sharedMaterial == null)
|
||||
return;
|
||||
|
||||
//if (canvasRenderer == null) m_canvasRenderer = this.canvasRenderer;
|
||||
|
||||
// Special handling to keep the Culling of the material in sync with parent text object
|
||||
if (m_sharedMaterial.HasProperty(ShaderUtilities.ShaderTag_CullMode))
|
||||
{
|
||||
float cullMode = textComponent.fontSharedMaterial.GetFloat(ShaderUtilities.ShaderTag_CullMode);
|
||||
m_sharedMaterial.SetFloat(ShaderUtilities.ShaderTag_CullMode, cullMode);
|
||||
}
|
||||
|
||||
canvasRenderer.materialCount = 1;
|
||||
canvasRenderer.SetMaterial(materialForRendering, 0);
|
||||
//canvasRenderer.SetTexture(materialForRendering.mainTexture);
|
||||
|
||||
#if UNITY_EDITOR
|
||||
if (m_sharedMaterial != null && gameObject.name != "TMP SubMeshUI [" + m_sharedMaterial.name + "]")
|
||||
gameObject.name = "TMP SubMeshUI [" + m_sharedMaterial.name + "]";
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
// IClippable implementation
|
||||
/// <summary>
|
||||
/// Method called when the state of a parent changes.
|
||||
/// </summary>
|
||||
public override void RecalculateClipping()
|
||||
{
|
||||
//Debug.Log("*** RecalculateClipping() ***");
|
||||
base.RecalculateClipping();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
// public override void RecalculateMasking()
|
||||
// {
|
||||
// //Debug.Log("RecalculateMasking()");
|
||||
//
|
||||
// this.m_ShouldRecalculateStencil = true;
|
||||
// SetMaterialDirty();
|
||||
// }
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Method which returns an instance of the shared material
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
Material GetMaterial()
|
||||
{
|
||||
// Make sure we have a valid reference to the renderer.
|
||||
//if (m_renderer == null) m_renderer = GetComponent<Renderer>();
|
||||
|
||||
//if (m_material == null || m_isNewSharedMaterial)
|
||||
//{
|
||||
// m_renderer.material = m_sharedMaterial;
|
||||
// m_material = m_renderer.material;
|
||||
// m_sharedMaterial = m_material;
|
||||
// m_padding = ShaderUtilities.GetPadding(m_sharedMaterial, m_TextMeshPro.extraPadding, false);
|
||||
// m_isNewSharedMaterial = false;
|
||||
//}
|
||||
|
||||
return m_sharedMaterial;
|
||||
}
|
||||
|
||||
|
||||
// Function called internally when a new material is assigned via the fontMaterial property.
|
||||
Material GetMaterial(Material mat)
|
||||
{
|
||||
// Check in case Object is disabled. If so, we don't have a valid reference to the Renderer.
|
||||
// This can occur when the Duplicate Material Context menu is used on an inactive object.
|
||||
//if (m_renderer == null)
|
||||
// m_renderer = GetComponent<Renderer>();
|
||||
|
||||
// Create Instance Material only if the new material is not the same instance previously used.
|
||||
if (m_material == null || m_material.GetInstanceID() != mat.GetInstanceID())
|
||||
m_material = CreateMaterialInstance(mat);
|
||||
|
||||
m_sharedMaterial = m_material;
|
||||
|
||||
// Compute and Set new padding values for this new material.
|
||||
m_padding = GetPaddingForMaterial();
|
||||
|
||||
SetVerticesDirty();
|
||||
SetMaterialDirty();
|
||||
|
||||
return m_sharedMaterial;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Method used to create an instance of the material
|
||||
/// </summary>
|
||||
/// <param name="source"></param>
|
||||
/// <returns></returns>
|
||||
Material CreateMaterialInstance(Material source)
|
||||
{
|
||||
Material mat = new Material(source);
|
||||
mat.shaderKeywords = source.shaderKeywords;
|
||||
mat.name += " (Instance)";
|
||||
|
||||
return mat;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Method returning the shared material assigned to the text object.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
Material GetSharedMaterial()
|
||||
{
|
||||
//if (canvasRenderer == null)
|
||||
// canvasRenderer = GetComponent<CanvasRenderer>();
|
||||
|
||||
return canvasRenderer.GetMaterial();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Method to set the shared material.
|
||||
/// </summary>
|
||||
/// <param name="mat"></param>
|
||||
void SetSharedMaterial(Material mat)
|
||||
{
|
||||
//Debug.Log("*** SetSharedMaterial UI() *** FRAME (" + Time.frameCount + ")");
|
||||
|
||||
// Assign new material.
|
||||
m_sharedMaterial = mat;
|
||||
m_Material = m_sharedMaterial;
|
||||
|
||||
//m_isDefaultMaterial = false;
|
||||
//if (mat.GetInstanceID() == m_fontAsset.material.GetInstanceID())
|
||||
// m_isDefaultMaterial = true;
|
||||
|
||||
// Compute and Set new padding values for this new material.
|
||||
m_padding = GetPaddingForMaterial();
|
||||
|
||||
//SetVerticesDirty();
|
||||
SetMaterialDirty();
|
||||
|
||||
#if UNITY_EDITOR
|
||||
//if (m_sharedMaterial != null)
|
||||
// gameObject.name = "TMP SubMesh [" + m_sharedMaterial.name + "]";
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 058cba836c1846c3aa1c5fd2e28aea77
|
||||
timeCreated: 1454709708
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,12 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 5143f58107604835ab1a5efa2d8818fd
|
||||
timeCreated: 1445841744
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,69 @@
|
|||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEngine.TextCore;
|
||||
|
||||
namespace TMPro
|
||||
{
|
||||
public enum TextElementType : byte
|
||||
{
|
||||
Character = 0x1,
|
||||
Sprite = 0x2,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Base class for all text elements like Character and SpriteCharacter.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class TMP_TextElement
|
||||
{
|
||||
/// <summary>
|
||||
/// The type of text element which can be a character or sprite.
|
||||
/// </summary>
|
||||
public TextElementType elementType { get { return m_ElementType; } }
|
||||
|
||||
/// <summary>
|
||||
/// The unicode value (code point) of the character.
|
||||
/// </summary>
|
||||
public uint unicode { get { return m_Unicode; } set { m_Unicode = value; } }
|
||||
|
||||
/// <summary>
|
||||
/// The Text Asset to which this Text Element belongs.
|
||||
/// </summary>
|
||||
public TMP_Asset textAsset { get { return m_TextAsset; } set { m_TextAsset = value; } }
|
||||
|
||||
/// <summary>
|
||||
/// The glyph used by this text element.
|
||||
/// </summary>
|
||||
public Glyph glyph { get { return m_Glyph; } set { m_Glyph = value; } }
|
||||
|
||||
/// <summary>
|
||||
/// The index of the glyph used by this text element.
|
||||
/// </summary>
|
||||
public uint glyphIndex { get { return m_GlyphIndex; } set { m_GlyphIndex = value; } }
|
||||
|
||||
/// <summary>
|
||||
/// The relative scale of the character.
|
||||
/// </summary>
|
||||
public float scale { get { return m_Scale; } set { m_Scale = value; } }
|
||||
|
||||
// =============================================
|
||||
// Private backing fields for public properties.
|
||||
// =============================================
|
||||
|
||||
[SerializeField]
|
||||
protected TextElementType m_ElementType;
|
||||
|
||||
[SerializeField]
|
||||
internal uint m_Unicode;
|
||||
|
||||
internal TMP_Asset m_TextAsset;
|
||||
|
||||
internal Glyph m_Glyph;
|
||||
|
||||
[SerializeField]
|
||||
internal uint m_GlyphIndex;
|
||||
|
||||
[SerializeField]
|
||||
internal float m_Scale;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 543674eec776b1442a192c932e6cd9b3
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,25 @@
|
|||
using UnityEngine;
|
||||
using System;
|
||||
using System.Collections;
|
||||
|
||||
|
||||
namespace TMPro
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Base class for all text elements like characters (glyphs) and sprites.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class TMP_TextElement_Legacy
|
||||
{
|
||||
public int id;
|
||||
public float x;
|
||||
public float y;
|
||||
public float width;
|
||||
public float height;
|
||||
public float xOffset;
|
||||
public float yOffset;
|
||||
public float xAdvance;
|
||||
public float scale;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 87ab1bebe13f41f89d5427e7d2c34d58
|
||||
timeCreated: 1448407070
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,312 @@
|
|||
using UnityEngine;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
|
||||
namespace TMPro
|
||||
{
|
||||
/// <summary>
|
||||
/// Class which contains information about every element contained within the text object.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class TMP_TextInfo
|
||||
{
|
||||
internal static Vector2 k_InfinityVectorPositive = new Vector2(32767, 32767);
|
||||
internal static Vector2 k_InfinityVectorNegative = new Vector2(-32767, -32767);
|
||||
|
||||
public TMP_Text textComponent;
|
||||
|
||||
public int characterCount;
|
||||
public int spriteCount;
|
||||
public int spaceCount;
|
||||
public int wordCount;
|
||||
public int linkCount;
|
||||
public int lineCount;
|
||||
public int pageCount;
|
||||
|
||||
public int materialCount;
|
||||
|
||||
public TMP_CharacterInfo[] characterInfo;
|
||||
public TMP_WordInfo[] wordInfo;
|
||||
public TMP_LinkInfo[] linkInfo;
|
||||
public TMP_LineInfo[] lineInfo;
|
||||
public TMP_PageInfo[] pageInfo;
|
||||
public TMP_MeshInfo[] meshInfo;
|
||||
|
||||
private TMP_MeshInfo[] m_CachedMeshInfo;
|
||||
|
||||
// Default Constructor
|
||||
public TMP_TextInfo()
|
||||
{
|
||||
characterInfo = new TMP_CharacterInfo[8];
|
||||
wordInfo = new TMP_WordInfo[16];
|
||||
linkInfo = new TMP_LinkInfo[0];
|
||||
lineInfo = new TMP_LineInfo[2];
|
||||
pageInfo = new TMP_PageInfo[4];
|
||||
|
||||
meshInfo = new TMP_MeshInfo[1];
|
||||
}
|
||||
|
||||
internal TMP_TextInfo(int characterCount)
|
||||
{
|
||||
characterInfo = new TMP_CharacterInfo[characterCount];
|
||||
wordInfo = new TMP_WordInfo[16];
|
||||
linkInfo = new TMP_LinkInfo[0];
|
||||
lineInfo = new TMP_LineInfo[2];
|
||||
pageInfo = new TMP_PageInfo[4];
|
||||
|
||||
meshInfo = new TMP_MeshInfo[1];
|
||||
}
|
||||
|
||||
public TMP_TextInfo(TMP_Text textComponent)
|
||||
{
|
||||
this.textComponent = textComponent;
|
||||
|
||||
characterInfo = new TMP_CharacterInfo[8];
|
||||
|
||||
wordInfo = new TMP_WordInfo[4];
|
||||
linkInfo = new TMP_LinkInfo[0];
|
||||
|
||||
lineInfo = new TMP_LineInfo[2];
|
||||
pageInfo = new TMP_PageInfo[4];
|
||||
|
||||
meshInfo = new TMP_MeshInfo[1];
|
||||
meshInfo[0].mesh = textComponent.mesh;
|
||||
materialCount = 1;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function to clear the counters of the text object.
|
||||
/// </summary>
|
||||
public void Clear()
|
||||
{
|
||||
characterCount = 0;
|
||||
spaceCount = 0;
|
||||
wordCount = 0;
|
||||
linkCount = 0;
|
||||
lineCount = 0;
|
||||
pageCount = 0;
|
||||
spriteCount = 0;
|
||||
|
||||
for (int i = 0; i < this.meshInfo.Length; i++)
|
||||
{
|
||||
this.meshInfo[i].vertexCount = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
internal void ClearAllData()
|
||||
{
|
||||
characterCount = 0;
|
||||
spaceCount = 0;
|
||||
wordCount = 0;
|
||||
linkCount = 0;
|
||||
lineCount = 0;
|
||||
pageCount = 0;
|
||||
spriteCount = 0;
|
||||
|
||||
this.characterInfo = new TMP_CharacterInfo[4];
|
||||
this.wordInfo = new TMP_WordInfo[1];
|
||||
this.lineInfo = new TMP_LineInfo[1];
|
||||
this.pageInfo = new TMP_PageInfo[1];
|
||||
this.linkInfo = new TMP_LinkInfo[0];
|
||||
|
||||
materialCount = 0;
|
||||
|
||||
this.meshInfo = new TMP_MeshInfo[1];
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function to clear the content of the MeshInfo array while preserving the Triangles, Normals and Tangents.
|
||||
/// </summary>
|
||||
public void ClearMeshInfo(bool updateMesh)
|
||||
{
|
||||
for (int i = 0; i < this.meshInfo.Length; i++)
|
||||
this.meshInfo[i].Clear(updateMesh);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function to clear the content of all the MeshInfo arrays while preserving their Triangles, Normals and Tangents.
|
||||
/// </summary>
|
||||
public void ClearAllMeshInfo()
|
||||
{
|
||||
for (int i = 0; i < this.meshInfo.Length; i++)
|
||||
this.meshInfo[i].Clear(true);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public void ResetVertexLayout(bool isVolumetric)
|
||||
{
|
||||
for (int i = 0; i < this.meshInfo.Length; i++)
|
||||
this.meshInfo[i].ResizeMeshInfo(0, isVolumetric);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function used to mark unused vertices as degenerate.
|
||||
/// </summary>
|
||||
/// <param name="materials"></param>
|
||||
public void ClearUnusedVertices(MaterialReference[] materials)
|
||||
{
|
||||
for (int i = 0; i < meshInfo.Length; i++)
|
||||
{
|
||||
int start = 0; // materials[i].referenceCount * 4;
|
||||
meshInfo[i].ClearUnusedVertices(start);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function to clear and initialize the lineInfo array.
|
||||
/// </summary>
|
||||
public void ClearLineInfo()
|
||||
{
|
||||
if (this.lineInfo == null)
|
||||
this.lineInfo = new TMP_LineInfo[2];
|
||||
|
||||
int length = this.lineInfo.Length;
|
||||
|
||||
for (int i = 0; i < length; i++)
|
||||
{
|
||||
this.lineInfo[i].characterCount = 0;
|
||||
this.lineInfo[i].spaceCount = 0;
|
||||
this.lineInfo[i].wordCount = 0;
|
||||
this.lineInfo[i].controlCharacterCount = 0;
|
||||
this.lineInfo[i].width = 0;
|
||||
|
||||
this.lineInfo[i].ascender = k_InfinityVectorNegative.x;
|
||||
this.lineInfo[i].descender = k_InfinityVectorPositive.x;
|
||||
|
||||
this.lineInfo[i].marginLeft = 0;
|
||||
this.lineInfo[i].marginRight = 0;
|
||||
|
||||
this.lineInfo[i].lineExtents.min = k_InfinityVectorPositive;
|
||||
this.lineInfo[i].lineExtents.max = k_InfinityVectorNegative;
|
||||
|
||||
this.lineInfo[i].maxAdvance = 0;
|
||||
//this.lineInfo[i].maxScale = 0;
|
||||
}
|
||||
}
|
||||
|
||||
internal void ClearPageInfo()
|
||||
{
|
||||
if (this.pageInfo == null)
|
||||
this.pageInfo = new TMP_PageInfo[2];
|
||||
|
||||
int length = this.pageInfo.Length;
|
||||
|
||||
for (int i = 0; i < length; i++)
|
||||
{
|
||||
this.pageInfo[i].firstCharacterIndex = 0;
|
||||
this.pageInfo[i].lastCharacterIndex = 0;
|
||||
this.pageInfo[i].ascender = -32767;
|
||||
this.pageInfo[i].baseLine = 0;
|
||||
this.pageInfo[i].descender = 32767;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function to copy the MeshInfo Arrays and their primary vertex data content.
|
||||
/// </summary>
|
||||
/// <returns>A copy of the MeshInfo[]</returns>
|
||||
public TMP_MeshInfo[] CopyMeshInfoVertexData()
|
||||
{
|
||||
if (m_CachedMeshInfo == null || m_CachedMeshInfo.Length != meshInfo.Length)
|
||||
{
|
||||
m_CachedMeshInfo = new TMP_MeshInfo[meshInfo.Length];
|
||||
|
||||
// Initialize all the vertex data arrays
|
||||
for (int i = 0; i < m_CachedMeshInfo.Length; i++)
|
||||
{
|
||||
int length = meshInfo[i].vertices.Length;
|
||||
|
||||
m_CachedMeshInfo[i].vertices = new Vector3[length];
|
||||
m_CachedMeshInfo[i].uvs0 = new Vector2[length];
|
||||
m_CachedMeshInfo[i].uvs2 = new Vector2[length];
|
||||
m_CachedMeshInfo[i].colors32 = new Color32[length];
|
||||
|
||||
//m_CachedMeshInfo[i].normals = new Vector3[length];
|
||||
//m_CachedMeshInfo[i].tangents = new Vector4[length];
|
||||
//m_CachedMeshInfo[i].triangles = new int[meshInfo[i].triangles.Length];
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < m_CachedMeshInfo.Length; i++)
|
||||
{
|
||||
int length = meshInfo[i].vertices.Length;
|
||||
|
||||
if (m_CachedMeshInfo[i].vertices.Length != length)
|
||||
{
|
||||
m_CachedMeshInfo[i].vertices = new Vector3[length];
|
||||
m_CachedMeshInfo[i].uvs0 = new Vector2[length];
|
||||
m_CachedMeshInfo[i].uvs2 = new Vector2[length];
|
||||
m_CachedMeshInfo[i].colors32 = new Color32[length];
|
||||
|
||||
//m_CachedMeshInfo[i].normals = new Vector3[length];
|
||||
//m_CachedMeshInfo[i].tangents = new Vector4[length];
|
||||
//m_CachedMeshInfo[i].triangles = new int[meshInfo[i].triangles.Length];
|
||||
}
|
||||
|
||||
|
||||
// Only copy the primary vertex data
|
||||
Array.Copy(meshInfo[i].vertices, m_CachedMeshInfo[i].vertices, length);
|
||||
Array.Copy(meshInfo[i].uvs0, m_CachedMeshInfo[i].uvs0, length);
|
||||
Array.Copy(meshInfo[i].uvs2, m_CachedMeshInfo[i].uvs2, length);
|
||||
Array.Copy(meshInfo[i].colors32, m_CachedMeshInfo[i].colors32, length);
|
||||
|
||||
//Array.Copy(meshInfo[i].normals, m_CachedMeshInfo[i].normals, length);
|
||||
//Array.Copy(meshInfo[i].tangents, m_CachedMeshInfo[i].tangents, length);
|
||||
//Array.Copy(meshInfo[i].triangles, m_CachedMeshInfo[i].triangles, meshInfo[i].triangles.Length);
|
||||
}
|
||||
|
||||
return m_CachedMeshInfo;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function to resize any of the structure contained in the TMP_TextInfo class.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="array"></param>
|
||||
/// <param name="size"></param>
|
||||
public static void Resize<T> (ref T[] array, int size)
|
||||
{
|
||||
// Allocated to the next power of two
|
||||
int newSize = size > 1024 ? size + 256 : Mathf.NextPowerOfTwo(size);
|
||||
|
||||
Array.Resize(ref array, newSize);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function to resize any of the structure contained in the TMP_TextInfo class.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="array"></param>
|
||||
/// <param name="size"></param>
|
||||
/// <param name="isFixedSize"></param>
|
||||
public static void Resize<T>(ref T[] array, int size, bool isBlockAllocated)
|
||||
{
|
||||
if (isBlockAllocated) size = size > 1024 ? size + 256 : Mathf.NextPowerOfTwo(size);
|
||||
|
||||
if (size == array.Length) return;
|
||||
|
||||
//Debug.Log("Resizing TextInfo from [" + array.Length + "] to [" + size + "]");
|
||||
|
||||
Array.Resize(ref array, size);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 4ae64f3f72004807a9f919f9c27af0db
|
||||
timeCreated: 1446589998
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,146 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace TMPro
|
||||
{
|
||||
public class TMP_TextParsingUtilities
|
||||
{
|
||||
private static readonly TMP_TextParsingUtilities s_Instance = new TMP_TextParsingUtilities();
|
||||
|
||||
/// <summary>
|
||||
/// Default constructor
|
||||
/// </summary>
|
||||
static TMP_TextParsingUtilities() { }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Get a singleton instance of the TextModuleUtilities.
|
||||
/// </summary>
|
||||
public static TMP_TextParsingUtilities instance
|
||||
{
|
||||
get { return s_Instance; }
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function returning the hashcode value of a given string.
|
||||
/// </summary>
|
||||
public static int GetHashCode(string s)
|
||||
{
|
||||
int hashCode = 0;
|
||||
|
||||
for (int i = 0; i < s.Length; i++)
|
||||
hashCode = ((hashCode << 5) + hashCode) ^ ToUpperASCIIFast(s[i]);
|
||||
|
||||
return hashCode;
|
||||
}
|
||||
|
||||
public static int GetHashCodeCaseSensitive(string s)
|
||||
{
|
||||
int hashCode = 0;
|
||||
|
||||
for (int i = 0; i < s.Length; i++)
|
||||
hashCode = ((hashCode << 5) + hashCode) ^ s[i];
|
||||
|
||||
return hashCode;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Table used to convert character to lowercase.
|
||||
/// </summary>
|
||||
const string k_LookupStringL = "-------------------------------- !-#$%&-()*+,-./0123456789:;<=>?@abcdefghijklmnopqrstuvwxyz[-]^_`abcdefghijklmnopqrstuvwxyz{|}~-";
|
||||
|
||||
/// <summary>
|
||||
/// Table used to convert character to uppercase.
|
||||
/// </summary>
|
||||
const string k_LookupStringU = "-------------------------------- !-#$%&-()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[-]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~-";
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Get lowercase version of this ASCII character.
|
||||
/// </summary>
|
||||
//[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static char ToLowerASCIIFast(char c)
|
||||
{
|
||||
if (c > k_LookupStringL.Length - 1)
|
||||
return c;
|
||||
|
||||
return k_LookupStringL[c];
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Get uppercase version of this ASCII character.
|
||||
/// </summary>
|
||||
//[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static char ToUpperASCIIFast(char c)
|
||||
{
|
||||
if (c > k_LookupStringU.Length - 1)
|
||||
return c;
|
||||
|
||||
return k_LookupStringU[c];
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Get uppercase version of this ASCII character.
|
||||
/// </summary>
|
||||
//[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static uint ToUpperASCIIFast(uint c)
|
||||
{
|
||||
if (c > k_LookupStringU.Length - 1)
|
||||
return c;
|
||||
|
||||
return k_LookupStringU[(int)c];
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Get lowercase version of this ASCII character.
|
||||
/// </summary>
|
||||
//[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static uint ToLowerASCIIFast(uint c)
|
||||
{
|
||||
if (c > k_LookupStringL.Length - 1)
|
||||
return c;
|
||||
|
||||
return k_LookupStringL[(int)c];
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Check if Unicode is High Surrogate
|
||||
/// </summary>
|
||||
/// <param name="c"></param>
|
||||
/// <returns></returns>
|
||||
//[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool IsHighSurrogate(uint c)
|
||||
{
|
||||
return c > 0xD800 && c < 0xDBFF;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check if Unicode is Low Surrogate
|
||||
/// </summary>
|
||||
/// <param name="c"></param>
|
||||
/// <returns></returns>
|
||||
//[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool IsLowSurrogate(uint c)
|
||||
{
|
||||
return c > 0xDC00 && c < 0xDFFF;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="highSurrogate"></param>
|
||||
/// <param name="lowSurrogate"></param>
|
||||
/// <returns></returns>
|
||||
internal static uint ConvertToUTF32(uint highSurrogate, uint lowSurrogate)
|
||||
{
|
||||
return ((highSurrogate - CodePoint.HIGH_SURROGATE_START) * 0x400) + ((lowSurrogate - CodePoint.LOW_SURROGATE_START) + CodePoint.UNICODE_PLANE01_START);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 6ad632cbcc87f634d9b86006cdffdaf5
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,400 @@
|
|||
using System;
|
||||
using System.Diagnostics;
|
||||
using UnityEngine;
|
||||
|
||||
namespace TMPro
|
||||
{
|
||||
/// <summary>
|
||||
/// Structure used to track basic XML tags which are binary (on / off)
|
||||
/// </summary>
|
||||
public struct TMP_FontStyleStack
|
||||
{
|
||||
public byte bold;
|
||||
public byte italic;
|
||||
public byte underline;
|
||||
public byte strikethrough;
|
||||
public byte highlight;
|
||||
public byte superscript;
|
||||
public byte subscript;
|
||||
public byte uppercase;
|
||||
public byte lowercase;
|
||||
public byte smallcaps;
|
||||
|
||||
/// <summary>
|
||||
/// Clear the basic XML tag stack.
|
||||
/// </summary>
|
||||
public void Clear()
|
||||
{
|
||||
bold = 0;
|
||||
italic = 0;
|
||||
underline = 0;
|
||||
strikethrough = 0;
|
||||
highlight = 0;
|
||||
superscript = 0;
|
||||
subscript = 0;
|
||||
uppercase = 0;
|
||||
lowercase = 0;
|
||||
smallcaps = 0;
|
||||
}
|
||||
|
||||
public byte Add(FontStyles style)
|
||||
{
|
||||
switch (style)
|
||||
{
|
||||
case FontStyles.Bold:
|
||||
bold++;
|
||||
return bold;
|
||||
case FontStyles.Italic:
|
||||
italic++;
|
||||
return italic;
|
||||
case FontStyles.Underline:
|
||||
underline++;
|
||||
return underline;
|
||||
case FontStyles.UpperCase:
|
||||
uppercase++;
|
||||
return uppercase;
|
||||
case FontStyles.LowerCase:
|
||||
lowercase++;
|
||||
return lowercase;
|
||||
case FontStyles.Strikethrough:
|
||||
strikethrough++;
|
||||
return strikethrough;
|
||||
case FontStyles.Superscript:
|
||||
superscript++;
|
||||
return superscript;
|
||||
case FontStyles.Subscript:
|
||||
subscript++;
|
||||
return subscript;
|
||||
case FontStyles.Highlight:
|
||||
highlight++;
|
||||
return highlight;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public byte Remove(FontStyles style)
|
||||
{
|
||||
switch (style)
|
||||
{
|
||||
case FontStyles.Bold:
|
||||
if (bold > 1)
|
||||
bold--;
|
||||
else
|
||||
bold = 0;
|
||||
return bold;
|
||||
case FontStyles.Italic:
|
||||
if (italic > 1)
|
||||
italic--;
|
||||
else
|
||||
italic = 0;
|
||||
return italic;
|
||||
case FontStyles.Underline:
|
||||
if (underline > 1)
|
||||
underline--;
|
||||
else
|
||||
underline = 0;
|
||||
return underline;
|
||||
case FontStyles.UpperCase:
|
||||
if (uppercase > 1)
|
||||
uppercase--;
|
||||
else
|
||||
uppercase = 0;
|
||||
return uppercase;
|
||||
case FontStyles.LowerCase:
|
||||
if (lowercase > 1)
|
||||
lowercase--;
|
||||
else
|
||||
lowercase = 0;
|
||||
return lowercase;
|
||||
case FontStyles.Strikethrough:
|
||||
if (strikethrough > 1)
|
||||
strikethrough--;
|
||||
else
|
||||
strikethrough = 0;
|
||||
return strikethrough;
|
||||
case FontStyles.Highlight:
|
||||
if (highlight > 1)
|
||||
highlight--;
|
||||
else
|
||||
highlight = 0;
|
||||
return highlight;
|
||||
case FontStyles.Superscript:
|
||||
if (superscript > 1)
|
||||
superscript--;
|
||||
else
|
||||
superscript = 0;
|
||||
return superscript;
|
||||
case FontStyles.Subscript:
|
||||
if (subscript > 1)
|
||||
subscript--;
|
||||
else
|
||||
subscript = 0;
|
||||
return subscript;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Structure used to track XML tags of various types.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
[DebuggerDisplay("Item count = {m_Count}")]
|
||||
public struct TMP_TextProcessingStack<T>
|
||||
{
|
||||
public T[] itemStack;
|
||||
public int index;
|
||||
|
||||
T m_DefaultItem;
|
||||
int m_Capacity;
|
||||
int m_RolloverSize;
|
||||
int m_Count;
|
||||
|
||||
const int k_DefaultCapacity = 4;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Constructor to create a new item stack.
|
||||
/// </summary>
|
||||
/// <param name="stack"></param>
|
||||
public TMP_TextProcessingStack(T[] stack)
|
||||
{
|
||||
itemStack = stack;
|
||||
m_Capacity = stack.Length;
|
||||
index = 0;
|
||||
m_RolloverSize = 0;
|
||||
|
||||
m_DefaultItem = default(T);
|
||||
m_Count = 0;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Constructor for a new item stack with the given capacity.
|
||||
/// </summary>
|
||||
/// <param name="capacity"></param>
|
||||
public TMP_TextProcessingStack(int capacity)
|
||||
{
|
||||
itemStack = new T[capacity];
|
||||
m_Capacity = capacity;
|
||||
index = 0;
|
||||
m_RolloverSize = 0;
|
||||
|
||||
m_DefaultItem = default(T);
|
||||
m_Count = 0;
|
||||
}
|
||||
|
||||
|
||||
public TMP_TextProcessingStack(int capacity, int rolloverSize)
|
||||
{
|
||||
itemStack = new T[capacity];
|
||||
m_Capacity = capacity;
|
||||
index = 0;
|
||||
m_RolloverSize = rolloverSize;
|
||||
|
||||
m_DefaultItem = default(T);
|
||||
m_Count = 0;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public int Count
|
||||
{
|
||||
get { return m_Count; }
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Returns the current item on the stack.
|
||||
/// </summary>
|
||||
public T current
|
||||
{
|
||||
get
|
||||
{
|
||||
if (index > 0)
|
||||
return itemStack[index - 1];
|
||||
|
||||
return itemStack[0];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public int rolloverSize
|
||||
{
|
||||
get { return m_RolloverSize; }
|
||||
set
|
||||
{
|
||||
m_RolloverSize = value;
|
||||
|
||||
//if (m_Capacity < m_RolloverSize)
|
||||
// Array.Resize(ref itemStack, m_RolloverSize);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Set stack elements to default item.
|
||||
/// </summary>
|
||||
/// <param name="stack">The stack of elements.</param>
|
||||
/// <param name="item"></param>
|
||||
internal static void SetDefault(TMP_TextProcessingStack<T>[] stack, T item)
|
||||
{
|
||||
for (int i = 0; i < stack.Length; i++)
|
||||
stack[i].SetDefault(item);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function to clear and reset stack to first item.
|
||||
/// </summary>
|
||||
public void Clear()
|
||||
{
|
||||
index = 0;
|
||||
m_Count = 0;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function to set the first item on the stack and reset index.
|
||||
/// </summary>
|
||||
/// <param name="item"></param>
|
||||
public void SetDefault(T item)
|
||||
{
|
||||
if (itemStack == null)
|
||||
{
|
||||
m_Capacity = k_DefaultCapacity;
|
||||
itemStack = new T[m_Capacity];
|
||||
m_DefaultItem = default(T);
|
||||
}
|
||||
|
||||
itemStack[0] = item;
|
||||
index = 1;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function to add a new item to the stack.
|
||||
/// </summary>
|
||||
/// <param name="item"></param>
|
||||
public void Add(T item)
|
||||
{
|
||||
if (index < itemStack.Length)
|
||||
{
|
||||
itemStack[index] = item;
|
||||
index += 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function to retrieve an item from the stack.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public T Remove()
|
||||
{
|
||||
index -= 1;
|
||||
|
||||
if (index <= 0)
|
||||
{
|
||||
index = 1;
|
||||
return itemStack[0];
|
||||
|
||||
}
|
||||
|
||||
return itemStack[index - 1];
|
||||
}
|
||||
|
||||
public void Push(T item)
|
||||
{
|
||||
if (index == m_Capacity)
|
||||
{
|
||||
m_Capacity *= 2;
|
||||
if (m_Capacity == 0)
|
||||
m_Capacity = k_DefaultCapacity;
|
||||
|
||||
Array.Resize(ref itemStack, m_Capacity);
|
||||
}
|
||||
|
||||
itemStack[index] = item;
|
||||
|
||||
if (m_RolloverSize == 0)
|
||||
{
|
||||
index += 1;
|
||||
m_Count += 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
index = (index + 1) % m_RolloverSize;
|
||||
m_Count = m_Count < m_RolloverSize ? m_Count + 1 : m_RolloverSize;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public T Pop()
|
||||
{
|
||||
if (index == 0 && m_RolloverSize == 0)
|
||||
return default(T);
|
||||
|
||||
if (m_RolloverSize == 0)
|
||||
index -= 1;
|
||||
else
|
||||
{
|
||||
index = (index - 1) % m_RolloverSize;
|
||||
index = index < 0 ? index + m_RolloverSize : index;
|
||||
}
|
||||
|
||||
T item = itemStack[index];
|
||||
itemStack[index] = m_DefaultItem;
|
||||
|
||||
m_Count = m_Count > 0 ? m_Count - 1 : 0;
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public T Peek()
|
||||
{
|
||||
if (index == 0)
|
||||
return m_DefaultItem;
|
||||
|
||||
return itemStack[index - 1];
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function to retrieve the current item from the stack.
|
||||
/// </summary>
|
||||
/// <returns>itemStack <T></returns>
|
||||
public T CurrentItem()
|
||||
{
|
||||
if (index > 0)
|
||||
return itemStack[index - 1];
|
||||
|
||||
return itemStack[0];
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function to retrieve the previous item without affecting the stack.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public T PreviousItem()
|
||||
{
|
||||
if (index > 1)
|
||||
return itemStack[index - 2];
|
||||
|
||||
return itemStack[0];
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 20a9b557a46149dfbfa04a3a7080f5aa
|
||||
timeCreated: 1448242247
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,12 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 4f0ca6874aa74540bb3d4fe5a0f86bcc
|
||||
timeCreated: 1432117579
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,249 @@
|
|||
using UnityEngine;
|
||||
using Unity.Profiling;
|
||||
using UnityEngine.UI;
|
||||
using System.Collections.Generic;
|
||||
|
||||
|
||||
namespace TMPro
|
||||
{
|
||||
|
||||
public class TMP_UpdateManager
|
||||
{
|
||||
private static TMP_UpdateManager s_Instance;
|
||||
|
||||
private readonly HashSet<int> m_LayoutQueueLookup = new HashSet<int>();
|
||||
private readonly List<TMP_Text> m_LayoutRebuildQueue = new List<TMP_Text>();
|
||||
|
||||
private readonly HashSet<int> m_GraphicQueueLookup = new HashSet<int>();
|
||||
private readonly List<TMP_Text> m_GraphicRebuildQueue = new List<TMP_Text>();
|
||||
|
||||
private readonly HashSet<int> m_InternalUpdateLookup = new HashSet<int>();
|
||||
private readonly List<TMP_Text> m_InternalUpdateQueue = new List<TMP_Text>();
|
||||
|
||||
private readonly HashSet<int> m_CullingUpdateLookup = new HashSet<int>();
|
||||
private readonly List<TMP_Text> m_CullingUpdateQueue = new List<TMP_Text>();
|
||||
|
||||
// Profiler Marker declarations
|
||||
private static ProfilerMarker k_RegisterTextObjectForUpdateMarker = new ProfilerMarker("TMP.RegisterTextObjectForUpdate");
|
||||
private static ProfilerMarker k_RegisterTextElementForGraphicRebuildMarker = new ProfilerMarker("TMP.RegisterTextElementForGraphicRebuild");
|
||||
private static ProfilerMarker k_RegisterTextElementForCullingUpdateMarker = new ProfilerMarker("TMP.RegisterTextElementForCullingUpdate");
|
||||
private static ProfilerMarker k_UnregisterTextObjectForUpdateMarker = new ProfilerMarker("TMP.UnregisterTextObjectForUpdate");
|
||||
private static ProfilerMarker k_UnregisterTextElementForGraphicRebuildMarker = new ProfilerMarker("TMP.UnregisterTextElementForGraphicRebuild");
|
||||
|
||||
/// <summary>
|
||||
/// Get a singleton instance of the registry
|
||||
/// </summary>
|
||||
static TMP_UpdateManager instance
|
||||
{
|
||||
get
|
||||
{
|
||||
if (s_Instance == null)
|
||||
s_Instance = new TMP_UpdateManager();
|
||||
|
||||
return s_Instance;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Register to receive rendering callbacks.
|
||||
/// </summary>
|
||||
TMP_UpdateManager()
|
||||
{
|
||||
Canvas.willRenderCanvases += DoRebuilds;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Function used as a replacement for LateUpdate() to handle SDF Scale updates and Legacy Animation updates.
|
||||
/// </summary>
|
||||
/// <param name="textObject"></param>
|
||||
internal static void RegisterTextObjectForUpdate(TMP_Text textObject)
|
||||
{
|
||||
k_RegisterTextObjectForUpdateMarker.Begin();
|
||||
|
||||
instance.InternalRegisterTextObjectForUpdate(textObject);
|
||||
|
||||
k_RegisterTextObjectForUpdateMarker.End();
|
||||
}
|
||||
|
||||
private void InternalRegisterTextObjectForUpdate(TMP_Text textObject)
|
||||
{
|
||||
int id = textObject.GetInstanceID();
|
||||
|
||||
if (m_InternalUpdateLookup.Contains(id))
|
||||
return;
|
||||
|
||||
m_InternalUpdateLookup.Add(id);
|
||||
m_InternalUpdateQueue.Add(textObject);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Function to register elements which require a layout rebuild.
|
||||
/// </summary>
|
||||
/// <param name="element"></param>
|
||||
public static void RegisterTextElementForLayoutRebuild(TMP_Text element)
|
||||
{
|
||||
instance.InternalRegisterTextElementForLayoutRebuild(element);
|
||||
}
|
||||
|
||||
private void InternalRegisterTextElementForLayoutRebuild(TMP_Text element)
|
||||
{
|
||||
int id = element.GetInstanceID();
|
||||
|
||||
if (m_LayoutQueueLookup.Contains(id))
|
||||
return;
|
||||
|
||||
m_LayoutQueueLookup.Add(id);
|
||||
m_LayoutRebuildQueue.Add(element);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Function to register elements which require a layout rebuild.
|
||||
/// </summary>
|
||||
/// <param name="element"></param>
|
||||
public static void RegisterTextElementForGraphicRebuild(TMP_Text element)
|
||||
{
|
||||
k_RegisterTextElementForGraphicRebuildMarker.Begin();
|
||||
|
||||
instance.InternalRegisterTextElementForGraphicRebuild(element);
|
||||
|
||||
k_RegisterTextElementForGraphicRebuildMarker.End();
|
||||
}
|
||||
|
||||
private void InternalRegisterTextElementForGraphicRebuild(TMP_Text element)
|
||||
{
|
||||
int id = element.GetInstanceID();
|
||||
|
||||
if (m_GraphicQueueLookup.Contains(id))
|
||||
return;
|
||||
|
||||
m_GraphicQueueLookup.Add(id);
|
||||
m_GraphicRebuildQueue.Add(element);
|
||||
}
|
||||
|
||||
public static void RegisterTextElementForCullingUpdate(TMP_Text element)
|
||||
{
|
||||
k_RegisterTextElementForCullingUpdateMarker.Begin();
|
||||
|
||||
instance.InternalRegisterTextElementForCullingUpdate(element);
|
||||
|
||||
k_RegisterTextElementForCullingUpdateMarker.End();
|
||||
}
|
||||
|
||||
private void InternalRegisterTextElementForCullingUpdate(TMP_Text element)
|
||||
{
|
||||
int id = element.GetInstanceID();
|
||||
|
||||
if (m_CullingUpdateLookup.Contains(id))
|
||||
return;
|
||||
|
||||
m_CullingUpdateLookup.Add(id);
|
||||
m_CullingUpdateQueue.Add(element);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Callback which occurs just before the cam is rendered.
|
||||
/// </summary>
|
||||
void OnCameraPreCull()
|
||||
{
|
||||
DoRebuilds();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Process the rebuild requests in the rebuild queues.
|
||||
/// </summary>
|
||||
void DoRebuilds()
|
||||
{
|
||||
// Handle text objects the require an update either as a result of scale changes or legacy animation.
|
||||
for (int i = 0; i < m_InternalUpdateQueue.Count; i++)
|
||||
{
|
||||
m_InternalUpdateQueue[i].InternalUpdate();
|
||||
}
|
||||
|
||||
// Handle Layout Rebuild Phase
|
||||
for (int i = 0; i < m_LayoutRebuildQueue.Count; i++)
|
||||
{
|
||||
m_LayoutRebuildQueue[i].Rebuild(CanvasUpdate.Prelayout);
|
||||
}
|
||||
|
||||
if (m_LayoutRebuildQueue.Count > 0)
|
||||
{
|
||||
m_LayoutRebuildQueue.Clear();
|
||||
m_LayoutQueueLookup.Clear();
|
||||
}
|
||||
|
||||
// Handle Graphic Rebuild Phase
|
||||
for (int i = 0; i < m_GraphicRebuildQueue.Count; i++)
|
||||
{
|
||||
m_GraphicRebuildQueue[i].Rebuild(CanvasUpdate.PreRender);
|
||||
}
|
||||
|
||||
// If there are no objects in the queue, we don't need to clear the lists again.
|
||||
if (m_GraphicRebuildQueue.Count > 0)
|
||||
{
|
||||
m_GraphicRebuildQueue.Clear();
|
||||
m_GraphicQueueLookup.Clear();
|
||||
}
|
||||
|
||||
// Handle Culling Update
|
||||
for (int i = 0; i < m_CullingUpdateQueue.Count; i++)
|
||||
{
|
||||
m_CullingUpdateQueue[i].UpdateCulling();
|
||||
}
|
||||
|
||||
// If there are no objects in the queue, we don't need to clear the lists again.
|
||||
if (m_CullingUpdateQueue.Count > 0)
|
||||
{
|
||||
m_CullingUpdateQueue.Clear();
|
||||
m_CullingUpdateLookup.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
internal static void UnRegisterTextObjectForUpdate(TMP_Text textObject)
|
||||
{
|
||||
k_UnregisterTextObjectForUpdateMarker.Begin();
|
||||
|
||||
instance.InternalUnRegisterTextObjectForUpdate(textObject);
|
||||
|
||||
k_UnregisterTextObjectForUpdateMarker.End();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Function to unregister elements which no longer require a rebuild.
|
||||
/// </summary>
|
||||
/// <param name="element"></param>
|
||||
public static void UnRegisterTextElementForRebuild(TMP_Text element)
|
||||
{
|
||||
instance.InternalUnRegisterTextElementForGraphicRebuild(element);
|
||||
instance.InternalUnRegisterTextElementForLayoutRebuild(element);
|
||||
instance.InternalUnRegisterTextObjectForUpdate(element);
|
||||
}
|
||||
|
||||
private void InternalUnRegisterTextElementForGraphicRebuild(TMP_Text element)
|
||||
{
|
||||
k_UnregisterTextElementForGraphicRebuildMarker.Begin();
|
||||
|
||||
int id = element.GetInstanceID();
|
||||
|
||||
m_GraphicRebuildQueue.Remove(element);
|
||||
m_GraphicQueueLookup.Remove(id);
|
||||
|
||||
k_UnregisterTextElementForGraphicRebuildMarker.End();
|
||||
}
|
||||
|
||||
private void InternalUnRegisterTextElementForLayoutRebuild(TMP_Text element)
|
||||
{
|
||||
int id = element.GetInstanceID();
|
||||
|
||||
m_LayoutRebuildQueue.Remove(element);
|
||||
m_LayoutQueueLookup.Remove(id);
|
||||
}
|
||||
|
||||
private void InternalUnRegisterTextObjectForUpdate(TMP_Text textObject)
|
||||
{
|
||||
int id = textObject.GetInstanceID();
|
||||
|
||||
m_InternalUpdateQueue.Remove(textObject);
|
||||
m_InternalUpdateLookup.Remove(id);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 691db8cb70c4426a8ae718465c21345f
|
||||
timeCreated: 1447406424
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue