feat: Initial commit
This commit is contained in:
11
Assets/TextMesh Pro/Scripts/Runtime/AssemblyInfo.cs
Normal file
11
Assets/TextMesh Pro/Scripts/Runtime/AssemblyInfo.cs
Normal file
@@ -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
|
11
Assets/TextMesh Pro/Scripts/Runtime/AssemblyInfo.cs.meta
Normal file
11
Assets/TextMesh Pro/Scripts/Runtime/AssemblyInfo.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cc4155a9f4c4a61478dced5053f1bd07
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
31
Assets/TextMesh Pro/Scripts/Runtime/GlobalSuppressions.cs
Normal file
31
Assets/TextMesh Pro/Scripts/Runtime/GlobalSuppressions.cs
Normal file
@@ -0,0 +1,31 @@
|
||||
// This file is used by Code Analysis to maintain SuppressMessage
|
||||
// attributes that are applied to this project.
|
||||
// Project-level suppressions either have no target or are given
|
||||
// a specific target and scoped to a namespace, type, member, etc.
|
||||
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
[assembly: SuppressMessage("Performance", "UNT0026")]
|
||||
[assembly: SuppressMessage("Performance", "UNT0035")]
|
||||
[assembly: SuppressMessage("Style", "IDE0017")]
|
||||
[assembly: SuppressMessage("Style", "IDE0018")]
|
||||
[assembly: SuppressMessage("Style", "IDE0031")]
|
||||
[assembly: SuppressMessage("Style", "IDE0034")]
|
||||
[assembly: SuppressMessage("Style", "IDE0044")]
|
||||
[assembly: SuppressMessage("Style", "IDE0051")]
|
||||
[assembly: SuppressMessage("Style", "IDE0052")]
|
||||
[assembly: SuppressMessage("Style", "IDE0054")]
|
||||
[assembly: SuppressMessage("Style", "IDE0056")]
|
||||
[assembly: SuppressMessage("Style", "IDE0057")]
|
||||
[assembly: SuppressMessage("Style", "IDE0059")]
|
||||
[assembly: SuppressMessage("Style", "IDE0060")]
|
||||
[assembly: SuppressMessage("Style", "IDE0063")]
|
||||
[assembly: SuppressMessage("Style", "IDE0066")]
|
||||
[assembly: SuppressMessage("Style", "IDE0074")]
|
||||
[assembly: SuppressMessage("Style", "IDE0079")]
|
||||
[assembly: SuppressMessage("Style", "IDE0083")]
|
||||
[assembly: SuppressMessage("Style", "IDE0090")]
|
||||
[assembly: SuppressMessage("Style", "IDE0180")]
|
||||
[assembly: SuppressMessage("Style", "IDE0251")]
|
||||
[assembly: SuppressMessage("Style", "IDE1005")]
|
||||
[assembly: SuppressMessage("Style", "IDE1006")]
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b51b4f4c3bc4c0844b9eb517250fe406
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
17
Assets/TextMesh Pro/Scripts/Runtime/ITextPreProcessor.cs
Normal file
17
Assets/TextMesh Pro/Scripts/Runtime/ITextPreProcessor.cs
Normal file
@@ -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: 04973cf92f7eb984989cc757a35ce78c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
623
Assets/TextMesh Pro/Scripts/Runtime/MaterialReferenceManager.cs
Normal file
623
Assets/TextMesh Pro/Scripts/Runtime/MaterialReferenceManager.cs
Normal file
@@ -0,0 +1,623 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.TextCore.Text;
|
||||
|
||||
|
||||
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, FontAsset> m_FontAssetReferenceLookup = new Dictionary<int, FontAsset>();
|
||||
private Dictionary<int, SpriteAsset> m_SpriteAssetReferenceLookup = new Dictionary<int, SpriteAsset>();
|
||||
private Dictionary<int, TextColorGradient> m_ColorGradientReferenceLookup = new Dictionary<int, TextColorGradient>();
|
||||
|
||||
|
||||
/// <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(FontAsset fontAsset)
|
||||
{
|
||||
MaterialReferenceManager.instance.AddFontAssetInternal(fontAsset);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add new Font Asset reference to dictionary.
|
||||
/// </summary>
|
||||
/// <param name="fontAsset"></param>
|
||||
private void AddFontAssetInternal(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(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(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, 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, 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, TextColorGradient 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, TextColorGradient 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(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(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 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 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 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 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 TextColorGradient 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 TextColorGradient 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 FontAsset fontAsset;
|
||||
public 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, FontAsset fontAsset, 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();
|
||||
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, 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, 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();
|
||||
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, 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].referenceCount = 0;
|
||||
|
||||
return index;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3fd0378c8b128984483147606e14726e
|
||||
timeCreated: 1449743129
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
220
Assets/TextMesh Pro/Scripts/Runtime/TMP_CharacterInfo.cs
Normal file
220
Assets/TextMesh Pro/Scripts/Runtime/TMP_CharacterInfo.cs
Normal file
@@ -0,0 +1,220 @@
|
||||
using System.Diagnostics;
|
||||
using UnityEngine;
|
||||
using UnityEngine.TextCore;
|
||||
using UnityEngine.TextCore.Text;
|
||||
|
||||
|
||||
namespace TMPro
|
||||
{
|
||||
public struct TMP_Vertex
|
||||
{
|
||||
public Vector3 position;
|
||||
public Vector4 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 TMP_TextElementType elementType;
|
||||
|
||||
public char character; // Should be changed to an uint to handle UTF32
|
||||
public int index;
|
||||
public int stringLength;
|
||||
|
||||
public TextElement textElement;
|
||||
public Glyph alternativeGlyph;
|
||||
public FontAsset fontAsset;
|
||||
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;
|
||||
internal float adjustedHorizontalAdvance;
|
||||
|
||||
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: 78117be65f9ab544a9a373a26f4148f0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
74
Assets/TextMesh Pro/Scripts/Runtime/TMP_Compatibility.cs
Normal file
74
Assets/TextMesh Pro/Scripts/Runtime/TMP_Compatibility.cs
Normal file
@@ -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: 2c9cc00f0e8000543a1ed26c2a0f1f0b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
246
Assets/TextMesh Pro/Scripts/Runtime/TMP_CoroutineTween.cs
Normal file
246
Assets/TextMesh Pro/Scripts/Runtime/TMP_CoroutineTween.cs
Normal file
@@ -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: 38133bafd4674d242835faca6f9f864f
|
||||
timeCreated: 1464850953
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
399
Assets/TextMesh Pro/Scripts/Runtime/TMP_DefaultControls.cs
Normal file
399
Assets/TextMesh Pro/Scripts/Runtime/TMP_DefaultControls.cs
Normal file
@@ -0,0 +1,399 @@
|
||||
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);
|
||||
|
||||
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.textWrappingMode = TextWrappingModes.NoWrap;
|
||||
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.textWrappingMode = TextWrappingModes.NoWrap;
|
||||
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: 094d5dbc4aa34bc40baa80a884b5ff3c
|
||||
timeCreated: 1446378357
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
1317
Assets/TextMesh Pro/Scripts/Runtime/TMP_Dropdown.cs
Normal file
1317
Assets/TextMesh Pro/Scripts/Runtime/TMP_Dropdown.cs
Normal file
File diff suppressed because it is too large
Load Diff
11
Assets/TextMesh Pro/Scripts/Runtime/TMP_Dropdown.cs.meta
Normal file
11
Assets/TextMesh Pro/Scripts/Runtime/TMP_Dropdown.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c0a28a6dcbb780342a6fc7a12c3d160e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {fileID: 2800000, guid: a7ec9e7ad8b847b7ae4510af83c5d868, type: 3}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,188 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.TextCore.LowLevel;
|
||||
|
||||
|
||||
namespace TMPro
|
||||
{
|
||||
internal class TMP_DynamicFontAssetUtilities
|
||||
{
|
||||
private static TMP_DynamicFontAssetUtilities s_Instance = new TMP_DynamicFontAssetUtilities();
|
||||
|
||||
private Dictionary<ulong, FontReference> s_SystemFontLookup;
|
||||
private string[] s_SystemFontPaths;
|
||||
private uint s_RegularStyleNameHashCode = 1291372090;
|
||||
|
||||
public struct FontReference
|
||||
{
|
||||
public string familyName;
|
||||
public string styleName;
|
||||
public int faceIndex;
|
||||
public string filePath;
|
||||
public ulong hashCode;
|
||||
|
||||
/// <summary>
|
||||
/// Constructor for new FontReference
|
||||
/// </summary>
|
||||
/// <param name="faceNameAndStyle">String that combines the family name with style name</param>
|
||||
/// <param name="index">Index of the font face and style.</param>
|
||||
public FontReference(string fontFilePath, string faceNameAndStyle, int index)
|
||||
{
|
||||
familyName = null;
|
||||
styleName = null;
|
||||
faceIndex = index;
|
||||
uint familyNameHashCode = 0;
|
||||
uint styleNameHashCode = 0;
|
||||
filePath = fontFilePath;
|
||||
|
||||
int length = faceNameAndStyle.Length;
|
||||
char[] conversionArray = new char[length];
|
||||
|
||||
int readingFlag = 0;
|
||||
int writingIndex = 0;
|
||||
|
||||
for (int i = 0; i < length; i++)
|
||||
{
|
||||
char c = faceNameAndStyle[i];
|
||||
|
||||
// Read family name
|
||||
if (readingFlag == 0)
|
||||
{
|
||||
bool isSeparator = i + 2 < length && c == ' ' && faceNameAndStyle[i + 1] == '-' && faceNameAndStyle[i + 2] == ' ';
|
||||
|
||||
if (isSeparator)
|
||||
{
|
||||
readingFlag = 1;
|
||||
this.familyName = new string(conversionArray, 0, writingIndex);
|
||||
i += 2;
|
||||
writingIndex = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
familyNameHashCode = (familyNameHashCode << 5) + familyNameHashCode ^ TMP_TextUtilities.ToUpperFast(c);
|
||||
conversionArray[writingIndex++] = c;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Read style name
|
||||
if (readingFlag == 1)
|
||||
{
|
||||
styleNameHashCode = (styleNameHashCode << 5) + styleNameHashCode ^ TMP_TextUtilities.ToUpperFast(c);
|
||||
conversionArray[writingIndex++] = c;
|
||||
|
||||
if (i + 1 == length)
|
||||
this.styleName = new string(conversionArray, 0, writingIndex);
|
||||
}
|
||||
}
|
||||
|
||||
hashCode = (ulong)styleNameHashCode << 32 | familyNameHashCode;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void InitializeSystemFontReferenceCache()
|
||||
{
|
||||
if (s_SystemFontLookup == null)
|
||||
s_SystemFontLookup = new Dictionary<ulong, FontReference>();
|
||||
else
|
||||
s_SystemFontLookup.Clear();
|
||||
|
||||
if (s_SystemFontPaths == null)
|
||||
s_SystemFontPaths = Font.GetPathsToOSFonts();
|
||||
|
||||
for (int i = 0; i < s_SystemFontPaths.Length; i++)
|
||||
{
|
||||
// Load font at the given path
|
||||
FontEngineError error = FontEngine.LoadFontFace(s_SystemFontPaths[i]);
|
||||
if (error != FontEngineError.Success)
|
||||
{
|
||||
Debug.LogWarning("Error [" + error + "] trying to load the font at path [" + s_SystemFontPaths[i] + "].");
|
||||
continue;
|
||||
}
|
||||
|
||||
// Get font faces and styles for this font
|
||||
string[] fontFaces = FontEngine.GetFontFaces();
|
||||
|
||||
// Iterate over each font face
|
||||
for (int j = 0; j < fontFaces.Length; j++)
|
||||
{
|
||||
FontReference fontRef = new FontReference(s_SystemFontPaths[i], fontFaces[j], j);
|
||||
|
||||
if (s_SystemFontLookup.ContainsKey(fontRef.hashCode))
|
||||
{
|
||||
//Debug.Log("<color=#FFFF80>[" + i + "]</color> Family Name <color=#FFFF80>[" + fontRef.familyName + "]</color> Style Name <color=#FFFF80>[" + fontRef.styleName + "]</color> Index [" + fontRef.faceIndex + "] HashCode [" + fontRef.hashCode + "] Path [" + fontRef.filePath + "].");
|
||||
continue;
|
||||
}
|
||||
|
||||
// Add font reference to lookup dictionary
|
||||
s_SystemFontLookup.Add(fontRef.hashCode, fontRef);
|
||||
|
||||
Debug.Log("[" + i + "] Family Name [" + fontRef.familyName + "] Style Name [" + fontRef.styleName + "] Index [" + fontRef.faceIndex + "] HashCode [" + fontRef.hashCode + "] Path [" + fontRef.filePath + "].");
|
||||
}
|
||||
|
||||
// Unload current font face.
|
||||
FontEngine.UnloadFontFace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="familyName"></param>
|
||||
/// <param name="fontRef"></param>
|
||||
/// <returns></returns>
|
||||
public static bool TryGetSystemFontReference(string familyName, out FontReference fontRef)
|
||||
{
|
||||
return s_Instance.TryGetSystemFontReferenceInternal(familyName, null, out fontRef);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="familyName"></param>
|
||||
/// <param name="styleName"></param>
|
||||
/// <param name="fontRef"></param>
|
||||
/// <returns></returns>
|
||||
public static bool TryGetSystemFontReference(string familyName, string styleName, out FontReference fontRef)
|
||||
{
|
||||
return s_Instance.TryGetSystemFontReferenceInternal(familyName, styleName, out fontRef);
|
||||
}
|
||||
|
||||
bool TryGetSystemFontReferenceInternal(string familyName, string styleName, out FontReference fontRef)
|
||||
{
|
||||
if (s_SystemFontLookup == null)
|
||||
InitializeSystemFontReferenceCache();
|
||||
|
||||
fontRef = new FontReference();
|
||||
|
||||
// Compute family name hash code
|
||||
uint familyNameHashCode = TMP_TextUtilities.GetHashCodeCaseInSensitive(familyName);
|
||||
uint styleNameHashCode = string.IsNullOrEmpty(styleName) ? s_RegularStyleNameHashCode : TMP_TextUtilities.GetHashCodeCaseInSensitive(styleName);
|
||||
ulong key = (ulong)styleNameHashCode << 32 | familyNameHashCode;
|
||||
|
||||
// Lookup font reference
|
||||
if (s_SystemFontLookup.ContainsKey(key))
|
||||
{
|
||||
fontRef = s_SystemFontLookup[key];
|
||||
return true;
|
||||
}
|
||||
|
||||
// Return if specified family and style name is not found.
|
||||
if (styleNameHashCode != s_RegularStyleNameHashCode)
|
||||
return false;
|
||||
|
||||
// Return first potential reference for the given family name
|
||||
foreach (KeyValuePair<ulong, FontReference> pair in s_SystemFontLookup)
|
||||
{
|
||||
if (pair.Value.familyName == familyName)
|
||||
{
|
||||
fontRef = pair.Value;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: aaf9006568d76504f982305b517fb490
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
458
Assets/TextMesh Pro/Scripts/Runtime/TMP_FontAssetCommon.cs
Normal file
458
Assets/TextMesh Pro/Scripts/Runtime/TMP_FontAssetCommon.cs
Normal file
@@ -0,0 +1,458 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Serialization;
|
||||
using UnityEngine.TextCore.Text;
|
||||
|
||||
|
||||
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 faceIndex;
|
||||
public int pointSizeSamplingMode;
|
||||
public int pointSize;
|
||||
public int padding;
|
||||
public int paddingMode;
|
||||
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.faceIndex = 0;
|
||||
this.pointSize = pointSize;
|
||||
this.pointSizeSamplingMode = pointSizeSamplingMode;
|
||||
this.padding = padding;
|
||||
this.paddingMode = 2;
|
||||
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 FontAsset regularTypeface;
|
||||
public 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 spacing.
|
||||
/// </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 FontAsset SearchForCharacter(FontAsset font, uint unicode, out 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 FontAsset SearchForCharacter(List<FontAsset> fonts, uint unicode, out Character character)
|
||||
{
|
||||
return SearchForCharacterInternal(fonts, unicode, out character);
|
||||
}
|
||||
|
||||
|
||||
private static FontAsset SearchForCharacterInternal(FontAsset font, uint unicode, out 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++)
|
||||
{
|
||||
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 FontAsset SearchForCharacterInternal(List<FontAsset> fonts, uint unicode, out Character character)
|
||||
{
|
||||
character = null;
|
||||
|
||||
if (fonts != null && fonts.Count > 0)
|
||||
{
|
||||
for (int i = 0; i < fonts.Count; i++)
|
||||
{
|
||||
FontAsset fontAsset = SearchForCharacterInternal(fonts[i], unicode, out character);
|
||||
|
||||
if (fontAsset != null)
|
||||
return fontAsset;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7c5c60f80f1a9814eb7e246f2e88afd4
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
440
Assets/TextMesh Pro/Scripts/Runtime/TMP_FontAssetUtilities.cs
Normal file
440
Assets/TextMesh Pro/Scripts/Runtime/TMP_FontAssetUtilities.cs
Normal file
@@ -0,0 +1,440 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine.TextCore.Text;
|
||||
|
||||
|
||||
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 Character GetCharacterFromFontAsset(uint unicode, 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 Character GetCharacterFromFontAsset_Internal(uint unicode, FontAsset sourceFontAsset, bool includeFallbacks, FontStyles fontStyle, FontWeight fontWeight, out bool isAlternativeTypeface)
|
||||
{
|
||||
isAlternativeTypeface = false;
|
||||
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.
|
||||
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;
|
||||
}
|
||||
|
||||
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 == UnityEngine.TextCore.Text.AtlasPopulationMode.Dynamic || temp.atlasPopulationMode == UnityEngine.TextCore.Text.AtlasPopulationMode.DynamicOS)
|
||||
{
|
||||
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 == UnityEngine.TextCore.Text.AtlasPopulationMode.Dynamic || sourceFontAsset.atlasPopulationMode == UnityEngine.TextCore.Text.AtlasPopulationMode.DynamicOS)
|
||||
{
|
||||
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<FontAsset> fallbackFontAssets = sourceFontAsset.fallbackFontAssetTable;
|
||||
int fallbackCount = fallbackFontAssets.Count;
|
||||
|
||||
if (fallbackCount == 0)
|
||||
return null;
|
||||
|
||||
for (int i = 0; i < fallbackCount; i++)
|
||||
{
|
||||
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 Character GetCharacterFromFontAssets(uint unicode, FontAsset sourceFontAsset, List<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++)
|
||||
{
|
||||
FontAsset fontAsset = fontAssets[i];
|
||||
|
||||
if (fontAsset == null) continue;
|
||||
|
||||
// Add reference to this search query
|
||||
//sourceFontAsset.FallbackSearchQueryLookup.Add(fontAsset.instanceID);
|
||||
|
||||
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 SpriteCharacter GetSpriteCharacterFromSpriteAsset(uint unicode, SpriteAsset spriteAsset, bool includeFallbacks)
|
||||
{
|
||||
// Make sure we have a valid sprite asset to search
|
||||
if (spriteAsset == null)
|
||||
return null;
|
||||
|
||||
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<SpriteAsset> fallbackSpriteAsset = spriteAsset.fallbackSpriteAssets;
|
||||
|
||||
if (fallbackSpriteAsset != null && fallbackSpriteAsset.Count > 0)
|
||||
{
|
||||
int fallbackCount = fallbackSpriteAsset.Count;
|
||||
|
||||
for (int i = 0; i < fallbackCount; i++)
|
||||
{
|
||||
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 SpriteCharacter GetSpriteCharacterFromSpriteAsset_Internal(uint unicode, SpriteAsset spriteAsset, bool includeFallbacks)
|
||||
{
|
||||
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<SpriteAsset> fallbackSpriteAsset = spriteAsset.fallbackSpriteAssets;
|
||||
|
||||
if (fallbackSpriteAsset != null && fallbackSpriteAsset.Count > 0)
|
||||
{
|
||||
int fallbackCount = fallbackSpriteAsset.Count;
|
||||
|
||||
for (int i = 0; i < fallbackCount; i++)
|
||||
{
|
||||
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: a4a26a81fe2bc7b42ba0c6aefa6f0cdb
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
219
Assets/TextMesh Pro/Scripts/Runtime/TMP_FontFeaturesCommon.cs
Normal file
219
Assets/TextMesh Pro/Scripts/Runtime/TMP_FontFeaturesCommon.cs
Normal file
@@ -0,0 +1,219 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.TextCore.LowLevel;
|
||||
|
||||
|
||||
namespace TMPro
|
||||
{
|
||||
/// <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: 3d7de7dd98a0728419392bf8b2f46a37
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
4650
Assets/TextMesh Pro/Scripts/Runtime/TMP_InputField.cs
Normal file
4650
Assets/TextMesh Pro/Scripts/Runtime/TMP_InputField.cs
Normal file
File diff suppressed because it is too large
Load Diff
11
Assets/TextMesh Pro/Scripts/Runtime/TMP_InputField.cs.meta
Normal file
11
Assets/TextMesh Pro/Scripts/Runtime/TMP_InputField.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5f332b1d4d7bb2d4a921f0787a93e5e3
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {fileID: 2800000, guid: 3ee40aa79cd242a5b53b0b0ca4f13f0f, type: 3}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
15
Assets/TextMesh Pro/Scripts/Runtime/TMP_InputValidator.cs
Normal file
15
Assets/TextMesh Pro/Scripts/Runtime/TMP_InputValidator.cs
Normal file
@@ -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: d98fc3935c2bc5f41bf9090a00b3f5f2
|
||||
timeCreated: 1473021069
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
52
Assets/TextMesh Pro/Scripts/Runtime/TMP_LineInfo.cs
Normal file
52
Assets/TextMesh Pro/Scripts/Runtime/TMP_LineInfo.cs
Normal file
@@ -0,0 +1,52 @@
|
||||
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 visibleSpaceCount;
|
||||
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;
|
||||
//}
|
||||
}
|
||||
}
|
12
Assets/TextMesh Pro/Scripts/Runtime/TMP_LineInfo.cs.meta
Normal file
12
Assets/TextMesh Pro/Scripts/Runtime/TMP_LineInfo.cs.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a562a6b3fa540314d97306048b47ed7d
|
||||
timeCreated: 1464310403
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
21
Assets/TextMesh Pro/Scripts/Runtime/TMP_ListPool.cs
Normal file
21
Assets/TextMesh Pro/Scripts/Runtime/TMP_ListPool.cs
Normal file
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
12
Assets/TextMesh Pro/Scripts/Runtime/TMP_ListPool.cs.meta
Normal file
12
Assets/TextMesh Pro/Scripts/Runtime/TMP_ListPool.cs.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ae064c55421e484469b4bd5d60205eb7
|
||||
timeCreated: 1458521386
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
685
Assets/TextMesh Pro/Scripts/Runtime/TMP_MaterialManager.cs
Normal file
685
Assets/TextMesh Pro/Scripts/Runtime/TMP_MaterialManager.cs
Normal file
@@ -0,0 +1,685 @@
|
||||
//#define TMP_DEBUG_MODE
|
||||
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.TextCore.Text;
|
||||
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(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);
|
||||
|
||||
// Make sure the same shader is used
|
||||
destination.shader = source.shader;
|
||||
|
||||
// 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: 6e915af4d2ed15047b3dcf4644ef8ce4
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
686
Assets/TextMesh Pro/Scripts/Runtime/TMP_MeshInfo.cs
Normal file
686
Assets/TextMesh Pro/Scripts/Runtime/TMP_MeshInfo.cs
Normal file
@@ -0,0 +1,686 @@
|
||||
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;
|
||||
|
||||
/// <summary>
|
||||
/// UV0 contains the following information
|
||||
/// X, Y are the UV coordinates of the glyph in the atlas texture.
|
||||
/// Z is the texture index in the texture atlas array
|
||||
/// W is the SDF Scale where a negative value represents bold text
|
||||
/// </summary>
|
||||
public Vector4[] uvs0;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
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 Vector4[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 Vector4[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;
|
||||
//}
|
||||
|
||||
}
|
||||
}
|
12
Assets/TextMesh Pro/Scripts/Runtime/TMP_MeshInfo.cs.meta
Normal file
12
Assets/TextMesh Pro/Scripts/Runtime/TMP_MeshInfo.cs.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 11458e91bbbed294daec353329f9e43a
|
||||
timeCreated: 1462398762
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
51
Assets/TextMesh Pro/Scripts/Runtime/TMP_ObjectPool.cs
Normal file
51
Assets/TextMesh Pro/Scripts/Runtime/TMP_ObjectPool.cs
Normal file
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
12
Assets/TextMesh Pro/Scripts/Runtime/TMP_ObjectPool.cs.meta
Normal file
12
Assets/TextMesh Pro/Scripts/Runtime/TMP_ObjectPool.cs.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6a903d9018f237440b662ce733e4fbf7
|
||||
timeCreated: 1458521389
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,383 @@
|
||||
#if UNITY_EDITOR
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using UnityEngine;
|
||||
using UnityEngine.TextCore.Text;
|
||||
using UnityEditor;
|
||||
|
||||
|
||||
namespace TMPro
|
||||
{
|
||||
[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;
|
||||
TextEventManager.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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[Serializable]
|
||||
internal class TMP_ShaderPackageImporter
|
||||
{
|
||||
bool m_ShadersImported;
|
||||
|
||||
const string s_TMPShaderPackageGUID = "e02b76aaf840d38469530d159da03749";
|
||||
|
||||
public void OnDestroy() { }
|
||||
|
||||
public void OnGUI()
|
||||
{
|
||||
GUILayout.BeginVertical();
|
||||
{
|
||||
// Display options to import Essential resources
|
||||
GUILayout.BeginVertical(EditorStyles.helpBox);
|
||||
{
|
||||
//GUILayout.Label("TextMeshPro Resources Update", EditorStyles.boldLabel);
|
||||
GUILayout.Label("This release of the TMP package includes updated resources.\n\nPlease use the menu options located in \"Window\\TextMeshPro\\...\" to import the updated\n\"TMP Essential Resources\" and \"TMP Examples & Extras\".\n\nAs usual please be sure to backup any of the files and resources that you may have added or modified in the \"Assets\\TextMesh Pro\\...\" folders.", new GUIStyle(EditorStyles.label) { wordWrap = true } );
|
||||
GUILayout.Space(5f);
|
||||
|
||||
GUI.enabled = !m_ShadersImported;
|
||||
// if (GUILayout.Button("Update TMP Shaders"))
|
||||
// {
|
||||
// string packagePath = AssetDatabase.GUIDToAssetPath(s_TMPShaderPackageGUID);
|
||||
//
|
||||
// if (string.IsNullOrEmpty(packagePath))
|
||||
// return;
|
||||
//
|
||||
// AssetDatabase.importPackageCompleted += ImportCallback;
|
||||
// AssetDatabase.ImportPackage(packagePath, true);
|
||||
// }
|
||||
GUILayout.Space(5f);
|
||||
GUI.enabled = true;
|
||||
}
|
||||
GUILayout.EndVertical();
|
||||
}
|
||||
GUILayout.EndVertical();
|
||||
GUILayout.Space(5f);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="packageName"></param>
|
||||
void ImportCallback(string packageName)
|
||||
{
|
||||
if (packageName == "TMP Shaders")
|
||||
{
|
||||
m_ShadersImported = true;
|
||||
|
||||
EditorWindow window = TMP_ShaderPackageImporterWindow.importerWindow;
|
||||
|
||||
if (window != null)
|
||||
window.Close();
|
||||
}
|
||||
|
||||
Debug.Log("[" + packageName + "] have been imported.");
|
||||
|
||||
AssetDatabase.importPackageCompleted -= ImportCallback;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="interactive"></param>
|
||||
internal static void ImportShaders(bool interactive)
|
||||
{
|
||||
string packagePath = AssetDatabase.GUIDToAssetPath(s_TMPShaderPackageGUID);
|
||||
|
||||
if (string.IsNullOrEmpty(packagePath))
|
||||
return;
|
||||
|
||||
AssetDatabase.ImportPackage(packagePath, interactive);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
internal class TMP_ShaderPackageImporterWindow : EditorWindow
|
||||
{
|
||||
[SerializeField]
|
||||
TMP_ShaderPackageImporter m_ResourceImporter;
|
||||
|
||||
internal static TMP_ShaderPackageImporterWindow importerWindow;
|
||||
|
||||
public static void ShowPackageImporterWindow()
|
||||
{
|
||||
if (importerWindow == null)
|
||||
{
|
||||
importerWindow = GetWindow<TMP_ShaderPackageImporterWindow>(true, "TextMeshPro Resources Update", true);
|
||||
}
|
||||
}
|
||||
|
||||
void OnEnable()
|
||||
{
|
||||
// Set Editor Window Size
|
||||
SetEditorWindowSize();
|
||||
|
||||
if (m_ResourceImporter == null)
|
||||
m_ResourceImporter = new TMP_ShaderPackageImporter();
|
||||
}
|
||||
|
||||
void OnDestroy()
|
||||
{
|
||||
m_ResourceImporter.OnDestroy();
|
||||
}
|
||||
|
||||
void OnGUI()
|
||||
{
|
||||
Rect p = position;
|
||||
|
||||
if (p.x < 10)
|
||||
{
|
||||
p.x = 10;
|
||||
position = p;
|
||||
}
|
||||
|
||||
if (p.y < 190)
|
||||
{
|
||||
p.y = 190;
|
||||
position = p;
|
||||
}
|
||||
|
||||
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, 117);
|
||||
editorWindow.minSize = windowSize;
|
||||
editorWindow.maxSize = windowSize;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@@ -0,0 +1,16 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e17f490ae164ee642afea371ed0c8604
|
||||
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:
|
158
Assets/TextMesh Pro/Scripts/Runtime/TMP_ResourcesManager.cs
Normal file
158
Assets/TextMesh Pro/Scripts/Runtime/TMP_ResourcesManager.cs
Normal file
@@ -0,0 +1,158 @@
|
||||
/*
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.TextCore.Text;
|
||||
|
||||
|
||||
namespace TMPro
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class 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
|
||||
// ======================================================
|
||||
|
||||
struct FontAssetRef
|
||||
{
|
||||
public int nameHashCode;
|
||||
public int familyNameHashCode;
|
||||
public int styleNameHashCode;
|
||||
public long familyNameAndStyleHashCode;
|
||||
public readonly FontAsset fontAsset;
|
||||
|
||||
public FontAssetRef(int nameHashCode, int familyNameHashCode, int styleNameHashCode, FontAsset fontAsset)
|
||||
{
|
||||
this.nameHashCode = nameHashCode;
|
||||
this.familyNameHashCode = familyNameHashCode;
|
||||
this.styleNameHashCode = styleNameHashCode;
|
||||
this.familyNameAndStyleHashCode = (long) styleNameHashCode << 32 | (uint) familyNameHashCode;
|
||||
this.fontAsset = fontAsset;
|
||||
}
|
||||
}
|
||||
|
||||
static readonly Dictionary<int, FontAssetRef> s_FontAssetReferences = new Dictionary<int, FontAssetRef>();
|
||||
static readonly Dictionary<int, FontAsset> s_FontAssetNameReferenceLookup = new Dictionary<int, FontAsset>();
|
||||
static readonly Dictionary<long, FontAsset> s_FontAssetFamilyNameAndStyleReferenceLookup = new Dictionary<long, FontAsset>();
|
||||
static readonly List<int> s_FontAssetRemovalList = new List<int>(16);
|
||||
|
||||
static readonly int k_RegularStyleHashCode = TMP_TextUtilities.GetHashCode("Regular");
|
||||
|
||||
/// <summary>
|
||||
/// Add font asset to resource manager.
|
||||
/// </summary>
|
||||
/// <param name="fontAsset">Font asset to be added to the resource manager.</param>
|
||||
//[System.Obsolete("AddFontAsset() has been deprecated. Use TextResourceManager.AddFontAsset() instead. (UnityUpgradable) -> TextResourceManager.AddFontAsset()")]
|
||||
public static void AddFontAsset(FontAsset fontAsset)
|
||||
{
|
||||
// Obsolete. Use TextResourceManager.AddFontAsset() instead.
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Remove font asset from resource manager.
|
||||
/// </summary>
|
||||
/// <param name="fontAsset">Font asset to be removed from the resource manager.</param>
|
||||
//[System.Obsolete("RemovedFontAsset() has been deprecated. Use TextResourceManager.RemoveFontAsset() instead. (UnityUpgradable) -> TextResourceManager.RemoveFontAsset()")]
|
||||
public static void RemoveFontAsset(FontAsset fontAsset)
|
||||
{
|
||||
// Obsolete. Use TextResourceManager.RemoveFontAsset() instead.
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Try getting a reference to the font asset using the hash code calculated from its file name.
|
||||
/// </summary>
|
||||
/// <param name="nameHashcode"></param>
|
||||
/// <param name="fontAsset"></param>
|
||||
/// <returns></returns>
|
||||
internal static bool TryGetFontAssetByName(int nameHashcode, out FontAsset fontAsset)
|
||||
{
|
||||
fontAsset = null;
|
||||
|
||||
return s_FontAssetNameReferenceLookup.TryGetValue(nameHashcode, out fontAsset);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Try getting a reference to the font asset using the hash code calculated from font's family and style name.
|
||||
/// </summary>
|
||||
/// <param name="familyNameHashCode"></param>
|
||||
/// <param name="styleNameHashCode"></param>
|
||||
/// <param name="fontAsset"></param>
|
||||
/// <returns></returns>
|
||||
internal static bool TryGetFontAssetByFamilyName(int familyNameHashCode, int styleNameHashCode, out FontAsset fontAsset)
|
||||
{
|
||||
fontAsset = null;
|
||||
|
||||
if (styleNameHashCode == 0)
|
||||
styleNameHashCode = k_RegularStyleHashCode;
|
||||
|
||||
long familyAndStyleNameHashCode = (long) styleNameHashCode << 32 | (uint) familyNameHashCode;
|
||||
|
||||
return s_FontAssetFamilyNameAndStyleReferenceLookup.TryGetValue(familyAndStyleNameHashCode, out fontAsset);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
internal static void RebuildFontAssetCache()
|
||||
{
|
||||
// Iterate over loaded font assets to update affected font assets
|
||||
foreach (var pair in s_FontAssetReferences)
|
||||
{
|
||||
FontAssetRef fontAssetRef = pair.Value;
|
||||
|
||||
FontAsset fontAsset = fontAssetRef.fontAsset;
|
||||
|
||||
if (fontAsset == null)
|
||||
{
|
||||
// Remove font asset from our lookup dictionaries
|
||||
s_FontAssetNameReferenceLookup.Remove(fontAssetRef.nameHashCode);
|
||||
s_FontAssetFamilyNameAndStyleReferenceLookup.Remove(fontAssetRef.familyNameAndStyleHashCode);
|
||||
|
||||
// Add font asset to our removal list
|
||||
s_FontAssetRemovalList.Add(pair.Key);
|
||||
continue;
|
||||
}
|
||||
|
||||
fontAsset.InitializeCharacterLookupDictionary();
|
||||
fontAsset.AddSynthesizedCharactersAndFaceMetrics();
|
||||
}
|
||||
|
||||
// Remove font assets in our removal list from our font asset references
|
||||
for (int i = 0; i < s_FontAssetRemovalList.Count; i++)
|
||||
{
|
||||
s_FontAssetReferences.Remove(s_FontAssetRemovalList[i]);
|
||||
}
|
||||
s_FontAssetRemovalList.Clear();
|
||||
|
||||
TextEventManager.ON_FONT_PROPERTY_CHANGED(true, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8fee14164794a4541a738db6c9e260fa
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
212
Assets/TextMesh Pro/Scripts/Runtime/TMP_RichTextTagsCommon.cs
Normal file
212
Assets/TextMesh Pro/Scripts/Runtime/TMP_RichTextTagsCommon.cs
Normal file
@@ -0,0 +1,212 @@
|
||||
using System;
|
||||
using UnityEngine.Bindings;
|
||||
|
||||
|
||||
namespace TMPro
|
||||
{
|
||||
/// <summary>
|
||||
/// Rich text markup tags and attribute definitions and respective hash code values.
|
||||
/// </summary>
|
||||
internal enum MarkupTag
|
||||
{
|
||||
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>
|
||||
|
||||
TABLE = 226476955, // <table>
|
||||
SLASH_TABLE = -979118220, // </table>
|
||||
TH = 5862489, // <th>
|
||||
SLASH_TH = 193346070, // </th>
|
||||
TR = 5862467, // <tr>
|
||||
SLASH_TR = 193346060, // </tr>
|
||||
TD = 5862485, // <td>
|
||||
SLASH_TD = 193346074, // </td>
|
||||
|
||||
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>
|
||||
PADDING = -2144568463,
|
||||
|
||||
// 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,
|
||||
NOTDEF = 612146780, // .notdef
|
||||
|
||||
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: e40fb84a8412ca04783a884a187d6a48
|
||||
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: b7fea85ee47630b4bb3dd0aeb85b3075
|
||||
timeCreated: 1484171293
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
37
Assets/TextMesh Pro/Scripts/Runtime/TMP_SelectionCaret.cs
Normal file
37
Assets/TextMesh Pro/Scripts/Runtime/TMP_SelectionCaret.cs
Normal file
@@ -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: f2b6ab3702365d845916dfed0abd567b
|
||||
timeCreated: 1477609203
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
540
Assets/TextMesh Pro/Scripts/Runtime/TMP_Settings.cs
Normal file
540
Assets/TextMesh Pro/Scripts/Runtime/TMP_Settings.cs
Normal file
@@ -0,0 +1,540 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Serialization;
|
||||
using UnityEngine.TextCore.Text;
|
||||
|
||||
|
||||
#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 the text wrapping mode of newly created text objects.
|
||||
/// </summary>
|
||||
public static TextWrappingModes textWrappingMode
|
||||
{
|
||||
get { return instance.m_TextWrappingMode; }
|
||||
}
|
||||
[FormerlySerializedAs("m_enableWordWrapping")]
|
||||
[SerializeField]
|
||||
private TextWrappingModes m_TextWrappingMode;
|
||||
|
||||
/// <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>
|
||||
/// Determines if the "Clear Dynamic Data on Build" property will be set to true or false on newly created dynamic font assets.
|
||||
/// </summary>
|
||||
public static bool clearDynamicDataOnBuild
|
||||
{
|
||||
get { return instance.m_ClearDynamicDataOnBuild; }
|
||||
}
|
||||
|
||||
[SerializeField] private bool m_ClearDynamicDataOnBuild = true;
|
||||
|
||||
/// <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 FontAsset defaultFontAsset
|
||||
{
|
||||
get { return instance.m_defaultFontAsset; }
|
||||
set { instance.m_defaultFontAsset = value; }
|
||||
}
|
||||
[SerializeField]
|
||||
private 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<FontAsset> fallbackFontAssets
|
||||
{
|
||||
get { return instance.m_fallbackFontAssets; }
|
||||
set { instance.m_fallbackFontAssets = value; }
|
||||
}
|
||||
[SerializeField]
|
||||
private List<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>
|
||||
/// Determines if sub text objects will be hidden in the scene hierarchy.
|
||||
/// </summary>
|
||||
public static bool hideSubTextObjects
|
||||
{
|
||||
get { return instance.m_HideSubTextObjects; }
|
||||
}
|
||||
[SerializeField] private bool m_HideSubTextObjects = true;
|
||||
|
||||
/// <summary>
|
||||
/// The Default Sprite Asset to be used by default.
|
||||
/// </summary>
|
||||
public static SpriteAsset defaultSpriteAsset
|
||||
{
|
||||
get { return instance.m_defaultSpriteAsset; }
|
||||
set { instance.m_defaultSpriteAsset = value; }
|
||||
}
|
||||
[SerializeField]
|
||||
private 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 TextStyleSheet defaultStyleSheet
|
||||
{
|
||||
get { return instance.m_defaultStyleSheet; }
|
||||
set { instance.m_defaultStyleSheet = value; }
|
||||
}
|
||||
[SerializeField]
|
||||
private TextStyleSheet 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 UnityEngine.TextAsset leadingCharacters
|
||||
{
|
||||
get { return instance.m_leadingCharacters; }
|
||||
}
|
||||
[SerializeField]
|
||||
private UnityEngine.TextAsset m_leadingCharacters;
|
||||
|
||||
/// <summary>
|
||||
/// Text file that contains the following characters used for line breaking for Asian languages.
|
||||
/// </summary>
|
||||
public static UnityEngine.TextAsset followingCharacters
|
||||
{
|
||||
get { return instance.m_followingCharacters; }
|
||||
}
|
||||
[SerializeField]
|
||||
private UnityEngine.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 (s_Instance == null)
|
||||
{
|
||||
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 (s_Instance == null && Time.frameCount != 0)
|
||||
{
|
||||
// Open TMP Resources Importer
|
||||
TMP_PackageResourceImporterWindow.ShowPackageImporterWindow();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return 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 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 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 TextStyleSheet 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 (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);
|
||||
|
||||
s_Instance.m_linebreakingRules.leadingCharacters.Add('\x2060');
|
||||
s_Instance.m_linebreakingRules.followingCharacters.Add('\x2060');
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Get the characters from the line breaking files
|
||||
/// </summary>
|
||||
/// <param name="file"></param>
|
||||
/// <returns></returns>
|
||||
private static HashSet<uint> GetCharacters(UnityEngine.TextAsset file)
|
||||
{
|
||||
HashSet<uint> dict = new HashSet<uint>();
|
||||
string text = file.text;
|
||||
|
||||
for (int i = 0; i < text.Length; i++)
|
||||
{
|
||||
dict.Add(text[i]);
|
||||
}
|
||||
|
||||
return dict;
|
||||
}
|
||||
|
||||
|
||||
public class LineBreakingTable
|
||||
{
|
||||
public HashSet<uint> leadingCharacters;
|
||||
public HashSet<uint> followingCharacters;
|
||||
}
|
||||
}
|
||||
}
|
12
Assets/TextMesh Pro/Scripts/Runtime/TMP_Settings.cs.meta
Normal file
12
Assets/TextMesh Pro/Scripts/Runtime/TMP_Settings.cs.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fab78ea2d673edc40a6dd404991a3764
|
||||
timeCreated: 1457654851
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
690
Assets/TextMesh Pro/Scripts/Runtime/TMP_ShaderUtilities.cs
Normal file
690
Assets/TextMesh Pro/Scripts/Runtime/TMP_ShaderUtilities.cs
Normal file
@@ -0,0 +1,690 @@
|
||||
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;
|
||||
|
||||
/// <summary>
|
||||
/// Property ID for the _OutlineOffset1 shader property used by URP and HDRP shaders
|
||||
/// </summary>
|
||||
public static int ID_OutlineOffset1;
|
||||
|
||||
/// <summary>
|
||||
/// Property ID for the _OutlineOffset2 shader property used by URP and HDRP shaders
|
||||
/// </summary>
|
||||
public static int ID_OutlineOffset2;
|
||||
|
||||
/// <summary>
|
||||
/// Property ID for the _OutlineOffset3 shader property used by URP and HDRP shaders
|
||||
/// </summary>
|
||||
public static int ID_OutlineOffset3;
|
||||
|
||||
/// <summary>
|
||||
/// Property ID for the ID_AdditiveOutlineMode shader property used by URP and HDRP shaders
|
||||
/// </summary>
|
||||
public static int ID_OutlineMode;
|
||||
|
||||
/// <summary>
|
||||
/// Property ID for the _IsoPerimeter shader property used by URP and HDRP shaders
|
||||
/// </summary>
|
||||
public static int ID_IsoPerimeter;
|
||||
|
||||
/// <summary>
|
||||
/// Property ID for the _Softness shader property used by URP and HDRP shaders
|
||||
/// </summary>
|
||||
public static int ID_Softness;
|
||||
|
||||
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_OutlineOffset1 = Shader.PropertyToID("_OutlineOffset1");
|
||||
ID_OutlineOffset2 = Shader.PropertyToID("_OutlineOffset2");
|
||||
ID_OutlineOffset3 = Shader.PropertyToID("_OutlineOffset3");
|
||||
ID_OutlineMode = Shader.PropertyToID("_OutlineMode");
|
||||
|
||||
ID_IsoPerimeter = Shader.PropertyToID("_IsoPerimeter");
|
||||
ID_Softness = Shader.PropertyToID("_Softness");
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
// Special handling for new SRP Shaders
|
||||
if (material.HasProperty(ID_IsoPerimeter))
|
||||
{
|
||||
return ComputePaddingForProperties(material) + 0.25f + extraPadding;
|
||||
}
|
||||
|
||||
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 gradientScale = 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_UnderlayDilate);
|
||||
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;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
static float ComputePaddingForProperties(Material mat)
|
||||
{
|
||||
Vector4 dilation = mat.GetVector(ID_IsoPerimeter);
|
||||
Vector2 outlineOffset1 = mat.GetVector(ID_OutlineOffset1);
|
||||
Vector2 outlineOffset2 = mat.GetVector(ID_OutlineOffset2);
|
||||
Vector2 outlineOffset3 = mat.GetVector(ID_OutlineOffset3);
|
||||
bool isOutlineModeEnabled = mat.GetFloat(ID_OutlineMode) != 0;
|
||||
|
||||
Vector4 softness = mat.GetVector(ID_Softness);
|
||||
float gradientScale = mat.GetFloat(ID_GradientScale);
|
||||
|
||||
// Face
|
||||
float padding = Mathf.Max(0, dilation.x + softness.x * 0.5f);
|
||||
|
||||
// Outlines
|
||||
if (!isOutlineModeEnabled)
|
||||
{
|
||||
padding = Mathf.Max(padding, dilation.y + softness.y * 0.5f + Mathf.Max(Mathf.Abs(outlineOffset1.x), Mathf.Abs(outlineOffset1.y)));
|
||||
padding = Mathf.Max(padding, dilation.z + softness.z * 0.5f + Mathf.Max(Mathf.Abs(outlineOffset2.x), Mathf.Abs(outlineOffset2.y)));
|
||||
padding = Mathf.Max(padding, dilation.w + softness.w * 0.5f + Mathf.Max(Mathf.Abs(outlineOffset3.x), Mathf.Abs(outlineOffset3.y)));
|
||||
}
|
||||
else
|
||||
{
|
||||
float offsetOutline1 = Mathf.Max(Mathf.Abs(outlineOffset1.x), Mathf.Abs(outlineOffset1.y));
|
||||
float offsetOutline2 = Mathf.Max(Mathf.Abs(outlineOffset2.x), Mathf.Abs(outlineOffset2.y));
|
||||
|
||||
padding = Mathf.Max(padding, dilation.y + softness.y * 0.5f + offsetOutline1);
|
||||
padding = Mathf.Max(padding, dilation.z + softness.z * 0.5f + offsetOutline2);
|
||||
|
||||
float maxOffset = Mathf.Max(offsetOutline1, offsetOutline2);
|
||||
padding += Mathf.Max(0 ,(dilation.w + softness.w * 0.5f) - Mathf.Max(0, padding - maxOffset));
|
||||
}
|
||||
|
||||
// Underlay
|
||||
Vector2 underlayOffset = mat.GetVector(ID_UnderlayOffset);
|
||||
float underlayDilation = mat.GetFloat(ID_UnderlayDilate);
|
||||
float underlaySoftness = mat.GetFloat(ID_UnderlaySoftness);
|
||||
padding = Mathf.Max(padding, underlayDilation + underlaySoftness * 0.5f + Mathf.Max(Mathf.Abs(underlayOffset.x), Mathf.Abs(underlayOffset.y)));
|
||||
|
||||
return padding * gradientScale;
|
||||
}
|
||||
|
||||
// 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: 6128368125c65fc49a91f9d849c07add
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
31
Assets/TextMesh Pro/Scripts/Runtime/TMP_Sprite.cs
Normal file
31
Assets/TextMesh Pro/Scripts/Runtime/TMP_Sprite.cs
Normal file
@@ -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;
|
||||
}
|
||||
}
|
10
Assets/TextMesh Pro/Scripts/Runtime/TMP_Sprite.cs.meta
Normal file
10
Assets/TextMesh Pro/Scripts/Runtime/TMP_Sprite.cs.meta
Normal file
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5865bfa814659cd4ab94f3619a4f1ac9
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
146
Assets/TextMesh Pro/Scripts/Runtime/TMP_SpriteAnimator.cs
Normal file
146
Assets/TextMesh Pro/Scripts/Runtime/TMP_SpriteAnimator.cs
Normal file
@@ -0,0 +1,146 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.TextCore.Text;
|
||||
|
||||
|
||||
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>();
|
||||
}
|
||||
|
||||
|
||||
public void StopAllAnimations()
|
||||
{
|
||||
StopAllCoroutines();
|
||||
m_animations.Clear();
|
||||
}
|
||||
|
||||
|
||||
public void DoSpriteAnimation(int currentCharacter, 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, 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.
|
||||
uint 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
|
||||
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
|
||||
Vector4[] 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.SetUVs(0, 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: 5ce67b52e7b613a43bb4b26dbaa10aa7
|
||||
timeCreated: 1471590333
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
61
Assets/TextMesh Pro/Scripts/Runtime/TMP_SpriteGlyph.cs
Normal file
61
Assets/TextMesh Pro/Scripts/Runtime/TMP_SpriteGlyph.cs
Normal file
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
11
Assets/TextMesh Pro/Scripts/Runtime/TMP_SpriteGlyph.cs.meta
Normal file
11
Assets/TextMesh Pro/Scripts/Runtime/TMP_SpriteGlyph.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c83f236994dcf674ea6ae8d0c54f6700
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
639
Assets/TextMesh Pro/Scripts/Runtime/TMP_SubMesh.cs
Normal file
639
Assets/TextMesh Pro/Scripts/Runtime/TMP_SubMesh.cs
Normal file
@@ -0,0 +1,639 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEngine.TextCore.Text;
|
||||
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 FontAsset fontAsset
|
||||
{
|
||||
get { return m_fontAsset; }
|
||||
set { m_fontAsset = value; }
|
||||
}
|
||||
[SerializeField]
|
||||
private FontAsset m_fontAsset;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// The TMP Sprite Asset assigned to this sub text object.
|
||||
/// </summary>
|
||||
public SpriteAsset spriteAsset
|
||||
{
|
||||
get { return m_spriteAsset; }
|
||||
set { m_spriteAsset = value; }
|
||||
}
|
||||
[SerializeField]
|
||||
private 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 = TMP_Settings.hideSubTextObjects ? HideFlags.HideAndDontSave : HideFlags.DontSave;
|
||||
|
||||
TMP_SubMesh subMesh = go.GetComponent<TMP_SubMesh>();
|
||||
|
||||
go.transform.SetParent(textComponent.transform, false);
|
||||
go.transform.SetLocalPositionAndRotation(Vector3.zero, 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
|
||||
TextEventManager.MATERIAL_PROPERTY_EVENT.Add(ON_MATERIAL_PROPERTY_CHANGED);
|
||||
TextEventManager.FONT_PROPERTY_EVENT.Add(ON_FONT_PROPERTY_CHANGED);
|
||||
//TMPro_EventManager.TEXTMESHPRO_PROPERTY_EVENT.Add(ON_TEXTMESHPRO_PROPERTY_CHANGED);
|
||||
TextEventManager.DRAG_AND_DROP_MATERIAL_EVENT.Add(ON_DRAG_AND_DROP_MATERIAL);
|
||||
//TMPro_EventManager.TEXT_STYLE_PROPERTY_EVENT.Add(ON_TEXT_STYLE_CHANGED);
|
||||
TextEventManager.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
|
||||
TextEventManager.MATERIAL_PROPERTY_EVENT.Remove(ON_MATERIAL_PROPERTY_CHANGED);
|
||||
TextEventManager.FONT_PROPERTY_EVENT.Remove(ON_FONT_PROPERTY_CHANGED);
|
||||
//TMPro_EventManager.TEXTMESHPRO_PROPERTY_EVENT.Remove(ON_TEXTMESHPRO_PROPERTY_CHANGED);
|
||||
TextEventManager.DRAG_AND_DROP_MATERIAL_EVENT.Remove(ON_DRAG_AND_DROP_MATERIAL);
|
||||
//TMPro_EventManager.TEXT_STYLE_PROPERTY_EVENT.Remove(ON_TEXT_STYLE_CHANGED);
|
||||
TextEventManager.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 != 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;
|
||||
//}
|
||||
}
|
||||
}
|
12
Assets/TextMesh Pro/Scripts/Runtime/TMP_SubMesh.cs.meta
Normal file
12
Assets/TextMesh Pro/Scripts/Runtime/TMP_SubMesh.cs.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3f05254b15a1c9d48a16578696ec5f11
|
||||
timeCreated: 1454709708
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
850
Assets/TextMesh Pro/Scripts/Runtime/TMP_SubMeshUI.cs
Normal file
850
Assets/TextMesh Pro/Scripts/Runtime/TMP_SubMeshUI.cs
Normal file
@@ -0,0 +1,850 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.Rendering;
|
||||
using UnityEngine.TextCore.Text;
|
||||
using UnityEngine.UI;
|
||||
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 FontAsset fontAsset
|
||||
{
|
||||
get { return m_fontAsset; }
|
||||
set { m_fontAsset = value; }
|
||||
}
|
||||
[SerializeField]
|
||||
private FontAsset m_fontAsset;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// The TMP Sprite Asset assigned to this sub text object.
|
||||
/// </summary>
|
||||
public SpriteAsset spriteAsset
|
||||
{
|
||||
get { return m_spriteAsset; }
|
||||
set { m_spriteAsset = value; }
|
||||
}
|
||||
[SerializeField]
|
||||
private 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 = TMP_Settings.hideSubTextObjects ? HideFlags.HideAndDontSave : 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
|
||||
TextEventManager.MATERIAL_PROPERTY_EVENT.Add(ON_MATERIAL_PROPERTY_CHANGED);
|
||||
TextEventManager.FONT_PROPERTY_EVENT.Add(ON_FONT_PROPERTY_CHANGED);
|
||||
//TMPro_EventManager.TEXTMESHPRO_PROPERTY_EVENT.Add(ON_TEXTMESHPRO_PROPERTY_CHANGED);
|
||||
TextEventManager.DRAG_AND_DROP_MATERIAL_EVENT.Add(ON_DRAG_AND_DROP_MATERIAL);
|
||||
//TMPro_EventManager.TEXT_STYLE_PROPERTY_EVENT.Add(ON_TEXT_STYLE_CHANGED);
|
||||
TextEventManager.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
|
||||
TextEventManager.MATERIAL_PROPERTY_EVENT.Remove(ON_MATERIAL_PROPERTY_CHANGED);
|
||||
TextEventManager.FONT_PROPERTY_EVENT.Remove(ON_FONT_PROPERTY_CHANGED);
|
||||
//TMPro_EventManager.TEXTMESHPRO_PROPERTY_EVENT.Remove(ON_TEXTMESHPRO_PROPERTY_CHANGED);
|
||||
TextEventManager.DRAG_AND_DROP_MATERIAL_EVENT.Remove(ON_DRAG_AND_DROP_MATERIAL);
|
||||
//TMPro_EventManager.TEXT_STYLE_PROPERTY_EVENT.Remove(ON_TEXT_STYLE_CHANGED);
|
||||
TextEventManager.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 != 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
|
||||
}
|
||||
}
|
||||
}
|
12
Assets/TextMesh Pro/Scripts/Runtime/TMP_SubMeshUI.cs.meta
Normal file
12
Assets/TextMesh Pro/Scripts/Runtime/TMP_SubMeshUI.cs.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f7f41dde6d2eaef4593c0f1d91033a5c
|
||||
timeCreated: 1454709708
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8655
Assets/TextMesh Pro/Scripts/Runtime/TMP_Text.cs
Normal file
8655
Assets/TextMesh Pro/Scripts/Runtime/TMP_Text.cs
Normal file
File diff suppressed because it is too large
Load Diff
12
Assets/TextMesh Pro/Scripts/Runtime/TMP_Text.cs.meta
Normal file
12
Assets/TextMesh Pro/Scripts/Runtime/TMP_Text.cs.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 23c7f259856fc274ba4a2e36bc2f8294
|
||||
timeCreated: 1445841744
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
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: dd20da212080cb64fa4dab66748e32c2
|
||||
timeCreated: 1448407070
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
314
Assets/TextMesh Pro/Scripts/Runtime/TMP_TextInfo.cs
Normal file
314
Assets/TextMesh Pro/Scripts/Runtime/TMP_TextInfo.cs
Normal file
@@ -0,0 +1,314 @@
|
||||
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>
|
||||
internal 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>
|
||||
internal void ClearLineInfo()
|
||||
{
|
||||
if (this.lineInfo == null)
|
||||
this.lineInfo = new TMP_LineInfo[1];
|
||||
|
||||
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].visibleCharacterCount = 0;
|
||||
this.lineInfo[i].visibleSpaceCount = 0;
|
||||
|
||||
this.lineInfo[i].ascender = k_InfinityVectorNegative.x;
|
||||
this.lineInfo[i].baseline = 0;
|
||||
this.lineInfo[i].descender = k_InfinityVectorPositive.x;
|
||||
this.lineInfo[i].maxAdvance = 0;
|
||||
|
||||
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].width = 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 Vector4[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 Vector4[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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
12
Assets/TextMesh Pro/Scripts/Runtime/TMP_TextInfo.cs.meta
Normal file
12
Assets/TextMesh Pro/Scripts/Runtime/TMP_TextInfo.cs.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c45f7c77e33838249b1ba5ef9967cfe5
|
||||
timeCreated: 1446589998
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
171
Assets/TextMesh Pro/Scripts/Runtime/TMP_TextParsingUtilities.cs
Normal file
171
Assets/TextMesh Pro/Scripts/Runtime/TMP_TextParsingUtilities.cs
Normal file
@@ -0,0 +1,171 @@
|
||||
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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="c"></param>
|
||||
/// <returns></returns>
|
||||
internal static bool IsDiacriticalMark(uint c)
|
||||
{
|
||||
return c >= 0x300 && c <= 0x36F || c >= 0x1AB0 && c <= 0x1AFF || c >= 0x1DC0 && c <= 0x1DFF || c >= 0x20D0 && c <= 0x20FF || c >= 0xFE20 && c <= 0xFE2F;
|
||||
}
|
||||
|
||||
internal static bool IsBaseGlyph(uint c)
|
||||
{
|
||||
return !(c >= 0x300 && c <= 0x36F || c >= 0x1AB0 && c <= 0x1AFF || c >= 0x1DC0 && c <= 0x1DFF || c >= 0x20D0 && c <= 0x20FF || c >= 0xFE20 && c <= 0xFE2F ||
|
||||
// Thai Marks
|
||||
c == 0xE31 || c >= 0xE34 && c <= 0xE3A || c >= 0xE47 && c <= 0xE4E ||
|
||||
// Hebrew Marks
|
||||
c >= 0x591 && c <= 0x5BD || c == 0x5BF || c >= 0x5C1 && c <= 0x5C2 || c >= 0x5C4 && c <= 0x5C5 || c == 0x5C7 ||
|
||||
// Arabic Marks
|
||||
c >= 0x610 && c <= 0x61A || c >= 0x64B && c <= 0x65F || c == 0x670 || c >= 0x6D6 && c <= 0x6DC || c >= 0x6DF && c <= 0x6E4 || c >= 0x6E7 && c <= 0x6E8 || c >= 0x6EA && c <= 0x6ED ||
|
||||
c >= 0x8D3 && c <= 0x8E1 || c >= 0x8E3 && c <= 0x8FF ||
|
||||
c >= 0xFBB2 && c <= 0xFBC1
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 038259973ac4c2d46b1fb39c2ffad201
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
403
Assets/TextMesh Pro/Scripts/Runtime/TMP_TextProcessingStack.cs
Normal file
403
Assets/TextMesh Pro/Scripts/Runtime/TMP_TextProcessingStack.cs
Normal file
@@ -0,0 +1,403 @@
|
||||
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;
|
||||
m_Count = 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;
|
||||
m_Count -= 1;
|
||||
|
||||
if (index <= 0)
|
||||
{
|
||||
m_Count = 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: ac75765659b30f4458fbc9a2e0972114
|
||||
timeCreated: 1448242247
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
2419
Assets/TextMesh Pro/Scripts/Runtime/TMP_TextUtilities.cs
Normal file
2419
Assets/TextMesh Pro/Scripts/Runtime/TMP_TextUtilities.cs
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 95637875cc1d1a543b787c13cbf63bf1
|
||||
timeCreated: 1432117579
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
249
Assets/TextMesh Pro/Scripts/Runtime/TMP_UpdateManager.cs
Normal file
249
Assets/TextMesh Pro/Scripts/Runtime/TMP_UpdateManager.cs
Normal file
@@ -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: b9f8c41802e966c46b574fd1d0c40057
|
||||
timeCreated: 1447406424
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
177
Assets/TextMesh Pro/Scripts/Runtime/TMP_UpdateRegistery.cs
Normal file
177
Assets/TextMesh Pro/Scripts/Runtime/TMP_UpdateRegistery.cs
Normal file
@@ -0,0 +1,177 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using UnityEngine.UI.Collections;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
|
||||
namespace TMPro
|
||||
{
|
||||
/// <summary>
|
||||
/// Class for handling and scheduling text object updates.
|
||||
/// </summary>
|
||||
public class TMP_UpdateRegistry
|
||||
{
|
||||
private static TMP_UpdateRegistry s_Instance;
|
||||
|
||||
private readonly List<ICanvasElement> m_LayoutRebuildQueue = new List<ICanvasElement>();
|
||||
private HashSet<int> m_LayoutQueueLookup = new HashSet<int>();
|
||||
|
||||
private readonly List<ICanvasElement> m_GraphicRebuildQueue = new List<ICanvasElement>();
|
||||
private HashSet<int> m_GraphicQueueLookup = new HashSet<int>();
|
||||
|
||||
//private bool m_PerformingLayoutUpdate;
|
||||
//private bool m_PerformingGraphicUpdate;
|
||||
|
||||
/// <summary>
|
||||
/// Get a singleton instance of the registry
|
||||
/// </summary>
|
||||
public static TMP_UpdateRegistry instance
|
||||
{
|
||||
get
|
||||
{
|
||||
if (TMP_UpdateRegistry.s_Instance == null)
|
||||
TMP_UpdateRegistry.s_Instance = new TMP_UpdateRegistry();
|
||||
return TMP_UpdateRegistry.s_Instance;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Register to receive callback from the Canvas System.
|
||||
/// </summary>
|
||||
protected TMP_UpdateRegistry()
|
||||
{
|
||||
//Debug.Log("Adding WillRenderCanvases");
|
||||
Canvas.willRenderCanvases += PerformUpdateForCanvasRendererObjects;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function to register elements which require a layout rebuild.
|
||||
/// </summary>
|
||||
/// <param name="element"></param>
|
||||
public static void RegisterCanvasElementForLayoutRebuild(ICanvasElement element)
|
||||
{
|
||||
TMP_UpdateRegistry.instance.InternalRegisterCanvasElementForLayoutRebuild(element);
|
||||
}
|
||||
|
||||
private bool InternalRegisterCanvasElementForLayoutRebuild(ICanvasElement element)
|
||||
{
|
||||
int id = (element as Object).GetInstanceID();
|
||||
|
||||
if (m_LayoutQueueLookup.Contains(id))
|
||||
return false;
|
||||
|
||||
m_LayoutQueueLookup.Add(id);
|
||||
m_LayoutRebuildQueue.Add(element);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function to register elements which require a graphic rebuild.
|
||||
/// </summary>
|
||||
/// <param name="element"></param>
|
||||
public static void RegisterCanvasElementForGraphicRebuild(ICanvasElement element)
|
||||
{
|
||||
TMP_UpdateRegistry.instance.InternalRegisterCanvasElementForGraphicRebuild(element);
|
||||
}
|
||||
|
||||
private bool InternalRegisterCanvasElementForGraphicRebuild(ICanvasElement element)
|
||||
{
|
||||
int id = (element as Object).GetInstanceID();
|
||||
|
||||
if (m_GraphicQueueLookup.Contains(id))
|
||||
return false;
|
||||
|
||||
m_GraphicQueueLookup.Add(id);
|
||||
m_GraphicRebuildQueue.Add(element);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Method to handle objects that need updating.
|
||||
/// </summary>
|
||||
private void PerformUpdateForCanvasRendererObjects()
|
||||
{
|
||||
//Debug.Log("Performing update of CanvasRenderer objects at Frame: " + Time.frameCount);
|
||||
|
||||
// Processing elements that require a layout rebuild.
|
||||
//this.m_PerformingLayoutUpdate = true;
|
||||
for (int index = 0; index < m_LayoutRebuildQueue.Count; index++)
|
||||
{
|
||||
ICanvasElement element = TMP_UpdateRegistry.instance.m_LayoutRebuildQueue[index];
|
||||
|
||||
element.Rebuild(CanvasUpdate.Prelayout);
|
||||
}
|
||||
|
||||
if (m_LayoutRebuildQueue.Count > 0)
|
||||
{
|
||||
m_LayoutRebuildQueue.Clear();
|
||||
m_LayoutQueueLookup.Clear();
|
||||
}
|
||||
|
||||
// Update font assets before graphic rebuild
|
||||
|
||||
|
||||
// Processing elements that require a graphic rebuild.
|
||||
for (int index = 0; index < m_GraphicRebuildQueue.Count; index++)
|
||||
{
|
||||
ICanvasElement element = TMP_UpdateRegistry.instance.m_GraphicRebuildQueue[index];
|
||||
|
||||
element.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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Method to handle objects that need updating.
|
||||
/// </summary>
|
||||
private void PerformUpdateForMeshRendererObjects()
|
||||
{
|
||||
Debug.Log("Perform update of MeshRenderer objects.");
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function to unregister elements which no longer require a rebuild.
|
||||
/// </summary>
|
||||
/// <param name="element"></param>
|
||||
public static void UnRegisterCanvasElementForRebuild(ICanvasElement element)
|
||||
{
|
||||
TMP_UpdateRegistry.instance.InternalUnRegisterCanvasElementForLayoutRebuild(element);
|
||||
TMP_UpdateRegistry.instance.InternalUnRegisterCanvasElementForGraphicRebuild(element);
|
||||
}
|
||||
|
||||
|
||||
private void InternalUnRegisterCanvasElementForLayoutRebuild(ICanvasElement element)
|
||||
{
|
||||
int id = (element as Object).GetInstanceID();
|
||||
|
||||
//element.LayoutComplete();
|
||||
TMP_UpdateRegistry.instance.m_LayoutRebuildQueue.Remove(element);
|
||||
m_GraphicQueueLookup.Remove(id);
|
||||
}
|
||||
|
||||
|
||||
private void InternalUnRegisterCanvasElementForGraphicRebuild(ICanvasElement element)
|
||||
{
|
||||
int id = (element as Object).GetInstanceID();
|
||||
|
||||
//element.GraphicUpdateComplete();
|
||||
TMP_UpdateRegistry.instance.m_GraphicRebuildQueue.Remove(element);
|
||||
m_LayoutQueueLookup.Remove(id);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: dc3b1c25534f87a4e95f0568febdcbb0
|
||||
timeCreated: 1446775434
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
282
Assets/TextMesh Pro/Scripts/Runtime/TMPro_ExtensionMethods.cs
Normal file
282
Assets/TextMesh Pro/Scripts/Runtime/TMPro_ExtensionMethods.cs
Normal file
@@ -0,0 +1,282 @@
|
||||
using UnityEngine;
|
||||
using System.Text;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace TMPro
|
||||
{
|
||||
public static class TMPro_ExtensionMethods
|
||||
{
|
||||
|
||||
public static int[] ToIntArray(this string text)
|
||||
{
|
||||
int[] intArray = new int[text.Length];
|
||||
|
||||
for (int i = 0; i < text.Length; i++)
|
||||
{
|
||||
intArray[i] = text[i];
|
||||
}
|
||||
|
||||
return intArray;
|
||||
}
|
||||
|
||||
public static string ArrayToString(this char[] chars)
|
||||
{
|
||||
string s = string.Empty;
|
||||
|
||||
for (int i = 0; i < chars.Length && chars[i] != 0; i++)
|
||||
{
|
||||
s += chars[i];
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
public static string IntToString(this int[] unicodes)
|
||||
{
|
||||
char[] chars = new char[unicodes.Length];
|
||||
|
||||
for (int i = 0; i < unicodes.Length; i++)
|
||||
{
|
||||
chars[i] = (char)unicodes[i];
|
||||
}
|
||||
|
||||
return new string(chars);
|
||||
}
|
||||
|
||||
internal static string UintToString(this List<uint> unicodes)
|
||||
{
|
||||
char[] chars = new char[unicodes.Count];
|
||||
|
||||
for (int i = 0; i < unicodes.Count; i++)
|
||||
{
|
||||
chars[i] = (char)unicodes[i];
|
||||
}
|
||||
|
||||
return new string(chars);
|
||||
}
|
||||
|
||||
public static string IntToString(this int[] unicodes, int start, int length)
|
||||
{
|
||||
if (start > unicodes.Length)
|
||||
return string.Empty;
|
||||
|
||||
int end = Mathf.Min(start + length, unicodes.Length);
|
||||
|
||||
char[] chars = new char[end - start];
|
||||
|
||||
int writeIndex = 0;
|
||||
|
||||
for (int i = start; i < end; i++)
|
||||
{
|
||||
chars[writeIndex++] = (char)unicodes[i];
|
||||
}
|
||||
|
||||
return new string(chars);
|
||||
}
|
||||
|
||||
|
||||
public static int FindInstanceID <T> (this List<T> list, T target) where T : Object
|
||||
{
|
||||
int targetID = target.GetInstanceID();
|
||||
|
||||
for (int i = 0; i < list.Count; i++)
|
||||
{
|
||||
if (list[i].GetInstanceID() == targetID)
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
public static bool Compare(this Color32 a, Color32 b)
|
||||
{
|
||||
return a.r == b.r && a.g == b.g && a.b == b.b && a.a == b.a;
|
||||
}
|
||||
|
||||
public static bool CompareRGB(this Color32 a, Color32 b)
|
||||
{
|
||||
return a.r == b.r && a.g == b.g && a.b == b.b;
|
||||
}
|
||||
|
||||
public static bool Compare(this Color a, Color b)
|
||||
{
|
||||
return a.r == b.r && a.g == b.g && a.b == b.b && a.a == b.a;
|
||||
}
|
||||
|
||||
|
||||
public static bool CompareRGB(this Color a, Color b)
|
||||
{
|
||||
return a.r == b.r && a.g == b.g && a.b == b.b;
|
||||
}
|
||||
|
||||
|
||||
public static Color32 Multiply (this Color32 c1, Color32 c2)
|
||||
{
|
||||
byte r = (byte)((c1.r / 255f) * (c2.r / 255f) * 255);
|
||||
byte g = (byte)((c1.g / 255f) * (c2.g / 255f) * 255);
|
||||
byte b = (byte)((c1.b / 255f) * (c2.b / 255f) * 255);
|
||||
byte a = (byte)((c1.a / 255f) * (c2.a / 255f) * 255);
|
||||
|
||||
return new Color32(r, g, b, a);
|
||||
}
|
||||
|
||||
|
||||
public static Color32 Tint (this Color32 c1, Color32 c2)
|
||||
{
|
||||
byte r = (byte)((c1.r / 255f) * (c2.r / 255f) * 255);
|
||||
byte g = (byte)((c1.g / 255f) * (c2.g / 255f) * 255);
|
||||
byte b = (byte)((c1.b / 255f) * (c2.b / 255f) * 255);
|
||||
byte a = (byte)((c1.a / 255f) * (c2.a / 255f) * 255);
|
||||
|
||||
return new Color32(r, g, b, a);
|
||||
}
|
||||
|
||||
public static Color32 Tint(this Color32 c1, float tint)
|
||||
{
|
||||
byte r = (byte)(Mathf.Clamp(c1.r / 255f * tint * 255, 0, 255));
|
||||
byte g = (byte)(Mathf.Clamp(c1.g / 255f * tint * 255, 0, 255));
|
||||
byte b = (byte)(Mathf.Clamp(c1.b / 255f * tint * 255, 0, 255));
|
||||
byte a = (byte)(Mathf.Clamp(c1.a / 255f * tint * 255, 0, 255));
|
||||
|
||||
return new Color32(r, g, b, a);
|
||||
}
|
||||
|
||||
internal static Color32 GammaToLinear(this Color32 c)
|
||||
{
|
||||
return new Color32(GammaToLinear(c.r), GammaToLinear(c.g), GammaToLinear(c.b), c.a);
|
||||
}
|
||||
|
||||
static byte GammaToLinear(byte value)
|
||||
{
|
||||
float v = value / 255f;
|
||||
|
||||
if (v <= 0.04045f)
|
||||
return (byte)(v / 12.92f * 255f);
|
||||
|
||||
if (v < 1.0f)
|
||||
return (byte)(Mathf.Pow((v + 0.055f) / 1.055f, 2.4f) * 255);
|
||||
|
||||
if (v == 1.0f)
|
||||
return 255;
|
||||
|
||||
return (byte)(Mathf.Pow(v, 2.2f) * 255);
|
||||
}
|
||||
|
||||
public static Color MinAlpha(this Color c1, Color c2)
|
||||
{
|
||||
float a = c1.a < c2.a ? c1.a : c2.a;
|
||||
|
||||
return new Color(c1.r, c1.g, c1.b, a);
|
||||
}
|
||||
|
||||
|
||||
public static bool Compare(this Vector3 v1, Vector3 v2, int accuracy)
|
||||
{
|
||||
bool x = (int)(v1.x * accuracy) == (int)(v2.x * accuracy);
|
||||
bool y = (int)(v1.y * accuracy) == (int)(v2.y * accuracy);
|
||||
bool z = (int)(v1.z * accuracy) == (int)(v2.z * accuracy);
|
||||
|
||||
return x && y && z;
|
||||
}
|
||||
|
||||
public static bool Compare(this Quaternion q1, Quaternion q2, int accuracy)
|
||||
{
|
||||
bool x = (int)(q1.x * accuracy) == (int)(q2.x * accuracy);
|
||||
bool y = (int)(q1.y * accuracy) == (int)(q2.y * accuracy);
|
||||
bool z = (int)(q1.z * accuracy) == (int)(q2.z * accuracy);
|
||||
bool w = (int)(q1.w * accuracy) == (int)(q2.w * accuracy);
|
||||
|
||||
return x && y && z && w;
|
||||
}
|
||||
|
||||
//public static void AddElementAtIndex<T>(this T[] array, int writeIndex, T item)
|
||||
//{
|
||||
// if (writeIndex >= array.Length)
|
||||
// System.Array.Resize(ref array, Mathf.NextPowerOfTwo(writeIndex + 1));
|
||||
|
||||
// array[writeIndex] = item;
|
||||
//}
|
||||
|
||||
/// <summary>
|
||||
/// Insert item into array at index.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="array"></param>
|
||||
/// <param name="index"></param>
|
||||
/// <param name="item"></param>
|
||||
//public static void Insert<T>(this T[] array, int index, T item)
|
||||
//{
|
||||
// if (index > array.Length - 1) return;
|
||||
|
||||
// T savedItem = item;
|
||||
|
||||
// for (int i = index; i < array.Length; i++)
|
||||
// {
|
||||
// savedItem = array[i];
|
||||
|
||||
// array[i] = item;
|
||||
|
||||
// item = savedItem;
|
||||
// }
|
||||
//}
|
||||
|
||||
/// <summary>
|
||||
/// Insert item into array at index.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="array"></param>
|
||||
/// <param name="index"></param>
|
||||
/// <param name="item"></param>
|
||||
//public static void Insert<T>(this T[] array, int index, T[] items)
|
||||
//{
|
||||
// if (index > array.Length - 1) return;
|
||||
|
||||
// System.Array.Resize(ref array, array.Length + items.Length);
|
||||
|
||||
// int sourceIndex = 0;
|
||||
|
||||
// T savedItem = items[sourceIndex];
|
||||
|
||||
// for (int i = index; i < array.Length; i++)
|
||||
// {
|
||||
// savedItem = array[i];
|
||||
|
||||
// array[i] = items[sourceIndex];
|
||||
|
||||
// items[sourceIndex] = savedItem;
|
||||
|
||||
// if (sourceIndex < items.Length - 1)
|
||||
// sourceIndex += 1;
|
||||
// else
|
||||
// sourceIndex = 0;
|
||||
// }
|
||||
//}
|
||||
|
||||
}
|
||||
|
||||
public static class TMP_Math
|
||||
{
|
||||
public const float FLOAT_MAX = 32767;
|
||||
public const float FLOAT_MIN = -32767;
|
||||
public const int INT_MAX = 2147483647;
|
||||
public const int INT_MIN = -2147483647;
|
||||
|
||||
public const float FLOAT_UNSET = -32767;
|
||||
public const int INT_UNSET = -32767;
|
||||
|
||||
public static Vector2 MAX_16BIT = new Vector2(FLOAT_MAX, FLOAT_MAX);
|
||||
public static Vector2 MIN_16BIT = new Vector2(FLOAT_MIN, FLOAT_MIN);
|
||||
|
||||
public static bool Approximately(float a, float b)
|
||||
{
|
||||
return (b - 0.0001f) < a && a < (b + 0.0001f);
|
||||
}
|
||||
|
||||
public static int Mod(int a, int b)
|
||||
{
|
||||
int r = a % b;
|
||||
return r < 0 ? r + b : r;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9568132c3c8cdd24887b44a8d1700d2b
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
454
Assets/TextMesh Pro/Scripts/Runtime/TMPro_MeshUtilities.cs
Normal file
454
Assets/TextMesh Pro/Scripts/Runtime/TMPro_MeshUtilities.cs
Normal file
@@ -0,0 +1,454 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.TextCore.Text;
|
||||
using System;
|
||||
|
||||
|
||||
namespace TMPro
|
||||
{
|
||||
/// <summary>
|
||||
/// Flags to control what vertex data is pushed to the mesh and renderer.
|
||||
/// </summary>
|
||||
public enum TMP_VertexDataUpdateFlags
|
||||
{
|
||||
None = 0x0,
|
||||
Vertices = 0x1,
|
||||
Uv0 = 0x2,
|
||||
Uv2 = 0x4,
|
||||
Uv4 = 0x8,
|
||||
Colors32 = 0x10,
|
||||
All = 0xFF
|
||||
};
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// TMP custom data type to represent 32 bit characters.
|
||||
/// </summary>
|
||||
//public struct TMP_Char
|
||||
//{
|
||||
// private int m_value;
|
||||
|
||||
// private TMP_Char(int value)
|
||||
// {
|
||||
// this.m_value = value;
|
||||
// }
|
||||
|
||||
// private TMP_Char(TMP_Char value)
|
||||
// {
|
||||
// this.m_value = (int)value;
|
||||
// }
|
||||
|
||||
// public static implicit operator TMP_Char(int value)
|
||||
// {
|
||||
// return new TMP_Char(value);
|
||||
// }
|
||||
|
||||
// public static implicit operator TMP_Char(char c)
|
||||
// {
|
||||
// return new TMP_Char(c);
|
||||
// }
|
||||
|
||||
// public static explicit operator int(TMP_Char value)
|
||||
// {
|
||||
// return value.m_value;
|
||||
// }
|
||||
|
||||
// public override string ToString()
|
||||
// {
|
||||
// return m_value.ToString();
|
||||
// }
|
||||
//}
|
||||
|
||||
|
||||
//public struct TMP_VertexInfo
|
||||
//{
|
||||
// public TMP_Vertex topLeft;
|
||||
// public TMP_Vertex bottomLeft;
|
||||
// public TMP_Vertex topRight;
|
||||
// public TMP_Vertex bottomRight;
|
||||
//}
|
||||
|
||||
|
||||
[Serializable]
|
||||
public struct VertexGradient
|
||||
{
|
||||
public Color topLeft;
|
||||
public Color topRight;
|
||||
public Color bottomLeft;
|
||||
public Color bottomRight;
|
||||
|
||||
public VertexGradient (Color color)
|
||||
{
|
||||
this.topLeft = color;
|
||||
this.topRight = color;
|
||||
this.bottomLeft = color;
|
||||
this.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 VertexGradient(Color color0, Color color1, Color color2, Color color3)
|
||||
{
|
||||
this.topLeft = color0;
|
||||
this.topRight = color1;
|
||||
this.bottomLeft = color2;
|
||||
this.bottomRight = color3;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public struct TMP_PageInfo
|
||||
{
|
||||
public int firstCharacterIndex;
|
||||
public int lastCharacterIndex;
|
||||
public float ascender;
|
||||
public float baseLine;
|
||||
public float descender;
|
||||
// public float extents;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Structure containing information about individual links contained in the text object.
|
||||
/// </summary>
|
||||
public struct TMP_LinkInfo
|
||||
{
|
||||
public TMP_Text textComponent;
|
||||
|
||||
public int hashCode;
|
||||
|
||||
public int linkIdFirstCharacterIndex;
|
||||
public int linkIdLength;
|
||||
public int linkTextfirstCharacterIndex;
|
||||
public int linkTextLength;
|
||||
|
||||
internal char[] linkID;
|
||||
|
||||
|
||||
internal void SetLinkID(char[] text, int startIndex, int length)
|
||||
{
|
||||
if (linkID == null || linkID.Length < length) linkID = new char[length];
|
||||
|
||||
for (int i = 0; i < length; i++)
|
||||
linkID[i] = text[startIndex + i];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Function which returns the text contained in a link.
|
||||
/// </summary>
|
||||
/// <param name="textInfo"></param>
|
||||
/// <returns></returns>
|
||||
public string GetLinkText()
|
||||
{
|
||||
string text = string.Empty;
|
||||
TMP_TextInfo textInfo = textComponent.textInfo;
|
||||
|
||||
for (int i = linkTextfirstCharacterIndex; i < linkTextfirstCharacterIndex + linkTextLength; i++)
|
||||
text += textInfo.characterInfo[i].character;
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function which returns the link ID as a string.
|
||||
/// </summary>
|
||||
/// <param name="text">The source input text.</param>
|
||||
/// <returns></returns>
|
||||
public string GetLinkID()
|
||||
{
|
||||
if (textComponent == null)
|
||||
return string.Empty;
|
||||
|
||||
return new string(linkID, 0, linkIdLength);
|
||||
//return textComponent.text.Substring(linkIdFirstCharacterIndex, linkIdLength);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Structure containing information about the individual words contained in the text object.
|
||||
/// </summary>
|
||||
public struct TMP_WordInfo
|
||||
{
|
||||
// NOTE: Structure could be simplified by only including the firstCharacterIndex and length.
|
||||
|
||||
public TMP_Text textComponent;
|
||||
|
||||
public int firstCharacterIndex;
|
||||
public int lastCharacterIndex;
|
||||
public int characterCount;
|
||||
//public float length;
|
||||
|
||||
/// <summary>
|
||||
/// Returns the word as a string.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public string GetWord()
|
||||
{
|
||||
string word = string.Empty;
|
||||
TMP_CharacterInfo[] charInfo = textComponent.textInfo.characterInfo;
|
||||
|
||||
for (int i = firstCharacterIndex; i < lastCharacterIndex + 1; i++)
|
||||
{
|
||||
word += charInfo[i].character;
|
||||
}
|
||||
|
||||
return word;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public struct TMP_SpriteInfo
|
||||
{
|
||||
public int spriteIndex; // Index of the sprite in the sprite atlas.
|
||||
public int characterIndex; // The characterInfo index which holds the key information about this sprite.
|
||||
public int vertexIndex;
|
||||
}
|
||||
|
||||
|
||||
//public struct SpriteInfo
|
||||
//{
|
||||
//
|
||||
//}
|
||||
|
||||
|
||||
public struct Extents
|
||||
{
|
||||
internal static Extents zero = new Extents(Vector2.zero, Vector2.zero);
|
||||
internal static Extents uninitialized = new Extents(new Vector2(32767, 32767), new Vector2(-32767, -32767));
|
||||
|
||||
public Vector2 min;
|
||||
public Vector2 max;
|
||||
|
||||
public Extents(Vector2 min, Vector2 max)
|
||||
{
|
||||
this.min = min;
|
||||
this.max = max;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
string s = "Min (" + min.x.ToString("f2") + ", " + min.y.ToString("f2") + ") Max (" + max.x.ToString("f2") + ", " + max.y.ToString("f2") + ")";
|
||||
return s;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[Serializable]
|
||||
public struct Mesh_Extents
|
||||
{
|
||||
public Vector2 min;
|
||||
public Vector2 max;
|
||||
|
||||
|
||||
public Mesh_Extents(Vector2 min, Vector2 max)
|
||||
{
|
||||
this.min = min;
|
||||
this.max = max;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
string s = "Min (" + min.x.ToString("f2") + ", " + min.y.ToString("f2") + ") Max (" + max.x.ToString("f2") + ", " + max.y.ToString("f2") + ")";
|
||||
//string s = "Center: (" + ")" + " Extents: (" + ((max.x - min.x) / 2).ToString("f2") + "," + ((max.y - min.y) / 2).ToString("f2") + ").";
|
||||
return s;
|
||||
}
|
||||
}
|
||||
|
||||
// internal struct TMP_TextProcessingState
|
||||
// {
|
||||
// // Multi Font & Material support related
|
||||
// public TMP_FontAsset CurrentFontAsset;
|
||||
// public TMP_SpriteAsset CurrentSpriteAsset;
|
||||
// public Material CurrentMaterial;
|
||||
// public int CurrentMaterialIndex;
|
||||
//
|
||||
// public float CurrentFontSize;
|
||||
// public float FontScale;
|
||||
// public float FontScaleMultiplier;
|
||||
// public FontStyles FontStyle;
|
||||
// public int ItalicAngle;
|
||||
//
|
||||
// public float CharacterSpacing;
|
||||
// public float CharacterMonoSpacing;
|
||||
// public bool TagNoParsing;
|
||||
//
|
||||
// public float HorizontalAdvance;
|
||||
// public float MaxCapHeight;
|
||||
// public float MaxTextAscender;
|
||||
// public float MaxTextDescender;
|
||||
// public float MaxElementAscender;
|
||||
// public float MaxElementDescender;
|
||||
// public float StartOfLineAscender;
|
||||
// public float MaxLineAscender;
|
||||
// public float MaxLineDescender;
|
||||
// public float PageAscender;
|
||||
//
|
||||
// public int PreviousWordBreak;
|
||||
// public int TotalCharacterCount;
|
||||
// //public int VisibleCharacterCount;
|
||||
// //public int VisibleSpriteCount;
|
||||
// public int VisibleLinkCount;
|
||||
// public int FirstCharacterIndex;
|
||||
// public int FirstVisibleCharacterIndex;
|
||||
// public int LastCharacterIndex;
|
||||
// public int LastVisibleCharIndex;
|
||||
//
|
||||
// public int LineNumber;
|
||||
// public float baselineOffset;
|
||||
// public float lineOffset;
|
||||
// public bool isDrivenLineSpacing;
|
||||
// public bool IsNonBreakingSpace;
|
||||
//
|
||||
// public HorizontalAlignmentOptions HorizontalAlignment;
|
||||
// public float MarginLeft;
|
||||
// public float MarginRight;
|
||||
//
|
||||
// public float PreferredWidth;
|
||||
// public float PreferredHeight;
|
||||
//
|
||||
// public Color32 VertexColor;
|
||||
// public Color32 UnderlineColor;
|
||||
// public Color32 StrikethroughColor;
|
||||
// //public Color32 HighlightColor;
|
||||
//
|
||||
// public Extents MeshExtents;
|
||||
// public TMP_LineInfo lineInfo;
|
||||
//
|
||||
// public int spriteAnimationID;
|
||||
//
|
||||
// public TMP_FontStyleStack BasicStyleStack;
|
||||
// public TMP_RichTextTagStack<int> ItalicAngleStack;
|
||||
// public TMP_RichTextTagStack<Color32> ColorStack;
|
||||
// public TMP_RichTextTagStack<Color32> UnderlineColorStack;
|
||||
// public TMP_RichTextTagStack<Color32> StrikethroughColorStack;
|
||||
// public TMP_RichTextTagStack<Color32> HighlightColorStack;
|
||||
// public TMP_RichTextTagStack<HighlightState> HighlightStateStack;
|
||||
// public TMP_RichTextTagStack<TMP_ColorGradient> ColorGradientStack;
|
||||
// public TMP_RichTextTagStack<float> SizeStack;
|
||||
// public TMP_RichTextTagStack<float> IndentStack;
|
||||
// public TMP_RichTextTagStack<FontWeight> FontWeightStack;
|
||||
//
|
||||
// public TMP_RichTextTagStack<float> BaselineStack;
|
||||
// //public TMP_RichTextTagStack<int> ActionStack;
|
||||
// public TMP_RichTextTagStack<MaterialReference> MaterialReferenceStack;
|
||||
// public TMP_RichTextTagStack<HorizontalAlignmentOptions> LineJustificationStack;
|
||||
// }
|
||||
|
||||
|
||||
// Structure used for Word Wrapping which tracks the state of execution when the last space or carriage return character was encountered.
|
||||
internal struct WordWrapState
|
||||
{
|
||||
public int previous_WordBreak;
|
||||
public int total_CharacterCount;
|
||||
public int visible_CharacterCount;
|
||||
public int visibleSpaceCount;
|
||||
public int visible_SpriteCount;
|
||||
public int visible_LinkCount;
|
||||
public int firstCharacterIndex;
|
||||
public int firstVisibleCharacterIndex;
|
||||
public int lastCharacterIndex;
|
||||
public int lastVisibleCharIndex;
|
||||
public int lineNumber;
|
||||
|
||||
public float maxCapHeight;
|
||||
public float maxAscender;
|
||||
public float maxDescender;
|
||||
public float startOfLineAscender;
|
||||
public float maxLineAscender;
|
||||
public float maxLineDescender;
|
||||
public float pageAscender;
|
||||
|
||||
public HorizontalAlignmentOptions horizontalAlignment;
|
||||
public float marginLeft;
|
||||
public float marginRight;
|
||||
|
||||
public float xAdvance;
|
||||
public float preferredWidth;
|
||||
public float preferredHeight;
|
||||
public float renderedWidth;
|
||||
public float renderedHeight;
|
||||
|
||||
public float previousLineScale;
|
||||
|
||||
public int wordCount;
|
||||
public FontStyles fontStyle;
|
||||
public int italicAngle;
|
||||
public float fontScaleMultiplier;
|
||||
|
||||
public float currentFontSize;
|
||||
public float baselineOffset;
|
||||
public float lineOffset;
|
||||
public bool isDrivenLineSpacing;
|
||||
public int lastBaseGlyphIndex;
|
||||
|
||||
public float cSpace;
|
||||
public float mSpace;
|
||||
|
||||
public TMP_TextInfo textInfo;
|
||||
public TMP_LineInfo lineInfo;
|
||||
|
||||
public Color32 vertexColor;
|
||||
public Color32 underlineColor;
|
||||
public Color32 strikethroughColor;
|
||||
public HighlightState highlightState;
|
||||
public TMP_FontStyleStack basicStyleStack;
|
||||
public TMP_TextProcessingStack<int> italicAngleStack;
|
||||
public TMP_TextProcessingStack<Color32> colorStack;
|
||||
public TMP_TextProcessingStack<Color32> underlineColorStack;
|
||||
public TMP_TextProcessingStack<Color32> strikethroughColorStack;
|
||||
public TMP_TextProcessingStack<Color32> highlightColorStack;
|
||||
public TMP_TextProcessingStack<HighlightState> highlightStateStack;
|
||||
public TMP_TextProcessingStack<TextColorGradient> colorGradientStack;
|
||||
public TMP_TextProcessingStack<float> sizeStack;
|
||||
public TMP_TextProcessingStack<float> indentStack;
|
||||
public TMP_TextProcessingStack<FontWeight> fontWeightStack;
|
||||
public TMP_TextProcessingStack<int> styleStack;
|
||||
public TMP_TextProcessingStack<float> baselineStack;
|
||||
public TMP_TextProcessingStack<int> actionStack;
|
||||
public TMP_TextProcessingStack<MaterialReference> materialReferenceStack;
|
||||
public TMP_TextProcessingStack<HorizontalAlignmentOptions> lineJustificationStack;
|
||||
public int spriteAnimationID;
|
||||
|
||||
public FontAsset currentFontAsset;
|
||||
public SpriteAsset currentSpriteAsset;
|
||||
public Material currentMaterial;
|
||||
public int currentMaterialIndex;
|
||||
|
||||
public Extents meshExtents;
|
||||
|
||||
public bool tagNoParsing;
|
||||
public bool isNonBreakingSpace;
|
||||
|
||||
public Quaternion fxRotation;
|
||||
public Vector3 fxScale;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Structure used to store retrieve the name and hashcode of the font and material
|
||||
/// </summary>
|
||||
internal struct TagAttribute
|
||||
{
|
||||
public int startIndex;
|
||||
public int length;
|
||||
public int hashCode;
|
||||
}
|
||||
|
||||
internal struct RichTextTagAttribute
|
||||
{
|
||||
public int nameHashCode;
|
||||
public int valueHashCode;
|
||||
public TagValueType valueType;
|
||||
public int valueStartIndex;
|
||||
public int valueLength;
|
||||
public TagUnitType unitType;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9323986b00321ac41a213fd83306a299
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
4676
Assets/TextMesh Pro/Scripts/Runtime/TMPro_Private.cs
Normal file
4676
Assets/TextMesh Pro/Scripts/Runtime/TMPro_Private.cs
Normal file
File diff suppressed because it is too large
Load Diff
10
Assets/TextMesh Pro/Scripts/Runtime/TMPro_Private.cs.meta
Normal file
10
Assets/TextMesh Pro/Scripts/Runtime/TMPro_Private.cs.meta
Normal file
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f94b1bd11214f6c4c8ba63e12fd0fd4a
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {fileID: 2800000, guid: 8e098d8d28c5182419f7a1c8b91ca722, type: 3}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
4797
Assets/TextMesh Pro/Scripts/Runtime/TMPro_UGUI_Private.cs
Normal file
4797
Assets/TextMesh Pro/Scripts/Runtime/TMPro_UGUI_Private.cs
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 766d7412cffa6a649af948d0743cd31e
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {fileID: 2800000, guid: 8e098d8d28c5182419f7a1c8b91ca722, type: 3}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
370
Assets/TextMesh Pro/Scripts/Runtime/TextContainer.cs
Normal file
370
Assets/TextMesh Pro/Scripts/Runtime/TextContainer.cs
Normal file
@@ -0,0 +1,370 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
using System.Collections;
|
||||
|
||||
|
||||
namespace TMPro
|
||||
{
|
||||
|
||||
public enum TextContainerAnchors { TopLeft = 0, Top = 1, TopRight = 2, Left = 3, Middle = 4, Right = 5, BottomLeft = 6, Bottom = 7, BottomRight = 8, Custom = 9 };
|
||||
|
||||
|
||||
[RequireComponent(typeof(RectTransform))]
|
||||
//[AddComponentMenu("Layout/Text Container")]
|
||||
public class TextContainer : UIBehaviour
|
||||
{
|
||||
|
||||
#pragma warning disable 0618 // Disabled warning related to deprecated properties. This is for backwards compatibility.
|
||||
|
||||
public bool hasChanged
|
||||
{
|
||||
get { return m_hasChanged; }
|
||||
set { m_hasChanged = value; }
|
||||
}
|
||||
private bool m_hasChanged;
|
||||
|
||||
|
||||
// Pivot / Transform Position
|
||||
public Vector2 pivot
|
||||
{
|
||||
get { return m_pivot; }
|
||||
set { /*Debug.Log("Pivot has changed.");*/ if (m_pivot != value) { m_pivot = value; m_anchorPosition = GetAnchorPosition(m_pivot); m_hasChanged = true; OnContainerChanged(); } }
|
||||
}
|
||||
[SerializeField]
|
||||
private Vector2 m_pivot;
|
||||
|
||||
|
||||
public TextContainerAnchors anchorPosition
|
||||
{
|
||||
get { return m_anchorPosition; }
|
||||
set { /*Debug.Log("Anchor has changed.");*/ if (m_anchorPosition != value) { m_anchorPosition = value; m_pivot = GetPivot(m_anchorPosition); m_hasChanged = true; OnContainerChanged(); } }
|
||||
}
|
||||
[SerializeField]
|
||||
private TextContainerAnchors m_anchorPosition = TextContainerAnchors.Middle;
|
||||
|
||||
|
||||
// Rect which defines the Rectangle
|
||||
public Rect rect
|
||||
{
|
||||
get { return m_rect; }
|
||||
set { /*Debug.Log("Rectangle has changed.");*/ if (m_rect != value) { m_rect = value; /*m_size = new Vector2(m_rect.width, m_rect.height);*/ m_hasChanged = true; OnContainerChanged(); } }
|
||||
}
|
||||
[SerializeField]
|
||||
private Rect m_rect;
|
||||
|
||||
|
||||
public Vector2 size
|
||||
{
|
||||
get { return new Vector2(m_rect.width, m_rect.height); }
|
||||
set { /*Debug.Log("Size has changed.");*/ if (new Vector2(m_rect.width, m_rect.height) != value) { SetRect(value); m_hasChanged = true; m_isDefaultWidth = false; m_isDefaultHeight = false; OnContainerChanged(); } }
|
||||
}
|
||||
|
||||
|
||||
// Sets the width of the Text Container.
|
||||
public float width
|
||||
{
|
||||
get { return m_rect.width; }
|
||||
set { /*Debug.Log("Width has changed.");*/ SetRect(new Vector2(value, m_rect.height)); m_hasChanged = true; m_isDefaultWidth = false; OnContainerChanged(); }
|
||||
}
|
||||
|
||||
|
||||
// Sets the height of the Text Container.
|
||||
public float height
|
||||
{
|
||||
get { return m_rect.height; }
|
||||
set { SetRect(new Vector2(m_rect.width, value)); m_hasChanged = true; m_isDefaultHeight = false; OnContainerChanged(); }
|
||||
}
|
||||
|
||||
|
||||
// Used to determine if the user has changed the width of the Text Container.
|
||||
public bool isDefaultWidth
|
||||
{
|
||||
get { return m_isDefaultWidth; }
|
||||
}
|
||||
private bool m_isDefaultWidth;
|
||||
|
||||
// Used to determine if the user has changed the height of the Text Container.
|
||||
public bool isDefaultHeight
|
||||
{
|
||||
get { return m_isDefaultHeight; }
|
||||
}
|
||||
private bool m_isDefaultHeight;
|
||||
|
||||
|
||||
public bool isAutoFitting
|
||||
{
|
||||
get { return m_isAutoFitting; }
|
||||
set { m_isAutoFitting = value; }
|
||||
}
|
||||
private bool m_isAutoFitting = false;
|
||||
|
||||
|
||||
// Corners of the Text Container
|
||||
public Vector3[] corners
|
||||
{
|
||||
get { return m_corners; }
|
||||
}
|
||||
private Vector3[] m_corners = new Vector3[4];
|
||||
|
||||
|
||||
public Vector3[] worldCorners
|
||||
{
|
||||
get { return m_worldCorners; }
|
||||
}
|
||||
private Vector3[] m_worldCorners = new Vector3[4];
|
||||
|
||||
|
||||
//public Vector3 normal
|
||||
//{
|
||||
// get { return m_normal; }
|
||||
//}
|
||||
//private Vector3 m_normal;
|
||||
|
||||
|
||||
// The margin offset from the Rectangle Bounds
|
||||
public Vector4 margins
|
||||
{
|
||||
get { return m_margins; }
|
||||
set { if (m_margins != value) { /*Debug.Log("Margins have changed.");*/ m_margins = value; m_hasChanged = true; OnContainerChanged(); } }
|
||||
}
|
||||
[SerializeField]
|
||||
private Vector4 m_margins;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// The RectTransform used by the object
|
||||
/// </summary>
|
||||
public RectTransform rectTransform
|
||||
{
|
||||
get
|
||||
{
|
||||
if (m_rectTransform == null) m_rectTransform = GetComponent<RectTransform>();
|
||||
|
||||
return m_rectTransform;
|
||||
}
|
||||
}
|
||||
private RectTransform m_rectTransform;
|
||||
|
||||
|
||||
//private Transform m_transform;
|
||||
//private bool m_isAddingRectTransform;
|
||||
private static Vector2 k_defaultSize = new Vector2(100, 100);
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public TextMeshPro textMeshPro
|
||||
{
|
||||
get
|
||||
{
|
||||
if (m_textMeshPro == null) m_textMeshPro = GetComponent<TextMeshPro>();
|
||||
return m_textMeshPro;
|
||||
}
|
||||
}
|
||||
private TextMeshPro m_textMeshPro;
|
||||
|
||||
|
||||
protected override void Awake()
|
||||
{
|
||||
Debug.LogWarning("The Text Container component is now Obsolete and can safely be removed from [" + gameObject.name + "].", this);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
protected override void OnEnable()
|
||||
{
|
||||
//Debug.Log("Text Container OnEnable() called.");
|
||||
|
||||
OnContainerChanged();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
protected override void OnDisable()
|
||||
{
|
||||
//Debug.Log("OnDisable() called.");
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
void OnContainerChanged()
|
||||
{
|
||||
//Debug.Log("OnContainerChanged");
|
||||
|
||||
UpdateCorners();
|
||||
//UpdateWorldCorners();
|
||||
|
||||
if (this.m_rectTransform != null)
|
||||
{
|
||||
m_rectTransform.sizeDelta = this.size;
|
||||
m_rectTransform.hasChanged = true;
|
||||
}
|
||||
|
||||
if (this.textMeshPro != null)
|
||||
{
|
||||
m_textMeshPro.SetVerticesDirty();
|
||||
m_textMeshPro.margin = m_margins;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if UNITY_EDITOR
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
protected override void OnValidate()
|
||||
{
|
||||
//Debug.Log("OnValidate() called.");
|
||||
m_hasChanged = true;
|
||||
OnContainerChanged();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
void LateUpdate()
|
||||
{
|
||||
// Used by the Run Time Text Input Component ... This will have to be changed.
|
||||
if (m_transform.hasChanged)
|
||||
UpdateWorldCorners();
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Callback from Unity to handle RectTransform changes.
|
||||
/// </summary>
|
||||
protected override void OnRectTransformDimensionsChange()
|
||||
{
|
||||
// Required to add a RectTransform to objects created in previous releases.
|
||||
if (this.rectTransform == null) m_rectTransform = gameObject.AddComponent<RectTransform>();
|
||||
|
||||
if (m_rectTransform.sizeDelta != k_defaultSize)
|
||||
this.size = m_rectTransform.sizeDelta;
|
||||
|
||||
pivot = m_rectTransform.pivot;
|
||||
|
||||
m_hasChanged = true;
|
||||
OnContainerChanged();
|
||||
}
|
||||
|
||||
|
||||
private void SetRect(Vector2 size)
|
||||
{
|
||||
m_rect = new Rect(m_rect.x, m_rect.y, size.x, size.y);
|
||||
//UpdateCorners();
|
||||
}
|
||||
|
||||
private void UpdateCorners()
|
||||
{
|
||||
m_corners[0] = new Vector3(-m_pivot.x * m_rect.width, (- m_pivot.y) * m_rect.height);
|
||||
m_corners[1] = new Vector3(-m_pivot.x * m_rect.width, (1 - m_pivot.y) * m_rect.height);
|
||||
m_corners[2] = new Vector3((1 - m_pivot.x) * m_rect.width, (1 - m_pivot.y) * m_rect.height);
|
||||
m_corners[3] = new Vector3((1 - m_pivot.x) * m_rect.width, (- m_pivot.y) * m_rect.height);
|
||||
//Debug.Log("Pivot " + m_pivot + " Corners 0: " + m_corners[0] + " 1: " + m_corners[1] + " 2: " + m_corners[2] + " 3: " + m_corners[3]);
|
||||
|
||||
if (m_rectTransform != null)
|
||||
m_rectTransform.pivot = m_pivot;
|
||||
}
|
||||
|
||||
|
||||
//private void UpdateWorldCorners()
|
||||
//{
|
||||
// if (m_transform == null)
|
||||
// return;
|
||||
|
||||
// Vector3 position = m_transform.position;
|
||||
// m_worldCorners[0] = position + m_transform.TransformDirection(m_corners[0]);
|
||||
// m_worldCorners[1] = position + m_transform.TransformDirection(m_corners[1]);
|
||||
// m_worldCorners[2] = position + m_transform.TransformDirection(m_corners[2]);
|
||||
// m_worldCorners[3] = position + m_transform.TransformDirection(m_corners[3]);
|
||||
|
||||
// m_normal = Vector3.Cross(worldCorners[1] - worldCorners[0], worldCorners[3] - worldCorners[0]);
|
||||
//}
|
||||
|
||||
|
||||
//public Vector3[] GetWorldCorners()
|
||||
//{
|
||||
// UpdateWorldCorners();
|
||||
|
||||
// return m_worldCorners;
|
||||
//}
|
||||
|
||||
|
||||
Vector2 GetPivot(TextContainerAnchors anchor)
|
||||
{
|
||||
Vector2 pivot = Vector2.zero;
|
||||
|
||||
switch (anchor)
|
||||
{
|
||||
case TextContainerAnchors.TopLeft:
|
||||
pivot = new Vector2(0, 1);
|
||||
break;
|
||||
case TextContainerAnchors.Top:
|
||||
pivot = new Vector2(0.5f, 1);
|
||||
break;
|
||||
case TextContainerAnchors.TopRight:
|
||||
pivot = new Vector2(1, 1);
|
||||
break;
|
||||
case TextContainerAnchors.Left:
|
||||
pivot = new Vector2(0, 0.5f);
|
||||
break;
|
||||
case TextContainerAnchors.Middle:
|
||||
pivot = new Vector2(0.5f, 0.5f);
|
||||
break;
|
||||
case TextContainerAnchors.Right:
|
||||
pivot = new Vector2(1, 0.5f);
|
||||
break;
|
||||
case TextContainerAnchors.BottomLeft:
|
||||
pivot = new Vector2(0, 0);
|
||||
break;
|
||||
case TextContainerAnchors.Bottom:
|
||||
pivot = new Vector2(0.5f, 0);
|
||||
break;
|
||||
case TextContainerAnchors.BottomRight:
|
||||
pivot = new Vector2(1, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
return pivot;
|
||||
}
|
||||
|
||||
|
||||
// Method which returns the Anchor position based on pivot value.
|
||||
TextContainerAnchors GetAnchorPosition(Vector2 pivot)
|
||||
{
|
||||
|
||||
if (pivot == new Vector2(0, 1))
|
||||
return TextContainerAnchors.TopLeft;
|
||||
else if (pivot == new Vector2(0.5f, 1))
|
||||
return TextContainerAnchors.Top;
|
||||
else if (pivot == new Vector2(1f, 1))
|
||||
return TextContainerAnchors.TopRight;
|
||||
else if (pivot == new Vector2(0, 0.5f))
|
||||
return TextContainerAnchors.Left;
|
||||
else if (pivot == new Vector2(0.5f, 0.5f))
|
||||
return TextContainerAnchors.Middle;
|
||||
else if (pivot == new Vector2(1, 0.5f))
|
||||
return TextContainerAnchors.Right;
|
||||
else if (pivot == new Vector2(0, 0))
|
||||
return TextContainerAnchors.BottomLeft;
|
||||
else if (pivot == new Vector2(0.5f, 0))
|
||||
return TextContainerAnchors.Bottom;
|
||||
else if (pivot == new Vector2(1, 0))
|
||||
return TextContainerAnchors.BottomRight;
|
||||
else
|
||||
return TextContainerAnchors.Custom;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
12
Assets/TextMesh Pro/Scripts/Runtime/TextContainer.cs.meta
Normal file
12
Assets/TextMesh Pro/Scripts/Runtime/TextContainer.cs.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 807f87a683c74f74fb134d8694f780ce
|
||||
timeCreated: 1448498693
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: -110
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
468
Assets/TextMesh Pro/Scripts/Runtime/TextMeshPro.cs
Normal file
468
Assets/TextMesh Pro/Scripts/Runtime/TextMeshPro.cs
Normal file
@@ -0,0 +1,468 @@
|
||||
using UnityEngine;
|
||||
using System;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace TMPro
|
||||
{
|
||||
|
||||
[DisallowMultipleComponent]
|
||||
[RequireComponent(typeof(MeshRenderer))]
|
||||
[AddComponentMenu("Mesh/TextMeshPro - Text")]
|
||||
[ExecuteAlways]
|
||||
[HelpURL("https://docs.unity3d.com/Packages/com.unity.textmeshpro@4.0")]
|
||||
public partial class TextMeshPro : TMP_Text, ILayoutElement
|
||||
{
|
||||
// Public Properties and Serializable Properties
|
||||
|
||||
[SerializeField] internal int _SortingLayer;
|
||||
|
||||
/// <summary>
|
||||
/// Sets the Renderer's sorting Layer ID
|
||||
/// </summary>
|
||||
public int sortingLayerID
|
||||
{
|
||||
get
|
||||
{
|
||||
if (renderer == null)
|
||||
return 0;
|
||||
|
||||
return m_renderer.sortingLayerID;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (renderer == null)
|
||||
return;
|
||||
|
||||
m_renderer.sortingLayerID = value;
|
||||
_SortingLayerID = value;
|
||||
|
||||
// Make sure sorting layer ID change is also reflected on sub text objects.
|
||||
UpdateSubMeshSortingLayerID(value);
|
||||
}
|
||||
}
|
||||
[SerializeField]
|
||||
internal int _SortingLayerID;
|
||||
|
||||
/// <summary>
|
||||
/// Sets the Renderer's sorting order within the assigned layer.
|
||||
/// </summary>
|
||||
public int sortingOrder
|
||||
{
|
||||
get
|
||||
{
|
||||
if (renderer == null)
|
||||
return 0;
|
||||
|
||||
return m_renderer.sortingOrder;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (renderer == null)
|
||||
return;
|
||||
|
||||
m_renderer.sortingOrder = value;
|
||||
_SortingOrder = value;
|
||||
|
||||
// Make sure sorting order change is also reflected on sub text objects.
|
||||
UpdateSubMeshSortingOrder(value);
|
||||
}
|
||||
}
|
||||
[SerializeField]
|
||||
internal int _SortingOrder;
|
||||
|
||||
/// <summary>
|
||||
/// Determines if the size of the text container will be adjusted to fit the text object when it is first created.
|
||||
/// </summary>
|
||||
public override bool autoSizeTextContainer
|
||||
{
|
||||
get { return m_autoSizeTextContainer; }
|
||||
|
||||
set { if (m_autoSizeTextContainer == value) return; m_autoSizeTextContainer = value; if (m_autoSizeTextContainer) { TMP_UpdateManager.RegisterTextElementForLayoutRebuild(this); SetLayoutDirty(); } }
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Returns a reference to the Transform
|
||||
/// </summary>
|
||||
public new Transform transform
|
||||
{
|
||||
get
|
||||
{
|
||||
if (m_transform == null)
|
||||
m_transform = GetComponent<Transform>();
|
||||
|
||||
return m_transform;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#pragma warning disable 0108
|
||||
/// <summary>
|
||||
/// Returns the rendered assigned to the text object.
|
||||
/// </summary>
|
||||
public Renderer renderer
|
||||
{
|
||||
get
|
||||
{
|
||||
if (m_renderer == null)
|
||||
m_renderer = GetComponent<Renderer>();
|
||||
|
||||
return m_renderer;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Returns the mesh assigned to the text object.
|
||||
/// </summary>
|
||||
public override Mesh mesh
|
||||
{
|
||||
get
|
||||
{
|
||||
if (m_mesh == null)
|
||||
{
|
||||
m_mesh = new Mesh();
|
||||
m_mesh.hideFlags = HideFlags.HideAndDontSave;
|
||||
}
|
||||
|
||||
return m_mesh;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the Mesh Filter of the text 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;
|
||||
}
|
||||
}
|
||||
|
||||
// MASKING RELATED PROPERTIES
|
||||
/// <summary>
|
||||
/// Sets the mask type
|
||||
/// </summary>
|
||||
public MaskingTypes maskType
|
||||
{
|
||||
get { return m_maskType; }
|
||||
set { m_maskType = value; SetMask(m_maskType); }
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function used to set the mask type and coordinates in World Space
|
||||
/// </summary>
|
||||
/// <param name="type"></param>
|
||||
/// <param name="maskCoords"></param>
|
||||
public void SetMask(MaskingTypes type, Vector4 maskCoords)
|
||||
{
|
||||
SetMask(type);
|
||||
|
||||
SetMaskCoordinates(maskCoords);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Function used to set the mask type, coordinates and softness
|
||||
/// </summary>
|
||||
/// <param name="type"></param>
|
||||
/// <param name="maskCoords"></param>
|
||||
/// <param name="softnessX"></param>
|
||||
/// <param name="softnessY"></param>
|
||||
public void SetMask(MaskingTypes type, Vector4 maskCoords, float softnessX, float softnessY)
|
||||
{
|
||||
SetMask(type);
|
||||
|
||||
SetMaskCoordinates(maskCoords, softnessX, softnessY);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Schedule rebuilding of the text geometry.
|
||||
/// </summary>
|
||||
public override void SetVerticesDirty()
|
||||
{
|
||||
//Debug.Log("***** SetVerticesDirty() called on object [" + this.name + "] at frame [" + Time.frameCount + "] *****");
|
||||
|
||||
if (this == null || !this.IsActive())
|
||||
return;
|
||||
|
||||
TMP_UpdateManager.RegisterTextElementForGraphicRebuild(this);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public override void SetLayoutDirty()
|
||||
{
|
||||
m_isPreferredWidthDirty = true;
|
||||
m_isPreferredHeightDirty = true;
|
||||
|
||||
if (this == null || !this.IsActive())
|
||||
return;
|
||||
|
||||
LayoutRebuilder.MarkLayoutForRebuild(this.rectTransform);
|
||||
|
||||
m_isLayoutDirty = true;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Schedule updating of the material used by the text object.
|
||||
/// </summary>
|
||||
public override void SetMaterialDirty()
|
||||
{
|
||||
//Debug.Log("SetMaterialDirty()");
|
||||
|
||||
//if (!this.IsActive())
|
||||
// return;
|
||||
|
||||
//m_isMaterialDirty = true;
|
||||
UpdateMaterial();
|
||||
//TMP_UpdateManager.RegisterTextElementForGraphicRebuild(this);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public override void SetAllDirty()
|
||||
{
|
||||
SetLayoutDirty();
|
||||
SetVerticesDirty();
|
||||
SetMaterialDirty();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="update"></param>
|
||||
public override void Rebuild(CanvasUpdate update)
|
||||
{
|
||||
if (this == null) return;
|
||||
|
||||
if (update == CanvasUpdate.Prelayout)
|
||||
{
|
||||
if (m_autoSizeTextContainer)
|
||||
{
|
||||
m_rectTransform.sizeDelta = GetPreferredValues(Mathf.Infinity, Mathf.Infinity);
|
||||
}
|
||||
}
|
||||
else if (update == CanvasUpdate.PreRender)
|
||||
{
|
||||
this.OnPreRenderObject();
|
||||
|
||||
if (!m_isMaterialDirty) return;
|
||||
|
||||
UpdateMaterial();
|
||||
m_isMaterialDirty = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
protected override void UpdateMaterial()
|
||||
{
|
||||
//Debug.Log("***** UpdateMaterial() called on object ID " + GetInstanceID() + ". *****");
|
||||
|
||||
//if (!this.IsActive())
|
||||
// return;
|
||||
|
||||
if (renderer == null || m_sharedMaterial == null)
|
||||
return;
|
||||
|
||||
// Only update the material if it has changed.
|
||||
if (m_renderer.sharedMaterial == null || m_renderer.sharedMaterial.GetInstanceID() != m_sharedMaterial.GetInstanceID())
|
||||
m_renderer.sharedMaterial = m_sharedMaterial;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function to be used to force recomputing of character padding when Shader / Material properties have been changed via script.
|
||||
/// </summary>
|
||||
public override void UpdateMeshPadding()
|
||||
{
|
||||
m_padding = ShaderUtilities.GetPadding(m_sharedMaterial, m_enableExtraPadding, m_isUsingBold);
|
||||
m_isMaskingEnabled = ShaderUtilities.IsMaskingEnabled(m_sharedMaterial);
|
||||
m_havePropertiesChanged = true;
|
||||
checkPaddingRequired = false;
|
||||
|
||||
// Return if text object is not awake yet.
|
||||
if (m_textInfo == null) return;
|
||||
|
||||
// Update sub text objects
|
||||
for (int i = 1; i < m_textInfo.materialCount; i++)
|
||||
m_subTextObjects[i].UpdateMeshPadding(m_enableExtraPadding, m_isUsingBold);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function to force regeneration of the text object before its normal process time. This is useful when changes to the text object properties need to be applied immediately.
|
||||
/// </summary>
|
||||
/// <param name="ignoreActiveState">Ignore Active State of text objects. Inactive objects are ignored by default.</param>
|
||||
/// <param name="forceTextReparsing">Force re-parsing of the text.</param>
|
||||
public override void ForceMeshUpdate(bool ignoreActiveState = false, bool forceTextReparsing = false)
|
||||
{
|
||||
m_havePropertiesChanged = true;
|
||||
m_ignoreActiveState = ignoreActiveState;
|
||||
OnPreRenderObject();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function used to evaluate the length of a text string.
|
||||
/// </summary>
|
||||
/// <param name="text"></param>
|
||||
/// <returns></returns>
|
||||
public override TMP_TextInfo GetTextInfo(string text)
|
||||
{
|
||||
SetText(text);
|
||||
SetArraySizes(m_TextProcessingArray);
|
||||
|
||||
m_renderMode = TextRenderFlags.DontRender;
|
||||
|
||||
ComputeMarginSize();
|
||||
|
||||
GenerateTextMesh();
|
||||
|
||||
m_renderMode = TextRenderFlags.Render;
|
||||
|
||||
return this.textInfo;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function to clear the geometry of the Primary and Sub Text objects.
|
||||
/// </summary>
|
||||
public override void ClearMesh(bool updateMesh)
|
||||
{
|
||||
if (m_textInfo.meshInfo[0].mesh == null) m_textInfo.meshInfo[0].mesh = m_mesh;
|
||||
|
||||
m_textInfo.ClearMeshInfo(updateMesh);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Event to allow users to modify the content of the text info before the text is rendered.
|
||||
/// </summary>
|
||||
public override event Action<TMP_TextInfo> OnPreRenderText;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function to update the geometry of the main and sub text objects.
|
||||
/// </summary>
|
||||
/// <param name="mesh"></param>
|
||||
/// <param name="index"></param>
|
||||
public override void UpdateGeometry(Mesh mesh, int index)
|
||||
{
|
||||
mesh.RecalculateBounds();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function to upload the updated vertex data and renderer.
|
||||
/// </summary>
|
||||
public override void UpdateVertexData(TMP_VertexDataUpdateFlags flags)
|
||||
{
|
||||
int materialCount = m_textInfo.materialCount;
|
||||
|
||||
for (int i = 0; i < materialCount; i++)
|
||||
{
|
||||
Mesh mesh;
|
||||
|
||||
if (i == 0)
|
||||
mesh = m_mesh;
|
||||
else
|
||||
{
|
||||
// Clear unused vertices
|
||||
// TODO: Causes issues when sorting geometry as last vertex data attribute get wiped out.
|
||||
//m_textInfo.meshInfo[i].ClearUnusedVertices();
|
||||
|
||||
mesh = m_subTextObjects[i].mesh;
|
||||
}
|
||||
|
||||
//mesh.MarkDynamic();
|
||||
|
||||
if ((flags & TMP_VertexDataUpdateFlags.Vertices) == TMP_VertexDataUpdateFlags.Vertices)
|
||||
mesh.vertices = m_textInfo.meshInfo[i].vertices;
|
||||
|
||||
if ((flags & TMP_VertexDataUpdateFlags.Uv0) == TMP_VertexDataUpdateFlags.Uv0)
|
||||
mesh.SetUVs(0, m_textInfo.meshInfo[i].uvs0);
|
||||
|
||||
if ((flags & TMP_VertexDataUpdateFlags.Uv2) == TMP_VertexDataUpdateFlags.Uv2)
|
||||
mesh.uv2 = m_textInfo.meshInfo[i].uvs2;
|
||||
|
||||
//if ((flags & TMP_VertexDataUpdateFlags.Uv4) == TMP_VertexDataUpdateFlags.Uv4)
|
||||
// mesh.uv4 = m_textInfo.meshInfo[i].uvs4;
|
||||
|
||||
if ((flags & TMP_VertexDataUpdateFlags.Colors32) == TMP_VertexDataUpdateFlags.Colors32)
|
||||
mesh.colors32 = m_textInfo.meshInfo[i].colors32;
|
||||
|
||||
mesh.RecalculateBounds();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function to upload the updated vertex data and renderer.
|
||||
/// </summary>
|
||||
public override void UpdateVertexData()
|
||||
{
|
||||
int materialCount = m_textInfo.materialCount;
|
||||
|
||||
for (int i = 0; i < materialCount; i++)
|
||||
{
|
||||
Mesh mesh;
|
||||
|
||||
if (i == 0)
|
||||
mesh = m_mesh;
|
||||
else
|
||||
{
|
||||
// Clear unused vertices
|
||||
m_textInfo.meshInfo[i].ClearUnusedVertices();
|
||||
|
||||
mesh = m_subTextObjects[i].mesh;
|
||||
}
|
||||
|
||||
|
||||
//mesh.MarkDynamic();
|
||||
mesh.vertices = m_textInfo.meshInfo[i].vertices;
|
||||
mesh.SetUVs(0, m_textInfo.meshInfo[i].uvs0);
|
||||
mesh.uv2 = m_textInfo.meshInfo[i].uvs2;
|
||||
//mesh.uv4 = m_textInfo.meshInfo[i].uvs4;
|
||||
mesh.colors32 = m_textInfo.meshInfo[i].colors32;
|
||||
|
||||
mesh.RecalculateBounds();
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateFontAsset()
|
||||
{
|
||||
LoadFontAsset();
|
||||
}
|
||||
|
||||
|
||||
private bool m_currentAutoSizeMode;
|
||||
|
||||
|
||||
public void CalculateLayoutInputHorizontal() { }
|
||||
|
||||
public void CalculateLayoutInputVertical() { }
|
||||
}
|
||||
}
|
39
Assets/TextMesh Pro/Scripts/Runtime/TextMeshPro.cs.meta
Normal file
39
Assets/TextMesh Pro/Scripts/Runtime/TextMeshPro.cs.meta
Normal file
@@ -0,0 +1,39 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 35fd352f36a42a74e9f2d44b7fc67bdf
|
||||
labels:
|
||||
- Text
|
||||
- TextMesh
|
||||
- Mesh
|
||||
- Glow
|
||||
- Shadow
|
||||
- Outline
|
||||
- Bevel
|
||||
- Pro
|
||||
- TextMeshPro
|
||||
- Kerning
|
||||
- Distance
|
||||
- Field
|
||||
- Signed
|
||||
- Font
|
||||
- Atlas
|
||||
- Creator
|
||||
- Advanced
|
||||
- Rendering
|
||||
- TrueType
|
||||
- Dynamic
|
||||
- Layout
|
||||
- Style
|
||||
- Styles
|
||||
- Fonts
|
||||
- SDF
|
||||
- Scene
|
||||
- GUI
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: -105
|
||||
icon: {fileID: 2800000, guid: 2fd6421f253b4ef1a19526541f9ffc0c, type: 3}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
710
Assets/TextMesh Pro/Scripts/Runtime/TextMeshProUGUI.cs
Normal file
710
Assets/TextMesh Pro/Scripts/Runtime/TextMeshProUGUI.cs
Normal file
@@ -0,0 +1,710 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Rendering;
|
||||
using UnityEngine.UI;
|
||||
|
||||
#pragma warning disable 0414 // Disabled a few warnings related to serialized variables not used in this script but used in the editor.
|
||||
|
||||
|
||||
namespace TMPro
|
||||
{
|
||||
[DisallowMultipleComponent]
|
||||
[RequireComponent(typeof(RectTransform))]
|
||||
[RequireComponent(typeof(CanvasRenderer))]
|
||||
[AddComponentMenu("UI/TextMeshPro - Text (UI)", 11)]
|
||||
[ExecuteAlways]
|
||||
[HelpURL("https://docs.unity3d.com/Packages/com.unity.textmeshpro@4.0")]
|
||||
public partial class TextMeshProUGUI : TMP_Text, ILayoutElement
|
||||
{
|
||||
/// <summary>
|
||||
/// Get the material that will be used for rendering.
|
||||
/// </summary>
|
||||
public override Material materialForRendering
|
||||
{
|
||||
get { return TMP_MaterialManager.GetMaterialForRendering(this, m_sharedMaterial); }
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Determines if the size of the text container will be adjusted to fit the text object when it is first created.
|
||||
/// </summary>
|
||||
public override bool autoSizeTextContainer
|
||||
{
|
||||
get { return m_autoSizeTextContainer; }
|
||||
|
||||
set { if (m_autoSizeTextContainer == value) return; m_autoSizeTextContainer = value; if (m_autoSizeTextContainer) { CanvasUpdateRegistry.RegisterCanvasElementForLayoutRebuild(this); SetLayoutDirty(); } }
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Reference to the Mesh used by the text object.
|
||||
/// </summary>
|
||||
public override Mesh mesh
|
||||
{
|
||||
get { return m_mesh; }
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Reference to the CanvasRenderer used by the text object.
|
||||
/// </summary>
|
||||
public new CanvasRenderer canvasRenderer
|
||||
{
|
||||
get
|
||||
{
|
||||
if (m_canvasRenderer == null) m_canvasRenderer = GetComponent<CanvasRenderer>();
|
||||
|
||||
return m_canvasRenderer;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Anchor dampening prevents the anchor position from being adjusted unless the positional change exceeds about 40% of the width of the underline character. This essentially stabilizes the anchor position.
|
||||
/// </summary>
|
||||
//public bool anchorDampening
|
||||
//{
|
||||
// get { return m_anchorDampening; }
|
||||
// set { if (m_anchorDampening != value) { havePropertiesChanged = true; m_anchorDampening = value; /* ScheduleUpdate(); */ } }
|
||||
//}
|
||||
|
||||
#if !UNITY_2019_3_OR_NEWER
|
||||
[SerializeField]
|
||||
private bool m_Maskable = true;
|
||||
#endif
|
||||
|
||||
private bool m_isRebuildingLayout = false;
|
||||
private Coroutine m_DelayedGraphicRebuild;
|
||||
private Coroutine m_DelayedMaterialRebuild;
|
||||
|
||||
/// <summary>
|
||||
/// Function called by Unity when the horizontal layout needs to be recalculated.
|
||||
/// </summary>
|
||||
public void CalculateLayoutInputHorizontal()
|
||||
{
|
||||
//Debug.Log("*** CalculateLayoutHorizontal() on Object ID: " + GetInstanceID() + " at frame: " + Time.frameCount + "***");
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function called by Unity when the vertical layout needs to be recalculated.
|
||||
/// </summary>
|
||||
public void CalculateLayoutInputVertical()
|
||||
{
|
||||
//Debug.Log("*** CalculateLayoutInputVertical() on Object ID: " + GetInstanceID() + " at frame: " + Time.frameCount + "***");
|
||||
}
|
||||
|
||||
|
||||
public override void SetVerticesDirty()
|
||||
{
|
||||
if (this == null || !this.IsActive())
|
||||
return;
|
||||
|
||||
if (CanvasUpdateRegistry.IsRebuildingGraphics())
|
||||
return;
|
||||
|
||||
CanvasUpdateRegistry.RegisterCanvasElementForGraphicRebuild(this);
|
||||
|
||||
if (m_OnDirtyVertsCallback != null)
|
||||
m_OnDirtyVertsCallback();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public override void SetLayoutDirty()
|
||||
{
|
||||
m_isPreferredWidthDirty = true;
|
||||
m_isPreferredHeightDirty = true;
|
||||
|
||||
if (this == null || !this.IsActive())
|
||||
return;
|
||||
|
||||
LayoutRebuilder.MarkLayoutForRebuild(this.rectTransform);
|
||||
|
||||
m_isLayoutDirty = true;
|
||||
|
||||
if (m_OnDirtyLayoutCallback != null)
|
||||
m_OnDirtyLayoutCallback();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public override void SetMaterialDirty()
|
||||
{
|
||||
if (this == null || !this.IsActive())
|
||||
return;
|
||||
|
||||
if (CanvasUpdateRegistry.IsRebuildingGraphics())
|
||||
return;
|
||||
|
||||
m_isMaterialDirty = true;
|
||||
CanvasUpdateRegistry.RegisterCanvasElementForGraphicRebuild(this);
|
||||
|
||||
if (m_OnDirtyMaterialCallback != null)
|
||||
m_OnDirtyMaterialCallback();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public override void SetAllDirty()
|
||||
{
|
||||
SetLayoutDirty();
|
||||
SetVerticesDirty();
|
||||
SetMaterialDirty();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Delay registration of text object for graphic rebuild by one frame.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
IEnumerator DelayedGraphicRebuild()
|
||||
{
|
||||
yield return null;
|
||||
|
||||
CanvasUpdateRegistry.RegisterCanvasElementForGraphicRebuild(this);
|
||||
|
||||
if (m_OnDirtyVertsCallback != null)
|
||||
m_OnDirtyVertsCallback();
|
||||
|
||||
m_DelayedGraphicRebuild = null;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Delay registration of text object for graphic rebuild by one frame.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
IEnumerator DelayedMaterialRebuild()
|
||||
{
|
||||
yield return null;
|
||||
|
||||
m_isMaterialDirty = true;
|
||||
CanvasUpdateRegistry.RegisterCanvasElementForGraphicRebuild(this);
|
||||
|
||||
if (m_OnDirtyMaterialCallback != null)
|
||||
m_OnDirtyMaterialCallback();
|
||||
|
||||
m_DelayedMaterialRebuild = null;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="update"></param>
|
||||
public override void Rebuild(CanvasUpdate update)
|
||||
{
|
||||
if (this == null) return;
|
||||
|
||||
if (update == CanvasUpdate.Prelayout)
|
||||
{
|
||||
if (m_autoSizeTextContainer)
|
||||
{
|
||||
m_rectTransform.sizeDelta = GetPreferredValues(Mathf.Infinity, Mathf.Infinity);
|
||||
}
|
||||
}
|
||||
else if (update == CanvasUpdate.PreRender)
|
||||
{
|
||||
OnPreRenderCanvas();
|
||||
|
||||
if (!m_isMaterialDirty) return;
|
||||
|
||||
UpdateMaterial();
|
||||
m_isMaterialDirty = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Method to keep the pivot of the sub text objects in sync with the parent pivot.
|
||||
/// </summary>
|
||||
private void UpdateSubObjectPivot()
|
||||
{
|
||||
if (m_textInfo == null) return;
|
||||
|
||||
for (int i = 1; i < m_subTextObjects.Length && m_subTextObjects[i] != null; i++)
|
||||
{
|
||||
m_subTextObjects[i].SetPivotDirty();
|
||||
}
|
||||
//m_isPivotDirty = false;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </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>
|
||||
///
|
||||
/// </summary>
|
||||
protected override void UpdateMaterial()
|
||||
{
|
||||
//Debug.Log("*** UpdateMaterial() ***");
|
||||
|
||||
//if (!this.IsActive())
|
||||
// return;
|
||||
|
||||
if (m_sharedMaterial == null || canvasRenderer == null) return;
|
||||
|
||||
m_canvasRenderer.materialCount = 1;
|
||||
m_canvasRenderer.SetMaterial(materialForRendering, 0);
|
||||
//m_canvasRenderer.SetTexture(materialForRendering.mainTexture);
|
||||
}
|
||||
|
||||
|
||||
//public override void OnRebuildRequested()
|
||||
//{
|
||||
// //Debug.Log("OnRebuildRequested");
|
||||
|
||||
// base.OnRebuildRequested();
|
||||
//}
|
||||
|
||||
|
||||
|
||||
//public override bool Raycast(Vector2 sp, Camera eventCamera)
|
||||
//{
|
||||
// //Debug.Log("Raycast Event. ScreenPoint: " + sp);
|
||||
// return base.Raycast(sp, eventCamera);
|
||||
//}
|
||||
|
||||
|
||||
// MASKING RELATED PROPERTIES
|
||||
/// <summary>
|
||||
/// Sets the masking offset from the bounds of the object
|
||||
/// </summary>
|
||||
public Vector4 maskOffset
|
||||
{
|
||||
get { return m_maskOffset; }
|
||||
set { m_maskOffset = value; UpdateMask(); m_havePropertiesChanged = true; }
|
||||
}
|
||||
|
||||
|
||||
//public override Material defaultMaterial
|
||||
//{
|
||||
// get { Debug.Log("Default Material called."); return m_sharedMaterial; }
|
||||
//}
|
||||
|
||||
|
||||
|
||||
//protected override void OnCanvasHierarchyChanged()
|
||||
//{
|
||||
// //Debug.Log("OnCanvasHierarchyChanged...");
|
||||
//}
|
||||
|
||||
|
||||
// IClippable implementation
|
||||
/// <summary>
|
||||
/// Method called when the state of a parent changes.
|
||||
/// </summary>
|
||||
public override void RecalculateClipping()
|
||||
{
|
||||
//Debug.Log("***** RecalculateClipping() *****");
|
||||
|
||||
base.RecalculateClipping();
|
||||
}
|
||||
|
||||
|
||||
// IMaskable Implementation
|
||||
/// <summary>
|
||||
/// Method called when Stencil Mask needs to be updated on this element and parents.
|
||||
/// </summary>
|
||||
// public override void RecalculateMasking()
|
||||
// {
|
||||
// //Debug.Log("***** RecalculateMasking() *****");
|
||||
//
|
||||
// this.m_ShouldRecalculateStencil = true;
|
||||
// SetMaterialDirty();
|
||||
// }
|
||||
|
||||
|
||||
//public override void SetClipRect(Rect clipRect, bool validRect)
|
||||
//{
|
||||
// //Debug.Log("***** SetClipRect (" + clipRect + ", " + validRect + ") *****");
|
||||
|
||||
// base.SetClipRect(clipRect, validRect);
|
||||
//}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Override of the Cull function to provide for the ability to override the culling of the text object.
|
||||
/// </summary>
|
||||
/// <param name="clipRect"></param>
|
||||
/// <param name="validRect"></param>
|
||||
public override void Cull(Rect clipRect, bool validRect)
|
||||
{
|
||||
m_ShouldUpdateCulling = false;
|
||||
|
||||
// Delay culling check in the event the text layout is dirty and geometry has to be updated.
|
||||
if (m_isLayoutDirty)
|
||||
{
|
||||
m_ShouldUpdateCulling = true;
|
||||
m_ClipRect = clipRect;
|
||||
m_ValidRect = validRect;
|
||||
return;
|
||||
}
|
||||
|
||||
// Get compound rect for the text object and sub text objects in local canvas space.
|
||||
Rect rect = GetCanvasSpaceClippingRect();
|
||||
|
||||
// No point culling if geometry bounds have no width or height.
|
||||
//if (rect.width == 0 || rect.height == 0)
|
||||
// return;
|
||||
|
||||
var cull = !validRect || !clipRect.Overlaps(rect, true);
|
||||
if (m_canvasRenderer.cull != cull)
|
||||
{
|
||||
m_canvasRenderer.cull = cull;
|
||||
onCullStateChanged.Invoke(cull);
|
||||
OnCullingChanged();
|
||||
|
||||
// Update any potential sub mesh objects
|
||||
for (int i = 1; i < m_subTextObjects.Length && m_subTextObjects[i] != null; i++)
|
||||
{
|
||||
m_subTextObjects[i].canvasRenderer.cull = cull;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool m_ShouldUpdateCulling;
|
||||
private Rect m_ClipRect;
|
||||
private bool m_ValidRect;
|
||||
|
||||
/// <summary>
|
||||
/// Internal function to allow delay of culling until the text geometry has been updated.
|
||||
/// </summary>
|
||||
internal override void UpdateCulling()
|
||||
{
|
||||
// Get compound rect for the text object and sub text objects in local canvas space.
|
||||
Rect rect = GetCanvasSpaceClippingRect();
|
||||
|
||||
// No point culling if geometry bounds have no width or height.
|
||||
//if (rect.width == 0 || rect.height == 0)
|
||||
// return;
|
||||
|
||||
var cull = !m_ValidRect || !m_ClipRect.Overlaps(rect, true);
|
||||
if (m_canvasRenderer.cull != cull)
|
||||
{
|
||||
m_canvasRenderer.cull = cull;
|
||||
onCullStateChanged.Invoke(cull);
|
||||
OnCullingChanged();
|
||||
|
||||
// Update any potential sub mesh objects
|
||||
for (int i = 1; i < m_subTextObjects.Length && m_subTextObjects[i] != null; i++)
|
||||
{
|
||||
m_subTextObjects[i].canvasRenderer.cull = cull;
|
||||
}
|
||||
}
|
||||
|
||||
m_ShouldUpdateCulling = false;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
/// <summary>
|
||||
/// Sets the mask type
|
||||
/// </summary>
|
||||
public MaskingTypes mask
|
||||
{
|
||||
get { return m_mask; }
|
||||
set { m_mask = value; havePropertiesChanged = true; isMaskUpdateRequired = true; }
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Set the masking offset mode (as percentage or pixels)
|
||||
/// </summary>
|
||||
public MaskingOffsetMode maskOffsetMode
|
||||
{
|
||||
get { return m_maskOffsetMode; }
|
||||
set { m_maskOffsetMode = value; havePropertiesChanged = true; isMaskUpdateRequired = true; }
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
/// <summary>
|
||||
/// Sets the softness of the mask
|
||||
/// </summary>
|
||||
public Vector2 maskSoftness
|
||||
{
|
||||
get { return m_maskSoftness; }
|
||||
set { m_maskSoftness = value; havePropertiesChanged = true; isMaskUpdateRequired = true; }
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Allows to move / offset the mesh vertices by a set amount
|
||||
/// </summary>
|
||||
public Vector2 vertexOffset
|
||||
{
|
||||
get { return m_vertexOffset; }
|
||||
set { m_vertexOffset = value; havePropertiesChanged = true; isMaskUpdateRequired = true; }
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function to be used to force recomputing of character padding when Shader / Material properties have been changed via script.
|
||||
/// </summary>
|
||||
public override void UpdateMeshPadding()
|
||||
{
|
||||
m_padding = ShaderUtilities.GetPadding(m_sharedMaterial, m_enableExtraPadding, m_isUsingBold);
|
||||
m_isMaskingEnabled = ShaderUtilities.IsMaskingEnabled(m_sharedMaterial);
|
||||
m_havePropertiesChanged = true;
|
||||
checkPaddingRequired = false;
|
||||
|
||||
// Return if text object is not awake yet.
|
||||
if (m_textInfo == null) return;
|
||||
|
||||
// Update sub text objects
|
||||
for (int i = 1; i < m_textInfo.materialCount; i++)
|
||||
m_subTextObjects[i].UpdateMeshPadding(m_enableExtraPadding, m_isUsingBold);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Tweens the CanvasRenderer color associated with this Graphic.
|
||||
/// </summary>
|
||||
/// <param name="targetColor">Target color.</param>
|
||||
/// <param name="duration">Tween duration.</param>
|
||||
/// <param name="ignoreTimeScale">Should ignore Time.scale?</param>
|
||||
/// <param name="useAlpha">Should also Tween the alpha channel?</param>
|
||||
protected override void InternalCrossFadeColor(Color targetColor, float duration, bool ignoreTimeScale, bool useAlpha)
|
||||
{
|
||||
if (m_textInfo == null)
|
||||
return;
|
||||
|
||||
int materialCount = m_textInfo.materialCount;
|
||||
|
||||
for (int i = 1; i < materialCount; i++)
|
||||
{
|
||||
m_subTextObjects[i].CrossFadeColor(targetColor, duration, ignoreTimeScale, useAlpha);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Tweens the alpha of the CanvasRenderer color associated with this Graphic.
|
||||
/// </summary>
|
||||
/// <param name="alpha">Target alpha.</param>
|
||||
/// <param name="duration">Duration of the tween in seconds.</param>
|
||||
/// <param name="ignoreTimeScale">Should ignore Time.scale?</param>
|
||||
protected override void InternalCrossFadeAlpha(float alpha, float duration, bool ignoreTimeScale)
|
||||
{
|
||||
if (m_textInfo == null)
|
||||
return;
|
||||
|
||||
int materialCount = m_textInfo.materialCount;
|
||||
|
||||
for (int i = 1; i < materialCount; i++)
|
||||
{
|
||||
m_subTextObjects[i].CrossFadeAlpha(alpha, duration, ignoreTimeScale);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function to force regeneration of the text object before its normal process time. This is useful when changes to the text object properties need to be applied immediately.
|
||||
/// </summary>
|
||||
/// <param name="ignoreActiveState">Ignore Active State of text objects. Inactive objects are ignored by default.</param>
|
||||
/// <param name="forceTextReparsing">Force re-parsing of the text.</param>
|
||||
public override void ForceMeshUpdate(bool ignoreActiveState = false, bool forceTextReparsing = false)
|
||||
{
|
||||
m_havePropertiesChanged = true;
|
||||
m_ignoreActiveState = ignoreActiveState;
|
||||
|
||||
// Special handling in the event the Canvas is only disabled
|
||||
if (m_canvas == null)
|
||||
m_canvas = GetComponentInParent<Canvas>();
|
||||
|
||||
OnPreRenderCanvas();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function used to evaluate the length of a text string.
|
||||
/// </summary>
|
||||
/// <param name="text"></param>
|
||||
/// <returns></returns>
|
||||
public override TMP_TextInfo GetTextInfo(string text)
|
||||
{
|
||||
SetText(text);
|
||||
SetArraySizes(m_TextProcessingArray);
|
||||
|
||||
m_renderMode = TextRenderFlags.DontRender;
|
||||
|
||||
ComputeMarginSize();
|
||||
|
||||
// Need to make sure we have a valid reference to a Canvas.
|
||||
if (m_canvas == null) m_canvas = this.canvas;
|
||||
|
||||
GenerateTextMesh();
|
||||
|
||||
m_renderMode = TextRenderFlags.Render;
|
||||
|
||||
return this.textInfo;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function to clear the geometry of the Primary and Sub Text objects.
|
||||
/// </summary>
|
||||
public override void ClearMesh()
|
||||
{
|
||||
m_canvasRenderer.SetMesh(null);
|
||||
|
||||
for (int i = 1; i < m_subTextObjects.Length && m_subTextObjects[i] != null; i++)
|
||||
m_subTextObjects[i].canvasRenderer.SetMesh(null);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Event to allow users to modify the content of the text info before the text is rendered.
|
||||
/// </summary>
|
||||
public override event Action<TMP_TextInfo> OnPreRenderText;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function to update the geometry of the main and sub text objects.
|
||||
/// </summary>
|
||||
/// <param name="mesh"></param>
|
||||
/// <param name="index"></param>
|
||||
public override void UpdateGeometry(Mesh mesh, int index)
|
||||
{
|
||||
mesh.RecalculateBounds();
|
||||
|
||||
if (index == 0)
|
||||
{
|
||||
m_canvasRenderer.SetMesh(mesh);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_subTextObjects[index].canvasRenderer.SetMesh(mesh);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function to upload the updated vertex data and renderer.
|
||||
/// </summary>
|
||||
public override void UpdateVertexData(TMP_VertexDataUpdateFlags flags)
|
||||
{
|
||||
int materialCount = m_textInfo.materialCount;
|
||||
|
||||
for (int i = 0; i < materialCount; i++)
|
||||
{
|
||||
Mesh mesh;
|
||||
|
||||
if (i == 0)
|
||||
mesh = m_mesh;
|
||||
else
|
||||
{
|
||||
// Clear unused vertices
|
||||
// TODO: Causes issues when sorting geometry as last vertex data attribute get wiped out.
|
||||
//m_textInfo.meshInfo[i].ClearUnusedVertices();
|
||||
|
||||
mesh = m_subTextObjects[i].mesh;
|
||||
}
|
||||
|
||||
if ((flags & TMP_VertexDataUpdateFlags.Vertices) == TMP_VertexDataUpdateFlags.Vertices)
|
||||
mesh.vertices = m_textInfo.meshInfo[i].vertices;
|
||||
|
||||
if ((flags & TMP_VertexDataUpdateFlags.Uv0) == TMP_VertexDataUpdateFlags.Uv0)
|
||||
mesh.SetUVs(0, m_textInfo.meshInfo[i].uvs0);
|
||||
|
||||
if ((flags & TMP_VertexDataUpdateFlags.Uv2) == TMP_VertexDataUpdateFlags.Uv2)
|
||||
mesh.uv2 = m_textInfo.meshInfo[i].uvs2;
|
||||
|
||||
//if ((flags & TMP_VertexDataUpdateFlags.Uv4) == TMP_VertexDataUpdateFlags.Uv4)
|
||||
// mesh.uv4 = m_textInfo.meshInfo[i].uvs4;
|
||||
|
||||
if ((flags & TMP_VertexDataUpdateFlags.Colors32) == TMP_VertexDataUpdateFlags.Colors32)
|
||||
mesh.colors32 = m_textInfo.meshInfo[i].colors32;
|
||||
|
||||
mesh.RecalculateBounds();
|
||||
|
||||
if (i == 0)
|
||||
m_canvasRenderer.SetMesh(mesh);
|
||||
else
|
||||
m_subTextObjects[i].canvasRenderer.SetMesh(mesh);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function to upload the updated vertex data and renderer.
|
||||
/// </summary>
|
||||
public override void UpdateVertexData()
|
||||
{
|
||||
int materialCount = m_textInfo.materialCount;
|
||||
|
||||
for (int i = 0; i < materialCount; i++)
|
||||
{
|
||||
Mesh mesh;
|
||||
|
||||
if (i == 0)
|
||||
mesh = m_mesh;
|
||||
else
|
||||
{
|
||||
// Clear unused vertices
|
||||
m_textInfo.meshInfo[i].ClearUnusedVertices();
|
||||
|
||||
mesh = m_subTextObjects[i].mesh;
|
||||
}
|
||||
|
||||
//mesh.MarkDynamic();
|
||||
mesh.vertices = m_textInfo.meshInfo[i].vertices;
|
||||
mesh.SetUVs(0, m_textInfo.meshInfo[i].uvs0);
|
||||
mesh.uv2 = m_textInfo.meshInfo[i].uvs2;
|
||||
//mesh.uv4 = m_textInfo.meshInfo[i].uvs4;
|
||||
mesh.colors32 = m_textInfo.meshInfo[i].colors32;
|
||||
|
||||
mesh.RecalculateBounds();
|
||||
|
||||
if (i == 0)
|
||||
m_canvasRenderer.SetMesh(mesh);
|
||||
else
|
||||
m_subTextObjects[i].canvasRenderer.SetMesh(mesh);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void UpdateFontAsset()
|
||||
{
|
||||
LoadFontAsset();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
11
Assets/TextMesh Pro/Scripts/Runtime/TextMeshProUGUI.cs.meta
Normal file
11
Assets/TextMesh Pro/Scripts/Runtime/TextMeshProUGUI.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 83e7715acbfae1d4b84414c13d03ed3f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: -100
|
||||
icon: {fileID: 2800000, guid: 2fd6421f253b4ef1a19526541f9ffc0c, type: 3}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
14
Assets/TextMesh Pro/Scripts/Runtime/Unity.TextMeshPro.asmdef
Normal file
14
Assets/TextMesh Pro/Scripts/Runtime/Unity.TextMeshPro.asmdef
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"name": "Unity.TextMeshPro",
|
||||
"rootNamespace": "",
|
||||
"references": [],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": true,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": true,
|
||||
"defineConstraints": [],
|
||||
"versionDefines": [],
|
||||
"noEngineReferences": false
|
||||
}
|
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: da293eebbcb9a4947a212534c52d1a32
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Reference in New Issue
Block a user