Reimport upgraded TextMesh Pro, modified.

This commit is contained in:
2023-02-01 22:14:43 +08:00
parent 623c53f79a
commit bd256ba1a6
293 changed files with 98622 additions and 345 deletions

View 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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: cc4155a9f4c4a61478dced5053f1bd07
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View 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);
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 04973cf92f7eb984989cc757a35ce78c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View 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;
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 3fd0378c8b128984483147606e14726e
timeCreated: 1449743129
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View 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;
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 78117be65f9ab544a9a373a26f4148f0
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View 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;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 2c9cc00f0e8000543a1ed26c2a0f1f0b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View 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;
}
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 38133bafd4674d242835faca6f9f864f
timeCreated: 1464850953
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View 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;
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 094d5dbc4aa34bc40baa80a884b5ff3c
timeCreated: 1446378357
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

View 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:

View File

@@ -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;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: aaf9006568d76504f982305b517fb490
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View 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;
}
}
}

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 7c5c60f80f1a9814eb7e246f2e88afd4
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View 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;
}
*/
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: a4a26a81fe2bc7b42ba0c6aefa6f0cdb
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View 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;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 3d7de7dd98a0728419392bf8b2f46a37
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

View 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:

View 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);
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: d98fc3935c2bc5f41bf9090a00b3f5f2
timeCreated: 1473021069
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View 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;
//}
}
}

View 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:

View 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);
}
}
}

View 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:

View 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
}
}

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 6e915af4d2ed15047b3dcf4644ef8ce4
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View 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;
//}
}
}

View 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:

View 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);
}
}
}

View 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:

View File

@@ -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

View File

@@ -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:

View 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);
}
}
}
*/

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 8fee14164794a4541a738db6c9e260fa
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View 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;
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e40fb84a8412ca04783a884a187d6a48
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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;
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: b7fea85ee47630b4bb3dd0aeb85b3075
timeCreated: 1484171293
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View 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.
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: f2b6ab3702365d845916dfed0abd567b
timeCreated: 1477609203
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,537 @@
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);
}
/// <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;
}
}
}

View 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:

Some files were not shown because too many files have changed in this diff Show More