6 using System.Collections;
7 using System.Collections.Generic;
9 #pragma warning disable 0414 // Disabled a few warnings related to serialized variables not used in this script but used in the editor. 14 public partial class TextMeshPro
17 private bool m_hasFontAssetChanged =
false;
19 float m_previousLossyScaleY = -1;
22 private Renderer m_renderer;
23 private MeshFilter m_meshFilter;
25 private bool m_isFirstAllocation;
26 private int m_max_characters = 8;
27 private int m_max_numberOfLines = 4;
29 private Bounds m_default_bounds =
new Bounds(Vector3.zero,
new Vector3(1000, 1000, 0));
32 protected TMP_SubMesh[] m_subTextObjects =
new TMP_SubMesh[8];
39 private bool m_isMaskingEnabled;
40 private bool isMaskUpdateRequired;
44 private MaskingTypes m_maskType;
47 private Matrix4x4 m_EnvMapMatrix =
new Matrix4x4();
51 private Vector3[] m_RectTransformCorners =
new Vector3[4];
54 private bool m_isRegisteredForEvents;
61 private int loopCountA;
68 protected override void Awake()
74 if (TMP_Settings.instance ==
null)
76 if (m_isWaitingOnResourceLoad ==
false)
77 TMPro_EventManager.RESOURCE_LOAD_EVENT.Add(ON_RESOURCES_LOADED);
79 m_isWaitingOnResourceLoad =
true;
85 m_renderer = GetComponent<Renderer>();
86 if (m_renderer ==
null)
87 m_renderer = gameObject.AddComponent<Renderer>();
91 if (this.canvasRenderer !=
null)
92 this.canvasRenderer.hideFlags = HideFlags.HideInInspector;
95 CanvasRenderer canvasRenderer = gameObject.AddComponent<CanvasRenderer>();
96 canvasRenderer.hideFlags = HideFlags.HideInInspector;
109 m_meshFilter = GetComponent<MeshFilter>();
110 if (m_meshFilter ==
null)
111 m_meshFilter = gameObject.AddComponent<MeshFilter>();
119 m_mesh.hideFlags = HideFlags.HideAndDontSave;
121 m_meshFilter.mesh = m_mesh;
124 m_meshFilter.hideFlags = HideFlags.HideInInspector;
133 TMP_StyleSheet.LoadDefaultStyleSheet();
136 if (m_char_buffer ==
null)
137 m_char_buffer =
new int[m_max_characters];
139 m_cached_TextElement =
new TMP_Glyph();
140 m_isFirstAllocation =
true;
142 if (m_textInfo ==
null)
143 m_textInfo =
new TMP_TextInfo(
this);
146 if (m_fontAsset ==
null)
148 Debug.LogWarning(
"Please assign a Font Asset to this " +
transform.name +
" gameobject.",
this);
153 TMP_SubMesh[] subTextObjects = GetComponentsInChildren<TMP_SubMesh>();
154 if (subTextObjects.Length > 0)
156 for (
int i = 0; i < subTextObjects.Length; i++)
157 m_subTextObjects[i + 1] = subTextObjects[i];
161 m_isInputParsingRequired =
true;
162 m_havePropertiesChanged =
true;
163 m_isCalculateSizeRequired =
true;
169 protected override void OnEnable()
174 if (m_isAwake ==
false)
178 if (!m_isRegisteredForEvents)
181 TMPro_EventManager.MATERIAL_PROPERTY_EVENT.Add(ON_MATERIAL_PROPERTY_CHANGED);
182 TMPro_EventManager.FONT_PROPERTY_EVENT.Add(ON_FONT_PROPERTY_CHANGED);
183 TMPro_EventManager.TEXTMESHPRO_PROPERTY_EVENT.Add(ON_TEXTMESHPRO_PROPERTY_CHANGED);
184 TMPro_EventManager.DRAG_AND_DROP_MATERIAL_EVENT.Add(ON_DRAG_AND_DROP_MATERIAL);
185 TMPro_EventManager.TEXT_STYLE_PROPERTY_EVENT.Add(ON_TEXT_STYLE_CHANGED);
186 TMPro_EventManager.COLOR_GRADIENT_PROPERTY_EVENT.Add(ON_COLOR_GRADIENT_CHANGED);
187 TMPro_EventManager.TMP_SETTINGS_PROPERTY_EVENT.Add(ON_TMP_SETTINGS_CHANGED);
189 m_isRegisteredForEvents =
true;
198 m_isInputParsingRequired =
true;
199 m_havePropertiesChanged =
true;
200 m_verticesAlreadyDirty =
false;
205 protected override void OnDisable()
210 if (m_isAwake ==
false)
213 TMP_UpdateManager.UnRegisterTextElementForRebuild(
this);
215 m_meshFilter.sharedMesh =
null;
220 protected override void OnDestroy()
227 DestroyImmediate(m_mesh);
232 TMPro_EventManager.MATERIAL_PROPERTY_EVENT.Remove(ON_MATERIAL_PROPERTY_CHANGED);
233 TMPro_EventManager.FONT_PROPERTY_EVENT.Remove(ON_FONT_PROPERTY_CHANGED);
234 TMPro_EventManager.TEXTMESHPRO_PROPERTY_EVENT.Remove(ON_TEXTMESHPRO_PROPERTY_CHANGED);
235 TMPro_EventManager.DRAG_AND_DROP_MATERIAL_EVENT.Remove(ON_DRAG_AND_DROP_MATERIAL);
236 TMPro_EventManager.TEXT_STYLE_PROPERTY_EVENT.Remove(ON_TEXT_STYLE_CHANGED);
237 TMPro_EventManager.COLOR_GRADIENT_PROPERTY_EVENT.Remove(ON_COLOR_GRADIENT_CHANGED);
238 TMPro_EventManager.TMP_SETTINGS_PROPERTY_EVENT.Remove(ON_TMP_SETTINGS_CHANGED);
239 TMPro_EventManager.RESOURCE_LOAD_EVENT.Remove(ON_RESOURCES_LOADED);
242 m_isRegisteredForEvents =
false;
243 TMP_UpdateManager.UnRegisterTextElementForRebuild(
this);
248 protected override void Reset()
253 if (m_isAwake ==
false)
257 DestroyImmediate(m_mesh);
263 protected override void OnValidate()
268 if (m_isAwake ==
false)
274 if (m_fontAsset ==
null || m_hasFontAssetChanged)
277 m_isCalculateSizeRequired =
true;
278 m_hasFontAssetChanged =
false;
283 m_isInputParsingRequired =
true;
284 m_inputSource = TextInputSources.Text;
285 m_havePropertiesChanged =
true;
286 m_isCalculateSizeRequired =
true;
287 m_isPreferredWidthDirty =
true;
288 m_isPreferredHeightDirty =
true;
295 void ON_RESOURCES_LOADED()
297 TMPro_EventManager.RESOURCE_LOAD_EVENT.Remove(ON_RESOURCES_LOADED);
305 void ON_MATERIAL_PROPERTY_CHANGED(
bool isChanged, Material mat)
309 if (m_renderer.sharedMaterial ==
null)
311 if (m_fontAsset !=
null)
313 m_renderer.sharedMaterial = m_fontAsset.
material;
314 Debug.LogWarning(
"No Material was assigned to " + name +
". " + m_fontAsset.
material.name +
" was assigned.",
this);
317 Debug.LogWarning(
"No Font Asset assigned to " + name +
". Please assign a Font Asset.",
this);
320 if (m_fontAsset.atlas.GetInstanceID() != m_renderer.sharedMaterial.GetTexture(ShaderUtilities.ID_MainTex).GetInstanceID())
322 m_renderer.sharedMaterial = m_sharedMaterial;
324 Debug.LogWarning(
"Font Asset Atlas doesn't match the Atlas in the newly assigned material. Select a matching material or a different font asset.",
this);
327 if (m_renderer.sharedMaterial != m_sharedMaterial)
330 m_sharedMaterial = m_renderer.sharedMaterial;
337 UpdateEnvMapMatrix();
338 m_havePropertiesChanged =
true;
344 void ON_FONT_PROPERTY_CHANGED(
bool isChanged, TMP_FontAsset
font)
346 if (MaterialReference.Contains(m_materialReferences,
font))
349 m_isInputParsingRequired =
true;
350 m_havePropertiesChanged =
true;
359 void ON_TEXTMESHPRO_PROPERTY_CHANGED(
bool isChanged, TextMeshPro obj)
364 m_havePropertiesChanged =
true;
365 m_isInputParsingRequired =
true;
375 void ON_DRAG_AND_DROP_MATERIAL(GameObject obj, Material currentMaterial, Material newMaterial)
380 #if UNITY_2018_2_OR_NEWER 381 if (obj == gameObject ||
UnityEditor.PrefabUtility.GetCorrespondingObjectFromSource(gameObject) == obj)
383 if (obj == gameObject ||
UnityEditor.PrefabUtility.GetPrefabParent(gameObject) == obj)
386 UnityEditor.Undo.RecordObject(
this,
"Material Assignment");
387 UnityEditor.Undo.RecordObject(m_renderer,
"Material Assignment");
389 m_sharedMaterial = newMaterial;
392 m_havePropertiesChanged =
true;
400 void ON_TEXT_STYLE_CHANGED(
bool isChanged)
402 m_havePropertiesChanged =
true;
403 m_isInputParsingRequired =
true;
412 void ON_COLOR_GRADIENT_CHANGED(TMP_ColorGradient gradient)
414 if (m_fontColorGradientPreset !=
null && gradient.GetInstanceID() == m_fontColorGradientPreset.GetInstanceID())
416 m_havePropertiesChanged =
true;
425 void ON_TMP_SETTINGS_CHANGED()
427 m_defaultSpriteAsset =
null;
428 m_havePropertiesChanged =
true;
429 m_isInputParsingRequired =
true;
440 ShaderUtilities.GetShaderPropertyIDs();
442 if (m_fontAsset ==
null)
447 m_fontAsset = Resources.Load<
TMP_FontAsset>(
"Fonts & Materials/LiberationSans SDF");
449 if (m_fontAsset ==
null)
451 Debug.LogWarning(
"The LiberationSans SDF Font Asset was not found. There is no Font Asset assigned to " + gameObject.name +
".",
this);
455 if (m_fontAsset.characterDictionary ==
null)
457 Debug.Log(
"Dictionary is Null!");
460 m_renderer.sharedMaterial = m_fontAsset.
material;
461 m_sharedMaterial = m_fontAsset.
material;
462 m_sharedMaterial.SetFloat(
"_CullMode", 0);
463 m_sharedMaterial.SetFloat(ShaderUtilities.ShaderTag_ZTestMode, 4);
464 m_renderer.receiveShadows =
false;
465 m_renderer.shadowCastingMode =
UnityEngine.Rendering.ShadowCastingMode.Off;
470 if (m_fontAsset.characterDictionary ==
null)
479 if (m_renderer.sharedMaterial ==
null || m_renderer.sharedMaterial.GetTexture(ShaderUtilities.ID_MainTex) ==
null || m_fontAsset.atlas.GetInstanceID() != m_renderer.sharedMaterial.GetTexture(ShaderUtilities.ID_MainTex).GetInstanceID())
481 m_renderer.sharedMaterial = m_fontAsset.
material;
482 m_sharedMaterial = m_fontAsset.
material;
486 m_sharedMaterial = m_renderer.sharedMaterial;
490 m_sharedMaterial.SetFloat(ShaderUtilities.ShaderTag_ZTestMode, 4);
493 if (m_sharedMaterial.passCount == 1)
495 m_renderer.receiveShadows =
false;
496 m_renderer.shadowCastingMode =
UnityEngine.Rendering.ShadowCastingMode.Off;
503 m_isMaskingEnabled = ShaderUtilities.IsMaskingEnabled(m_sharedMaterial);
517 void UpdateEnvMapMatrix()
519 if (!m_sharedMaterial.HasProperty(ShaderUtilities.ID_EnvMap) || m_sharedMaterial.GetTexture(ShaderUtilities.ID_EnvMap) ==
null)
523 Vector3 rotation = m_sharedMaterial.GetVector(ShaderUtilities.ID_EnvMatrixRotation);
524 m_EnvMapMatrix = Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(rotation), Vector3.one);
526 m_sharedMaterial.SetMatrix(ShaderUtilities.ID_EnvMatrix, m_EnvMapMatrix);
535 case MaskingTypes.MaskOff:
536 m_sharedMaterial.DisableKeyword(ShaderUtilities.Keyword_MASK_SOFT);
537 m_sharedMaterial.DisableKeyword(ShaderUtilities.Keyword_MASK_HARD);
538 m_sharedMaterial.DisableKeyword(ShaderUtilities.Keyword_MASK_TEX);
540 case MaskingTypes.MaskSoft:
541 m_sharedMaterial.EnableKeyword(ShaderUtilities.Keyword_MASK_SOFT);
542 m_sharedMaterial.DisableKeyword(ShaderUtilities.Keyword_MASK_HARD);
543 m_sharedMaterial.DisableKeyword(ShaderUtilities.Keyword_MASK_TEX);
545 case MaskingTypes.MaskHard:
546 m_sharedMaterial.EnableKeyword(ShaderUtilities.Keyword_MASK_HARD);
547 m_sharedMaterial.DisableKeyword(ShaderUtilities.Keyword_MASK_SOFT);
548 m_sharedMaterial.DisableKeyword(ShaderUtilities.Keyword_MASK_TEX);
560 void SetMaskCoordinates(Vector4 coords)
562 m_sharedMaterial.SetVector(ShaderUtilities.ID_ClipRect, coords);
566 void SetMaskCoordinates(Vector4 coords,
float softX,
float softY)
568 m_sharedMaterial.SetVector(ShaderUtilities.ID_ClipRect, coords);
569 m_sharedMaterial.SetFloat(ShaderUtilities.ID_MaskSoftnessX, softX);
570 m_sharedMaterial.SetFloat(ShaderUtilities.ID_MaskSoftnessY, softY);
578 if (m_sharedMaterial.HasProperty(ShaderUtilities.ID_ClipRect))
580 m_sharedMaterial.EnableKeyword(ShaderUtilities.Keyword_MASK_SOFT);
581 m_sharedMaterial.DisableKeyword(ShaderUtilities.Keyword_MASK_HARD);
582 m_sharedMaterial.DisableKeyword(ShaderUtilities.Keyword_MASK_TEX);
584 m_isMaskingEnabled =
true;
591 void DisableMasking()
593 if (m_sharedMaterial.HasProperty(ShaderUtilities.ID_ClipRect))
595 m_sharedMaterial.DisableKeyword(ShaderUtilities.Keyword_MASK_SOFT);
596 m_sharedMaterial.DisableKeyword(ShaderUtilities.Keyword_MASK_HARD);
597 m_sharedMaterial.DisableKeyword(ShaderUtilities.Keyword_MASK_TEX);
599 m_isMaskingEnabled =
false;
609 if (!m_isMaskingEnabled)
618 if (m_isMaskingEnabled && m_fontMaterial ==
null)
620 CreateMaterialInstance();
688 if (m_fontMaterial ==
null || m_fontMaterial.GetInstanceID() != mat.GetInstanceID())
689 m_fontMaterial = CreateMaterialInstance(mat);
691 m_sharedMaterial = m_fontMaterial;
698 return m_sharedMaterial;
708 int materialCount = m_textInfo.materialCount;
710 if (m_fontMaterials ==
null)
711 m_fontMaterials =
new Material[materialCount];
712 else if (m_fontMaterials.Length != materialCount)
713 TMP_TextInfo.Resize(ref m_fontMaterials, materialCount,
false);
716 for (
int i = 0; i < materialCount; i++)
721 m_fontMaterials[i] = m_subTextObjects[i].material;
724 m_fontSharedMaterials = m_fontMaterials;
726 return m_fontMaterials;
738 m_sharedMaterial = mat;
752 int materialCount = m_textInfo.materialCount;
754 if (m_fontSharedMaterials ==
null)
755 m_fontSharedMaterials =
new Material[materialCount];
756 else if (m_fontSharedMaterials.Length != materialCount)
757 TMP_TextInfo.Resize(ref m_fontSharedMaterials, materialCount,
false);
759 for (
int i = 0; i < materialCount; i++)
762 m_fontSharedMaterials[i] = m_sharedMaterial;
764 m_fontSharedMaterials[i] = m_subTextObjects[i].sharedMaterial;
767 return m_fontSharedMaterials;
776 int materialCount = m_textInfo.materialCount;
779 if (m_fontSharedMaterials ==
null)
780 m_fontSharedMaterials =
new Material[materialCount];
781 else if (m_fontSharedMaterials.Length != materialCount)
782 TMP_TextInfo.Resize(ref m_fontSharedMaterials, materialCount,
false);
785 for (
int i = 0; i < materialCount; i++)
787 Texture mat_MainTex = materials[i].GetTexture(ShaderUtilities.ID_MainTex);
792 if ( mat_MainTex ==
null || mat_MainTex.GetInstanceID() != m_sharedMaterial.GetTexture(ShaderUtilities.ID_MainTex).GetInstanceID())
795 m_sharedMaterial = m_fontSharedMaterials[i] = materials[i];
801 if (mat_MainTex ==
null || mat_MainTex.GetInstanceID() != m_subTextObjects[i].sharedMaterial.GetTexture(ShaderUtilities.ID_MainTex).GetInstanceID())
805 if (m_subTextObjects[i].isDefaultMaterial)
806 m_subTextObjects[i].sharedMaterial = m_fontSharedMaterials[i] = materials[i];
815 thickness = Mathf.Clamp01(thickness);
816 m_renderer.material.SetFloat(ShaderUtilities.ID_OutlineWidth, thickness);
818 if (m_fontMaterial ==
null)
819 m_fontMaterial = m_renderer.material;
821 m_fontMaterial = m_renderer.material;
822 m_sharedMaterial = m_fontMaterial;
830 m_renderer.material.SetColor(ShaderUtilities.ID_FaceColor,
color);
832 if (m_fontMaterial ==
null)
833 m_fontMaterial = m_renderer.material;
835 m_sharedMaterial = m_fontMaterial;
842 m_renderer.material.SetColor(ShaderUtilities.ID_OutlineColor,
color);
844 if (m_fontMaterial ==
null)
845 m_fontMaterial = m_renderer.material;
848 m_sharedMaterial = m_fontMaterial;
853 void CreateMaterialInstance()
855 Material mat =
new Material(m_sharedMaterial);
856 mat.shaderKeywords = m_sharedMaterial.shaderKeywords;
859 mat.name +=
" Instance";
861 m_fontMaterial = mat;
871 m_sharedMaterial.SetFloat(ShaderUtilities.ShaderTag_ZTestMode, 0);
873 m_renderer.material.renderQueue = 4000;
875 m_sharedMaterial = m_renderer.material;
881 m_sharedMaterial.SetFloat(ShaderUtilities.ShaderTag_ZTestMode, 4);
882 m_renderer.material.renderQueue = -1;
884 m_sharedMaterial = m_renderer.material;
893 if (m_isCullingEnabled)
895 m_renderer.material.SetFloat(
"_CullMode", 2);
897 for (
int i = 1; i < m_subTextObjects.Length && m_subTextObjects[i] !=
null; i++)
899 Renderer
renderer = m_subTextObjects[i].renderer;
903 renderer.material.SetFloat(ShaderUtilities.ShaderTag_CullMode, 2);
909 m_renderer.material.SetFloat(
"_CullMode", 0);
911 for (
int i = 1; i < m_subTextObjects.Length && m_subTextObjects[i] !=
null; i++)
913 Renderer
renderer = m_subTextObjects[i].renderer;
917 renderer.material.SetFloat(ShaderUtilities.ShaderTag_CullMode, 0);
925 void SetPerspectiveCorrection()
927 if (m_isOrthographic)
928 m_sharedMaterial.SetFloat(ShaderUtilities.ID_PerspectiveFilter, 0.0f);
930 m_sharedMaterial.SetFloat(ShaderUtilities.ID_PerspectiveFilter, 0.875f);
940 m_padding = ShaderUtilities.GetPadding(mat, m_enableExtraPadding, m_isUsingBold);
941 m_isMaskingEnabled = ShaderUtilities.IsMaskingEnabled(m_sharedMaterial);
942 m_isSDFShader = mat.HasProperty(ShaderUtilities.ID_WeightNormal);
954 ShaderUtilities.GetShaderPropertyIDs();
956 if (m_sharedMaterial ==
null)
return 0;
958 m_padding = ShaderUtilities.GetPadding(m_sharedMaterial, m_enableExtraPadding, m_isUsingBold);
959 m_isMaskingEnabled = ShaderUtilities.IsMaskingEnabled(m_sharedMaterial);
960 m_isSDFShader = m_sharedMaterial.HasProperty(ShaderUtilities.ID_WeightNormal);
974 m_totalCharacterCount = 0;
975 m_isUsingBold =
false;
976 m_isParsingText =
false;
977 tag_NoParsing =
false;
978 m_style = m_fontStyle;
980 m_fontWeightInternal = (m_style & FontStyles.Bold) == FontStyles.Bold ? 700 : m_fontWeight;
981 m_fontWeightStack.
SetDefault(m_fontWeightInternal);
983 m_currentFontAsset = m_fontAsset;
984 m_currentMaterial = m_sharedMaterial;
985 m_currentMaterialIndex = 0;
987 m_materialReferenceStack.SetDefault(
new MaterialReference(m_currentMaterialIndex, m_currentFontAsset,
null, m_currentMaterial, m_padding));
989 m_materialReferenceIndexLookup.Clear();
992 if (m_textInfo ==
null) m_textInfo =
new TMP_TextInfo();
993 m_textElementType = TMP_TextElementType.Character;
996 if (m_linkedTextComponent !=
null)
998 m_linkedTextComponent.
text =
string.Empty;
1003 for (
int i = 0; i < chars.Length && chars[i] != 0; i++)
1006 if (m_textInfo.characterInfo ==
null || m_totalCharacterCount >= m_textInfo.characterInfo.Length)
1007 TMP_TextInfo.Resize(ref m_textInfo.characterInfo, m_totalCharacterCount + 1,
true);
1012 #region PARSE XML TAGS 1013 if (m_isRichText && c == 60)
1015 int prev_MaterialIndex = m_currentMaterialIndex;
1022 if ((m_style & FontStyles.Bold) == FontStyles.Bold) m_isUsingBold =
true;
1024 if (m_textElementType == TMP_TextElementType.Sprite)
1026 m_materialReferences[m_currentMaterialIndex].referenceCount += 1;
1028 m_textInfo.characterInfo[m_totalCharacterCount].character = (char)(57344 + m_spriteIndex);
1029 m_textInfo.characterInfo[m_totalCharacterCount].spriteIndex = m_spriteIndex;
1030 m_textInfo.characterInfo[m_totalCharacterCount].fontAsset = m_currentFontAsset;
1031 m_textInfo.characterInfo[m_totalCharacterCount].spriteAsset = m_currentSpriteAsset;
1032 m_textInfo.characterInfo[m_totalCharacterCount].materialReferenceIndex = m_currentMaterialIndex;
1033 m_textInfo.characterInfo[m_totalCharacterCount].elementType = m_textElementType;
1036 m_textElementType = TMP_TextElementType.Character;
1037 m_currentMaterialIndex = prev_MaterialIndex;
1040 m_totalCharacterCount += 1;
1049 bool isUsingFallback =
false;
1050 bool isUsingAlternativeTypeface =
false;
1055 Material prev_material = m_currentMaterial;
1056 int prev_materialIndex = m_currentMaterialIndex;
1060 #region Handling of LowerCase, UpperCase and SmallCaps Font Styles 1061 if (m_textElementType == TMP_TextElementType.Character)
1063 if ((m_style & FontStyles.UpperCase) == FontStyles.UpperCase)
1066 if (
char.IsLower((
char)c))
1067 c =
char.ToUpper((
char)c);
1070 else if ((m_style & FontStyles.LowerCase) == FontStyles.LowerCase)
1073 if (
char.IsUpper((
char)c))
1074 c =
char.ToLower((
char)c);
1076 else if ((m_fontStyle & FontStyles.SmallCaps) == FontStyles.SmallCaps || (m_style & FontStyles.SmallCaps) == FontStyles.SmallCaps)
1079 if (
char.IsLower((
char)c))
1080 c =
char.ToUpper((
char)c);
1087 #region HANDLING OF FONT WEIGHT 1089 if (tempFontAsset !=
null)
1091 isUsingFallback =
true;
1092 isUsingAlternativeTypeface =
true;
1093 m_currentFontAsset = tempFontAsset;
1100 #region LOOKUP GLYPH 1101 tempFontAsset = TMP_FontUtilities.SearchForGlyph(m_currentFontAsset, c, out glyph);
1108 if (spriteAsset !=
null)
1110 int spriteIndex = -1;
1115 if (spriteIndex != -1)
1117 m_textElementType = TMP_TextElementType.Sprite;
1118 m_textInfo.characterInfo[m_totalCharacterCount].elementType = m_textElementType;
1121 m_materialReferences[m_currentMaterialIndex].referenceCount += 1;
1123 m_textInfo.characterInfo[m_totalCharacterCount].character = (char)c;
1124 m_textInfo.characterInfo[m_totalCharacterCount].spriteIndex = spriteIndex;
1125 m_textInfo.characterInfo[m_totalCharacterCount].fontAsset = m_currentFontAsset;
1126 m_textInfo.characterInfo[m_totalCharacterCount].spriteAsset =
spriteAsset;
1127 m_textInfo.characterInfo[m_totalCharacterCount].materialReferenceIndex = m_currentMaterialIndex;
1130 m_textElementType = TMP_TextElementType.Character;
1131 m_currentMaterialIndex = prev_materialIndex;
1134 m_totalCharacterCount += 1;
1163 int spriteIndex = -1;
1168 if (spriteIndex != -1)
1170 m_textElementType = TMP_TextElementType.Sprite;
1171 m_textInfo.characterInfo[m_totalCharacterCount].elementType = m_textElementType;
1174 m_materialReferences[m_currentMaterialIndex].referenceCount += 1;
1176 m_textInfo.characterInfo[m_totalCharacterCount].character = (char)c;
1177 m_textInfo.characterInfo[m_totalCharacterCount].spriteIndex = spriteIndex;
1178 m_textInfo.characterInfo[m_totalCharacterCount].fontAsset = m_currentFontAsset;
1179 m_textInfo.characterInfo[m_totalCharacterCount].spriteAsset =
spriteAsset;
1180 m_textInfo.characterInfo[m_totalCharacterCount].materialReferenceIndex = m_currentMaterialIndex;
1183 m_textElementType = TMP_TextElementType.Character;
1184 m_currentMaterialIndex = prev_materialIndex;
1187 m_totalCharacterCount += 1;
1221 tempFontAsset = TMP_FontUtilities.SearchForGlyph(m_currentFontAsset, c, out glyph);
1241 tempFontAsset = TMP_FontUtilities.SearchForGlyph(m_currentFontAsset, c, out glyph);
1242 if (!
TMP_Settings.
warningsDisabled) Debug.LogWarning(
"Character with ASCII value of " + srcGlyph +
" was not found in the Font Asset Glyph Table. It was replaced by a space.",
this);
1247 if (tempFontAsset !=
null)
1249 if (tempFontAsset.GetInstanceID() != m_currentFontAsset.GetInstanceID())
1251 isUsingFallback =
true;
1252 isUsingAlternativeTypeface =
false;
1253 m_currentFontAsset = tempFontAsset;
1259 m_textInfo.characterInfo[m_totalCharacterCount].elementType = TMP_TextElementType.Character;
1260 m_textInfo.characterInfo[m_totalCharacterCount].textElement = glyph;
1261 m_textInfo.characterInfo[m_totalCharacterCount].isUsingAlternateTypeface = isUsingAlternativeTypeface;
1262 m_textInfo.characterInfo[m_totalCharacterCount].character = (char)c;
1263 m_textInfo.characterInfo[m_totalCharacterCount].fontAsset = m_currentFontAsset;
1265 if (isUsingFallback)
1269 m_currentMaterial = TMP_MaterialManager.GetFallbackMaterial(m_currentMaterial, m_currentFontAsset.
material);
1271 m_currentMaterial = m_currentFontAsset.
material;
1276 if (!
char.IsWhiteSpace((
char)c) && c != 0x200B)
1279 if (m_materialReferences[m_currentMaterialIndex].referenceCount < 16383)
1280 m_materialReferences[m_currentMaterialIndex].referenceCount += 1;
1284 m_materialReferences[m_currentMaterialIndex].referenceCount += 1;
1288 m_textInfo.characterInfo[m_totalCharacterCount].material = m_currentMaterial;
1289 m_textInfo.characterInfo[m_totalCharacterCount].materialReferenceIndex = m_currentMaterialIndex;
1290 m_materialReferences[m_currentMaterialIndex].isFallbackMaterial = isUsingFallback;
1293 if (isUsingFallback)
1295 m_materialReferences[m_currentMaterialIndex].fallbackMaterial = prev_material;
1296 m_currentFontAsset = prev_fontAsset;
1297 m_currentMaterial = prev_material;
1298 m_currentMaterialIndex = prev_materialIndex;
1301 m_totalCharacterCount += 1;
1305 if (m_isCalculatingPreferredValues)
1307 m_isCalculatingPreferredValues =
false;
1308 m_isInputParsingRequired =
true;
1309 return m_totalCharacterCount;
1313 m_textInfo.spriteCount = spriteCount;
1314 int materialCount = m_textInfo.materialCount = m_materialReferenceIndexLookup.Count;
1317 if (materialCount > m_textInfo.meshInfo.Length)
1318 TMP_TextInfo.Resize(ref m_textInfo.meshInfo, materialCount,
false);
1321 if (materialCount > m_subTextObjects.Length)
1322 TMP_TextInfo.Resize(ref m_subTextObjects, Mathf.NextPowerOfTwo(materialCount + 1));
1325 if (m_textInfo.characterInfo.Length - m_totalCharacterCount > 256)
1326 TMP_TextInfo.Resize(ref m_textInfo.characterInfo, Mathf.Max(m_totalCharacterCount + 1, 256),
true);
1330 for (
int i = 0; i < materialCount; i++)
1335 if (m_subTextObjects[i] ==
null)
1337 m_subTextObjects[i] =
TMP_SubMesh.AddSubTextObject(
this, m_materialReferences[i]);
1340 m_textInfo.meshInfo[i].vertices =
null;
1346 if (m_subTextObjects[i].sharedMaterial ==
null || m_subTextObjects[i].sharedMaterial.GetInstanceID() != m_materialReferences[i].material.GetInstanceID())
1348 bool isDefaultMaterial = m_materialReferences[i].isDefaultMaterial;
1350 m_subTextObjects[i].isDefaultMaterial = isDefaultMaterial;
1353 if (!isDefaultMaterial || m_subTextObjects[i].sharedMaterial ==
null || m_subTextObjects[i].sharedMaterial.GetTexture(ShaderUtilities.ID_MainTex).GetInstanceID() != m_materialReferences[i].material.GetTexture(ShaderUtilities.ID_MainTex).GetInstanceID())
1355 m_subTextObjects[i].sharedMaterial = m_materialReferences[i].material;
1356 m_subTextObjects[i].fontAsset = m_materialReferences[i].fontAsset;
1357 m_subTextObjects[i].spriteAsset = m_materialReferences[i].spriteAsset;
1362 if (m_materialReferences[i].isFallbackMaterial)
1364 m_subTextObjects[i].fallbackMaterial = m_materialReferences[i].material;
1365 m_subTextObjects[i].fallbackSourceMaterial = m_materialReferences[i].fallbackMaterial;
1370 int referenceCount = m_materialReferences[i].referenceCount;
1373 if (m_textInfo.meshInfo[i].vertices ==
null || m_textInfo.meshInfo[i].vertices.Length < referenceCount * (!m_isVolumetricText ? 4 : 8))
1375 if (m_textInfo.meshInfo[i].vertices ==
null)
1378 m_textInfo.meshInfo[i] =
new TMP_MeshInfo(m_mesh, referenceCount + 1, m_isVolumetricText);
1380 m_textInfo.meshInfo[i] =
new TMP_MeshInfo(m_subTextObjects[i].
mesh, referenceCount + 1, m_isVolumetricText);
1383 m_textInfo.meshInfo[i].
ResizeMeshInfo(referenceCount > 1024 ? referenceCount + 256 : Mathf.NextPowerOfTwo(referenceCount), m_isVolumetricText);
1385 else if (m_textInfo.meshInfo[i].vertices.Length - referenceCount * (!m_isVolumetricText ? 4 : 8) > 1024)
1389 m_textInfo.meshInfo[i].
ResizeMeshInfo(referenceCount > 1024 ? referenceCount + 256 : Mathf.Max(Mathf.NextPowerOfTwo(referenceCount), 256), m_isVolumetricText);
1396 for (
int i = materialCount; i < m_subTextObjects.Length && m_subTextObjects[i] !=
null; i++)
1398 if (i < m_textInfo.meshInfo.Length)
1404 return m_totalCharacterCount;
1425 m_marginWidth = m_rectTransform.rect.width - m_margin.x - m_margin.z;
1426 m_marginHeight = m_rectTransform.rect.height - m_margin.y - m_margin.w;
1434 protected override void OnDidApplyAnimationProperties()
1438 m_havePropertiesChanged =
true;
1439 isMaskUpdateRequired =
true;
1445 protected override void OnTransformParentChanged()
1453 protected override void OnRectTransformDimensionsChange()
1469 if (m_rectTransform.hasChanged)
1472 float lossyScaleY = m_rectTransform.lossyScale.y;
1473 if (!m_havePropertiesChanged && lossyScaleY != m_previousLossyScaleY && m_text !=
string.Empty && m_text !=
null)
1477 m_previousLossyScaleY = lossyScaleY;
1482 if (m_isUsingLegacyAnimationComponent)
1485 m_havePropertiesChanged =
true;
1498 if (!m_isAwake || (this.IsActive() ==
false && m_ignoreActiveState ==
false))
return;
1507 if (m_havePropertiesChanged || m_isLayoutDirty)
1511 if (isMaskUpdateRequired)
1514 isMaskUpdateRequired =
false;
1518 if (checkPaddingRequired)
1522 if (m_isInputParsingRequired || m_isTextTruncated)
1526 if (m_enableAutoSizing)
1527 m_fontSize = Mathf.Clamp(m_fontSizeBase, m_fontSizeMin, m_fontSizeMax);
1529 m_maxFontSize = m_fontSizeMax;
1530 m_minFontSize = m_fontSizeMin;
1531 m_lineSpacingDelta = 0;
1532 m_charWidthAdjDelta = 0;
1535 m_isCharacterWrappingEnabled =
false;
1536 m_isTextTruncated =
false;
1538 m_havePropertiesChanged =
false;
1539 m_isLayoutDirty =
false;
1540 m_ignoreActiveState =
false;
1556 if (m_fontAsset ==
null || m_fontAsset.characterDictionary ==
null)
1558 Debug.LogWarning(
"Can't Generate Mesh! No Font Asset has been assigned to Object ID: " + this.GetInstanceID());
1563 if (m_textInfo !=
null)
1567 if (m_char_buffer ==
null || m_char_buffer.Length == 0 || m_char_buffer[0] == (
char)0)
1572 m_preferredWidth = 0;
1573 m_preferredHeight = 0;
1576 TMPro_EventManager.ON_TEXT_CHANGED(
this);
1581 m_currentFontAsset = m_fontAsset;
1582 m_currentMaterial = m_sharedMaterial;
1583 m_currentMaterialIndex = 0;
1584 m_materialReferenceStack.SetDefault(
new MaterialReference(m_currentMaterialIndex, m_currentFontAsset,
null, m_currentMaterial, m_padding));
1586 m_currentSpriteAsset = m_spriteAsset;
1589 if (m_spriteAnimator !=
null)
1590 m_spriteAnimator.StopAllAnimations();
1593 int totalCharacterCount = m_totalCharacterCount;
1597 float baseScale = m_fontScale = (m_fontSize / m_fontAsset.
fontInfo.PointSize * m_fontAsset.
fontInfo.Scale * (m_isOrthographic ? 1 : 0.1f));
1598 float currentElementScale = baseScale;
1599 m_fontScaleMultiplier = 1;
1601 m_currentFontSize = m_fontSize;
1603 float fontSizeDelta = 0;
1607 m_style = m_fontStyle;
1608 m_fontWeightInternal = (m_style & FontStyles.Bold) == FontStyles.Bold ? 700 : m_fontWeight;
1609 m_fontWeightStack.
SetDefault(m_fontWeightInternal);
1610 m_fontStyleStack.
Clear();
1612 m_lineJustification = m_textAlignment;
1613 m_lineJustificationStack.
SetDefault(m_lineJustification);
1616 float style_padding = 0;
1617 float bold_xAdvance_multiplier = 1;
1619 m_baselineOffset = 0;
1620 m_baselineOffsetStack.
Clear();
1623 bool beginUnderline =
false;
1624 Vector3 underline_start = Vector3.zero;
1625 Vector3 underline_end = Vector3.zero;
1628 bool beginStrikethrough =
false;
1629 Vector3 strikethrough_start = Vector3.zero;
1630 Vector3 strikethrough_end = Vector3.zero;
1633 bool beginHighlight =
false;
1634 Vector3 highlight_start = Vector3.zero;
1635 Vector3 highlight_end = Vector3.zero;
1637 m_fontColor32 = m_fontColor;
1638 Color32 vertexColor;
1639 m_htmlColor = m_fontColor32;
1640 m_underlineColor = m_htmlColor;
1641 m_strikethroughColor = m_htmlColor;
1644 m_underlineColorStack.
SetDefault(m_htmlColor);
1645 m_strikethroughColorStack.
SetDefault(m_htmlColor);
1646 m_highlightColorStack.
SetDefault(m_htmlColor);
1648 m_colorGradientPreset =
null;
1649 m_colorGradientStack.SetDefault(
null);
1655 m_actionStack.
Clear();
1657 m_isFXMatrixSet =
false;
1660 m_lineHeight = TMP_Math.FLOAT_UNSET;
1661 float lineGap = m_currentFontAsset.
fontInfo.LineHeight - (m_currentFontAsset.
fontInfo.Ascender - m_currentFontAsset.
fontInfo.Descender);
1665 float lineOffsetDelta = 0;
1671 tag_NoParsing =
false;
1674 m_characterCount = 0;
1677 m_firstCharacterOfLine = 0;
1678 m_lastCharacterOfLine = 0;
1679 m_firstVisibleCharacterOfLine = 0;
1680 m_lastVisibleCharacterOfLine = 0;
1681 m_maxLineAscender = k_LargeNegativeFloat;
1682 m_maxLineDescender = k_LargePositiveFloat;
1684 m_lineVisibleCharacterCount = 0;
1685 bool isStartOfNewLine =
true;
1686 m_firstOverflowCharacterIndex = -1;
1689 int pageToDisplay = Mathf.Clamp(m_pageToDisplay - 1, 0, m_textInfo.pageInfo.Length - 1);
1690 int previousPageOverflowChar = 0;
1692 int ellipsisIndex = 0;
1694 Vector4 margins = m_margin;
1695 float marginWidth = m_marginWidth;
1696 float marginHeight = m_marginHeight;
1700 float width = marginWidth + 0.0001f - m_marginLeft - m_marginRight;
1703 m_meshExtents.min = k_LargePositiveVector2;
1704 m_meshExtents.max = k_LargeNegativeVector2;
1713 float pageAscender = 0;
1714 float maxVisibleDescender = 0;
1715 bool isMaxVisibleDescenderSet =
false;
1716 m_isNewPage =
false;
1719 bool isFirstWord =
true;
1720 m_isNonBreakingSpace =
false;
1721 bool ignoreNonBreakingSpace =
false;
1722 bool isLastBreakingChar =
false;
1723 float linebreakingWidth = 0;
1724 int wrappingIndex = 0;
1732 int endTagIndex = 0;
1734 for (
int i = 0; i < m_char_buffer.Length && m_char_buffer[i] != 0; i++)
1736 charCode = m_char_buffer[i];
1739 #region Parse Rich Text Tag 1740 if (m_isRichText && charCode == 60)
1742 m_isParsingText =
true;
1743 m_textElementType = TMP_TextElementType.Character;
1751 if (m_textElementType == TMP_TextElementType.Character)
1757 m_textElementType = m_textInfo.characterInfo[m_characterCount].elementType;
1758 m_currentMaterialIndex = m_textInfo.characterInfo[m_characterCount].materialReferenceIndex;
1759 m_currentFontAsset = m_textInfo.characterInfo[m_characterCount].fontAsset;
1761 #endregion End Parse Rich Text Tag 1763 int prev_MaterialIndex = m_currentMaterialIndex;
1764 bool isUsingAltTypeface = m_textInfo.characterInfo[m_characterCount].isUsingAlternateTypeface;
1766 m_isParsingText =
false;
1769 if (m_characterCount < m_firstVisibleCharacter)
1771 m_textInfo.characterInfo[m_characterCount].isVisible =
false;
1772 m_textInfo.characterInfo[m_characterCount].character = (char)0x200B;
1773 m_characterCount += 1;
1778 #region Handling of LowerCase, UpperCase and SmallCaps Font Styles 1780 float smallCapsMultiplier = 1.0f;
1782 if (m_textElementType == TMP_TextElementType.Character)
1784 if ((m_style & FontStyles.UpperCase) == FontStyles.UpperCase)
1787 if (
char.IsLower((
char)charCode))
1788 charCode =
char.ToUpper((
char)charCode);
1791 else if ((m_style & FontStyles.LowerCase) == FontStyles.LowerCase)
1794 if (
char.IsUpper((
char)charCode))
1795 charCode =
char.ToLower((
char)charCode);
1797 else if ((m_fontStyle & FontStyles.SmallCaps) == FontStyles.SmallCaps || (m_style & FontStyles.SmallCaps) == FontStyles.SmallCaps)
1799 if (
char.IsLower((
char)charCode))
1801 smallCapsMultiplier = 0.8f;
1802 charCode =
char.ToUpper((
char)charCode);
1810 #region Look up Character Data 1811 if (m_textElementType == TMP_TextElementType.Sprite)
1815 m_currentSpriteAsset = m_textInfo.characterInfo[m_characterCount].spriteAsset;
1816 m_spriteIndex = m_textInfo.characterInfo[m_characterCount].spriteIndex;
1818 TMP_Sprite sprite = m_currentSpriteAsset.spriteInfoList[m_spriteIndex];
1819 if (sprite ==
null)
continue;
1823 charCode = 57344 + m_spriteIndex;
1825 m_spriteColor = s_colorWhite;
1828 float spriteScale = (m_currentFontSize / m_currentFontAsset.
fontInfo.PointSize * m_currentFontAsset.
fontInfo.Scale * (m_isOrthographic ? 1 : 0.1f));
1829 currentElementScale = m_currentFontAsset.
fontInfo.Ascender / sprite.height * sprite.scale * spriteScale;
1831 m_cached_TextElement = sprite;
1833 m_textInfo.characterInfo[m_characterCount].elementType = TMP_TextElementType.Sprite;
1834 m_textInfo.characterInfo[m_characterCount].scale = spriteScale;
1835 m_textInfo.characterInfo[m_characterCount].spriteAsset = m_currentSpriteAsset;
1836 m_textInfo.characterInfo[m_characterCount].fontAsset = m_currentFontAsset;
1837 m_textInfo.characterInfo[m_characterCount].materialReferenceIndex = m_currentMaterialIndex;
1839 m_currentMaterialIndex = prev_MaterialIndex;
1843 else if (m_textElementType == TMP_TextElementType.Character)
1845 m_cached_TextElement = m_textInfo.characterInfo[m_characterCount].textElement;
1846 if (m_cached_TextElement ==
null)
continue;
1848 m_currentFontAsset = m_textInfo.characterInfo[m_characterCount].fontAsset;
1849 m_currentMaterial = m_textInfo.characterInfo[m_characterCount].material;
1850 m_currentMaterialIndex = m_textInfo.characterInfo[m_characterCount].materialReferenceIndex;
1853 m_fontScale = m_currentFontSize * smallCapsMultiplier / m_currentFontAsset.
fontInfo.PointSize * m_currentFontAsset.
fontInfo.Scale * (m_isOrthographic ? 1 : 0.1f);
1855 currentElementScale = m_fontScale * m_fontScaleMultiplier * m_cached_TextElement.scale;
1857 m_textInfo.characterInfo[m_characterCount].elementType = TMP_TextElementType.Character;
1858 m_textInfo.characterInfo[m_characterCount].scale = currentElementScale;
1860 padding = m_currentMaterialIndex == 0 ? m_padding : m_subTextObjects[m_currentMaterialIndex].padding;
1866 #region Handle Soft Hyphen 1867 float old_scale = currentElementScale;
1868 if (charCode == 0xAD)
1870 currentElementScale = 0;
1876 m_textInfo.characterInfo[m_characterCount].character = (char)charCode;
1877 m_textInfo.characterInfo[m_characterCount].pointSize = m_currentFontSize;
1878 m_textInfo.characterInfo[m_characterCount].color = m_htmlColor;
1879 m_textInfo.characterInfo[m_characterCount].underlineColor = m_underlineColor;
1880 m_textInfo.characterInfo[m_characterCount].strikethroughColor = m_strikethroughColor;
1881 m_textInfo.characterInfo[m_characterCount].highlightColor = m_highlightColor;
1882 m_textInfo.characterInfo[m_characterCount].style = m_style;
1883 m_textInfo.characterInfo[m_characterCount].
index = i;
1888 #region Handle Kerning 1890 if (m_enableKerning)
1894 if (m_characterCount < totalCharacterCount - 1)
1896 uint nextGlyph = m_textInfo.characterInfo[m_characterCount + 1].character;
1899 m_currentFontAsset.
kerningDictionary.TryGetValue((
int)keyValue.key, out adjustmentPair);
1900 if (adjustmentPair !=
null)
1901 glyphAdjustments = adjustmentPair.firstGlyphAdjustments;
1904 if (m_characterCount >= 1)
1906 uint previousGlyph = m_textInfo.characterInfo[m_characterCount - 1].character;
1909 m_currentFontAsset.
kerningDictionary.TryGetValue((
int)keyValue.key, out adjustmentPair);
1910 if (adjustmentPair !=
null)
1911 glyphAdjustments += adjustmentPair.secondGlyphAdjustments;
1918 #region Handle Right-to-Left 1919 if (m_isRightToLeft)
1921 m_xAdvance -= ((m_cached_TextElement.xAdvance * bold_xAdvance_multiplier + m_characterSpacing + m_wordSpacing + m_currentFontAsset.normalSpacingOffset) * currentElementScale + m_cSpacing) * (1 - m_charWidthAdjDelta);
1923 if (
char.IsWhiteSpace((
char)charCode) || charCode == 0x200B)
1924 m_xAdvance -= m_wordSpacing * currentElementScale;
1930 #region Handle Mono Spacing 1931 float monoAdvance = 0;
1932 if (m_monoSpacing != 0)
1934 monoAdvance = (m_monoSpacing / 2 - (m_cached_TextElement.width / 2 + m_cached_TextElement.xOffset) * currentElementScale) * (1 - m_charWidthAdjDelta);
1935 m_xAdvance += monoAdvance;
1941 #region Handle Style Padding 1942 if (m_textElementType == TMP_TextElementType.Character && !isUsingAltTypeface && ((m_style & FontStyles.Bold) == FontStyles.Bold || (m_fontStyle & FontStyles.Bold) == FontStyles.Bold))
1944 if (m_currentMaterial.HasProperty(ShaderUtilities.ID_GradientScale))
1946 float gradientScale = m_currentMaterial.GetFloat(ShaderUtilities.ID_GradientScale);
1947 style_padding = m_currentFontAsset.boldStyle / 4.0f * gradientScale * m_currentMaterial.GetFloat(ShaderUtilities.ID_ScaleRatio_A);
1950 if (style_padding + padding > gradientScale)
1951 padding = gradientScale - style_padding;
1956 bold_xAdvance_multiplier = 1 + m_currentFontAsset.boldSpacing * 0.01f;
1960 if (m_currentMaterial.HasProperty(ShaderUtilities.ID_GradientScale))
1962 float gradientScale = m_currentMaterial.GetFloat(ShaderUtilities.ID_GradientScale);
1963 style_padding = m_currentFontAsset.normalStyle / 4.0f * gradientScale * m_currentMaterial.GetFloat(ShaderUtilities.ID_ScaleRatio_A);
1966 if (style_padding + padding > gradientScale)
1967 padding = gradientScale - style_padding;
1972 bold_xAdvance_multiplier = 1.0f;
1974 #endregion Handle Style Padding 1978 #region Calculate Vertices Position 1979 float fontBaseLineOffset = m_currentFontAsset.
fontInfo.Baseline * m_fontScale * m_fontScaleMultiplier * m_currentFontAsset.
fontInfo.Scale;
1981 top_left.x = m_xAdvance + ((m_cached_TextElement.xOffset - padding - style_padding + glyphAdjustments.xPlacement) * currentElementScale * (1 - m_charWidthAdjDelta));
1982 top_left.y = fontBaseLineOffset + (m_cached_TextElement.yOffset + padding + glyphAdjustments.yPlacement) * currentElementScale - m_lineOffset + m_baselineOffset;
1985 Vector3 bottom_left;
1986 bottom_left.x = top_left.x;
1987 bottom_left.y = top_left.y - ((m_cached_TextElement.height + padding * 2) * currentElementScale);
1991 top_right.x = bottom_left.x + ((m_cached_TextElement.width + padding * 2 + style_padding * 2) * currentElementScale * (1 - m_charWidthAdjDelta));
1992 top_right.y = top_left.y;
1995 Vector3 bottom_right;
1996 bottom_right.x = top_right.x;
1997 bottom_right.y = bottom_left.y;
2003 #region Handle Italic & Shearing 2004 if (m_textElementType == TMP_TextElementType.Character && !isUsingAltTypeface && ((m_style & FontStyles.Italic) == FontStyles.Italic || (m_fontStyle & FontStyles.Italic) == FontStyles.Italic))
2007 float shear_value = m_currentFontAsset.italicStyle * 0.01f;
2008 Vector3 topShear =
new Vector3(shear_value * ((m_cached_TextElement.yOffset + padding + style_padding) * currentElementScale), 0, 0);
2009 Vector3 bottomShear =
new Vector3(shear_value * (((m_cached_TextElement.yOffset - m_cached_TextElement.height - padding - style_padding)) * currentElementScale), 0, 0);
2011 top_left = top_left + topShear;
2012 bottom_left = bottom_left + bottomShear;
2013 top_right = top_right + topShear;
2014 bottom_right = bottom_right + bottomShear;
2016 #endregion Handle Italics & Shearing 2020 #region Handle Character Rotation 2021 if (m_isFXMatrixSet)
2024 if (m_FXMatrix.m00 != 1)
2032 Vector3 positionOffset = (top_right + bottom_left) / 2;
2034 top_left = m_FXMatrix.MultiplyPoint3x4(top_left - positionOffset) + positionOffset;
2035 bottom_left = m_FXMatrix.MultiplyPoint3x4(bottom_left - positionOffset) + positionOffset;
2036 top_right = m_FXMatrix.MultiplyPoint3x4(top_right - positionOffset) + positionOffset;
2037 bottom_right = m_FXMatrix.MultiplyPoint3x4(bottom_right - positionOffset) + positionOffset;
2043 m_textInfo.characterInfo[m_characterCount].bottomLeft = bottom_left;
2044 m_textInfo.characterInfo[m_characterCount].topLeft = top_left;
2045 m_textInfo.characterInfo[m_characterCount].topRight = top_right;
2046 m_textInfo.characterInfo[m_characterCount].bottomRight = bottom_right;
2048 m_textInfo.characterInfo[m_characterCount].origin = m_xAdvance;
2049 m_textInfo.characterInfo[m_characterCount].baseLine = fontBaseLineOffset - m_lineOffset + m_baselineOffset;
2050 m_textInfo.characterInfo[m_characterCount].aspectRatio = (top_right.x - bottom_left.x) / (top_left.y - bottom_left.y);
2054 float elementAscender = m_currentFontAsset.
fontInfo.Ascender * (m_textElementType == TMP_TextElementType.Character ? currentElementScale / smallCapsMultiplier : m_textInfo.characterInfo[m_characterCount].scale) + m_baselineOffset;
2055 m_textInfo.characterInfo[m_characterCount].ascender = elementAscender - m_lineOffset;
2056 m_maxLineAscender = elementAscender > m_maxLineAscender ? elementAscender : m_maxLineAscender;
2059 float elementDescender = m_currentFontAsset.
fontInfo.Descender * (m_textElementType == TMP_TextElementType.Character ? currentElementScale / smallCapsMultiplier : m_textInfo.characterInfo[m_characterCount].scale) + m_baselineOffset;
2060 float elementDescenderII = m_textInfo.characterInfo[m_characterCount].descender = elementDescender - m_lineOffset;
2061 m_maxLineDescender = elementDescender < m_maxLineDescender ? elementDescender : m_maxLineDescender;
2064 if ((m_style & FontStyles.Subscript) == FontStyles.Subscript || (m_style & FontStyles.Superscript) == FontStyles.Superscript)
2066 float baseAscender = (elementAscender - m_baselineOffset) / m_currentFontAsset.
fontInfo.SubSize;
2067 elementAscender = m_maxLineAscender;
2068 m_maxLineAscender = baseAscender > m_maxLineAscender ? baseAscender : m_maxLineAscender;
2070 float baseDescender = (elementDescender - m_baselineOffset) / m_currentFontAsset.
fontInfo.SubSize;
2071 elementDescender = m_maxLineDescender;
2072 m_maxLineDescender = baseDescender < m_maxLineDescender ? baseDescender : m_maxLineDescender;
2075 if (m_lineNumber == 0 || m_isNewPage)
2077 m_maxAscender = m_maxAscender > elementAscender ? m_maxAscender : elementAscender;
2078 m_maxCapHeight = Mathf.Max(m_maxCapHeight, m_currentFontAsset.
fontInfo.CapHeight * currentElementScale / smallCapsMultiplier);
2080 if (m_lineOffset == 0) pageAscender = pageAscender > elementAscender ? pageAscender : elementAscender;
2084 m_textInfo.characterInfo[m_characterCount].isVisible =
false;
2087 #region Handle Visible Characters 2088 if (charCode == 9 || charCode == 0xA0 || charCode == 0x2007 || (!
char.IsWhiteSpace((
char)charCode) && charCode != 0x200B) || m_textElementType == TMP_TextElementType.Sprite)
2090 m_textInfo.characterInfo[m_characterCount].isVisible =
true;
2092 #region Experimental Margin Shaper 2127 width = m_width != -1 ? Mathf.Min(marginWidth + 0.0001f - m_marginLeft - m_marginRight, m_width) : marginWidth + 0.0001f - m_marginLeft - m_marginRight;
2128 m_textInfo.lineInfo[m_lineNumber].marginLeft = m_marginLeft;
2133 linebreakingWidth = Mathf.Abs(m_xAdvance) + (!m_isRightToLeft ? m_cached_TextElement.xAdvance : 0) * (1 - m_charWidthAdjDelta) * (charCode != 0xAD ? currentElementScale : old_scale);
2136 #region Handle Line Breaking, Text Auto-Sizing and Horizontal Overflow 2137 if (linebreakingWidth > width * (isJustifiedOrFlush ? 1.05f : 1.0f))
2139 ellipsisIndex = m_characterCount - 1;
2142 #region Handle Word Wrapping 2146 #region Line Breaking Check 2147 if (wrappingIndex == m_SavedWordWrapState.previous_WordBreak || isFirstWord)
2150 if (m_enableAutoSizing && m_fontSize > m_fontSizeMin)
2153 #region Character Width Adjustments 2154 if (m_charWidthAdjDelta < m_charWidthMaxAdj / 100)
2157 m_charWidthAdjDelta += 0.01f;
2164 m_maxFontSize = m_fontSize;
2166 m_fontSize -= Mathf.Max((m_fontSize - m_minFontSize) / 2, 0.05f);
2167 m_fontSize = (int)(Mathf.Max(m_fontSize, m_fontSizeMin) * 20 + 0.5f) / 20f;
2169 if (loopCountA > 20)
return;
2175 if (m_isCharacterWrappingEnabled ==
false)
2177 if (ignoreNonBreakingSpace ==
false)
2178 ignoreNonBreakingSpace =
true;
2180 m_isCharacterWrappingEnabled =
true;
2183 isLastBreakingChar =
true;
2199 if (m_char_buffer[i] == 0xAD)
2201 m_isTextTruncated =
true;
2202 m_char_buffer[i] = 0x2D;
2210 if (m_lineNumber > 0 && !TMP_Math.Approximately(m_maxLineAscender, m_startOfLineAscender) && m_lineHeight == TMP_Math.FLOAT_UNSET && !m_isNewPage)
2213 float offsetDelta = m_maxLineAscender - m_startOfLineAscender;
2215 m_lineOffset += offsetDelta;
2216 m_SavedWordWrapState.lineOffset = m_lineOffset;
2217 m_SavedWordWrapState.previousLineAscender = m_maxLineAscender;
2221 m_isNewPage =
false;
2224 float lineAscender = m_maxLineAscender - m_lineOffset;
2225 float lineDescender = m_maxLineDescender - m_lineOffset;
2229 m_maxDescender = m_maxDescender < lineDescender ? m_maxDescender : lineDescender;
2230 if (!isMaxVisibleDescenderSet)
2231 maxVisibleDescender = m_maxDescender;
2233 if (m_useMaxVisibleDescender && (m_characterCount >= m_maxVisibleCharacters || m_lineNumber >= m_maxVisibleLines))
2234 isMaxVisibleDescenderSet =
true;
2237 m_textInfo.lineInfo[m_lineNumber].firstCharacterIndex = m_firstCharacterOfLine;
2238 m_textInfo.lineInfo[m_lineNumber].firstVisibleCharacterIndex = m_firstVisibleCharacterOfLine = m_firstCharacterOfLine > m_firstVisibleCharacterOfLine ? m_firstCharacterOfLine : m_firstVisibleCharacterOfLine;
2239 m_textInfo.lineInfo[m_lineNumber].lastCharacterIndex = m_lastCharacterOfLine = m_characterCount - 1 > 0 ? m_characterCount - 1 : 0;
2240 m_textInfo.lineInfo[m_lineNumber].lastVisibleCharacterIndex = m_lastVisibleCharacterOfLine = m_lastVisibleCharacterOfLine < m_firstVisibleCharacterOfLine ? m_firstVisibleCharacterOfLine : m_lastVisibleCharacterOfLine;
2242 m_textInfo.lineInfo[m_lineNumber].characterCount = m_textInfo.lineInfo[m_lineNumber].lastCharacterIndex - m_textInfo.lineInfo[m_lineNumber].firstCharacterIndex + 1;
2243 m_textInfo.lineInfo[m_lineNumber].visibleCharacterCount = m_lineVisibleCharacterCount;
2244 m_textInfo.lineInfo[m_lineNumber].lineExtents.min =
new Vector2(m_textInfo.characterInfo[m_firstVisibleCharacterOfLine].bottomLeft.x, lineDescender);
2245 m_textInfo.lineInfo[m_lineNumber].lineExtents.max =
new Vector2(m_textInfo.characterInfo[m_lastVisibleCharacterOfLine].topRight.x, lineAscender);
2246 m_textInfo.lineInfo[m_lineNumber].length = m_textInfo.lineInfo[m_lineNumber].lineExtents.max.x;
2247 m_textInfo.lineInfo[m_lineNumber].width = width;
2251 m_textInfo.lineInfo[m_lineNumber].maxAdvance = m_textInfo.characterInfo[m_lastVisibleCharacterOfLine].xAdvance - (m_characterSpacing + m_currentFontAsset.normalSpacingOffset) * currentElementScale - m_cSpacing;
2253 m_textInfo.lineInfo[m_lineNumber].baseline = 0 - m_lineOffset;
2254 m_textInfo.lineInfo[m_lineNumber].ascender = lineAscender;
2255 m_textInfo.lineInfo[m_lineNumber].descender = lineDescender;
2256 m_textInfo.lineInfo[m_lineNumber].lineHeight = lineAscender - lineDescender + lineGap * baseScale;
2258 m_firstCharacterOfLine = m_characterCount;
2259 m_lineVisibleCharacterCount = 0;
2265 isStartOfNewLine =
true;
2269 if (m_lineNumber >= m_textInfo.lineInfo.Length)
2273 if (m_lineHeight == TMP_Math.FLOAT_UNSET)
2275 float ascender = m_textInfo.characterInfo[m_characterCount].ascender - m_textInfo.characterInfo[m_characterCount].baseLine;
2276 lineOffsetDelta = 0 - m_maxLineDescender + ascender + (lineGap + m_lineSpacing + m_lineSpacingDelta) * baseScale;
2277 m_lineOffset += lineOffsetDelta;
2279 m_startOfLineAscender = ascender;
2282 m_lineOffset += m_lineHeight + m_lineSpacing * baseScale;
2284 m_maxLineAscender = k_LargeNegativeFloat;
2285 m_maxLineDescender = k_LargePositiveFloat;
2287 m_xAdvance = 0 + tag_Indent;
2291 #endregion End Word Wrapping 2295 #region Handle Text Auto-Sizing 2296 if (m_enableAutoSizing && m_fontSize > m_fontSizeMin)
2299 #region Character Width Adjustments 2300 if (m_charWidthAdjDelta < m_charWidthMaxAdj / 100)
2303 m_charWidthAdjDelta += 0.01f;
2310 m_maxFontSize = m_fontSize;
2312 m_fontSize -= Mathf.Max((m_fontSize - m_minFontSize) / 2, 0.05f);
2313 m_fontSize = (int)(Mathf.Max(m_fontSize, m_fontSizeMin) * 20 + 0.5f) / 20f;
2316 if (loopCountA > 20)
return;
2320 #endregion End Text Auto-Sizing 2324 #region Handle Text Overflow 2325 switch (m_overflowMode)
2327 case TextOverflowModes.Overflow:
2328 if (m_isMaskingEnabled)
2332 case TextOverflowModes.Ellipsis:
2333 if (m_isMaskingEnabled)
2336 m_isTextTruncated =
true;
2338 if (m_characterCount < 1)
2340 m_textInfo.characterInfo[m_characterCount].isVisible =
false;
2345 m_char_buffer[i - 1] = 8230;
2346 m_char_buffer[i] = (char)0;
2348 if (m_cached_Ellipsis_GlyphInfo !=
null)
2350 m_textInfo.characterInfo[ellipsisIndex].character = (char)8230;
2351 m_textInfo.characterInfo[ellipsisIndex].textElement = m_cached_Ellipsis_GlyphInfo;
2352 m_textInfo.characterInfo[ellipsisIndex].fontAsset = m_materialReferences[0].fontAsset;
2353 m_textInfo.characterInfo[ellipsisIndex].material = m_materialReferences[0].material;
2354 m_textInfo.characterInfo[ellipsisIndex].materialReferenceIndex = 0;
2358 Debug.LogWarning(
"Unable to use Ellipsis character since it wasn't found in the current Font Asset [" + m_fontAsset.name +
"]. Consider regenerating this font asset to include the Ellipsis character (u+2026).\nNote: Warnings can be disabled in the TMP Settings file.",
this);
2361 m_totalCharacterCount = ellipsisIndex + 1;
2365 case TextOverflowModes.Masking:
2366 if (!m_isMaskingEnabled)
2369 case TextOverflowModes.ScrollRect:
2370 if (!m_isMaskingEnabled)
2373 case TextOverflowModes.Truncate:
2374 if (m_isMaskingEnabled)
2377 m_textInfo.characterInfo[m_characterCount].isVisible =
false;
2379 case TextOverflowModes.Linked:
2390 #endregion End Text Overflow 2393 #endregion End Check for Characters Exceeding Width of Text Container 2397 if (charCode == 9 || charCode == 0xA0 || charCode == 0x2007)
2399 m_textInfo.characterInfo[m_characterCount].isVisible =
false;
2400 m_lastVisibleCharacterOfLine = m_characterCount;
2401 m_textInfo.lineInfo[m_lineNumber].spaceCount += 1;
2402 m_textInfo.spaceCount += 1;
2404 if (charCode == 0xA0)
2405 m_textInfo.lineInfo[m_lineNumber].controlCharacterCount += 1;
2410 if (m_overrideHtmlColors)
2411 vertexColor = m_fontColor32;
2413 vertexColor = m_htmlColor;
2416 if (m_textElementType == TMP_TextElementType.Character)
2421 else if (m_textElementType == TMP_TextElementType.Sprite)
2429 if (m_textInfo.characterInfo[m_characterCount].isVisible && charCode != 0xAD)
2431 if (isStartOfNewLine) { isStartOfNewLine =
false; m_firstVisibleCharacterOfLine = m_characterCount; }
2433 m_lineVisibleCharacterCount += 1;
2434 m_lastVisibleCharacterOfLine = m_characterCount;
2441 if ((charCode == 10 ||
char.IsSeparator((
char)charCode)) && charCode != 0xAD && charCode != 0x200B && charCode != 0x2060)
2443 m_textInfo.lineInfo[m_lineNumber].spaceCount += 1;
2444 m_textInfo.spaceCount += 1;
2447 #endregion Handle Visible Characters 2451 #region Adjust Line Spacing 2452 if (m_lineNumber > 0 && !TMP_Math.Approximately(m_maxLineAscender, m_startOfLineAscender) && m_lineHeight == TMP_Math.FLOAT_UNSET && !m_isNewPage)
2457 float offsetDelta = m_maxLineAscender - m_startOfLineAscender;
2459 elementDescenderII -= offsetDelta;
2460 m_lineOffset += offsetDelta;
2462 m_startOfLineAscender += offsetDelta;
2463 m_SavedWordWrapState.lineOffset = m_lineOffset;
2464 m_SavedWordWrapState.previousLineAscender = m_startOfLineAscender;
2470 #region Store Character Data 2471 m_textInfo.characterInfo[m_characterCount].lineNumber = m_lineNumber;
2472 m_textInfo.characterInfo[m_characterCount].pageNumber = m_pageNumber;
2474 if (charCode != 10 && charCode != 13 && charCode != 8230 || m_textInfo.lineInfo[m_lineNumber].characterCount == 1)
2475 m_textInfo.lineInfo[m_lineNumber].alignment = m_lineJustification;
2476 #endregion Store Character Data 2480 #region Check Vertical Bounds & Auto-Sizing 2481 if (m_maxAscender - elementDescenderII > marginHeight + 0.0001f)
2484 #region Line Spacing Adjustments 2485 if (m_enableAutoSizing && m_lineSpacingDelta > m_lineSpacingMax && m_lineNumber > 0)
2489 m_lineSpacingDelta -= 1;
2497 #region Text Auto-Sizing (Text greater than vertical bounds) 2498 if (m_enableAutoSizing && m_fontSize > m_fontSizeMin)
2500 m_maxFontSize = m_fontSize;
2502 m_fontSize -= Mathf.Max((m_fontSize - m_minFontSize) / 2, 0.05f);
2503 m_fontSize = (int)(Mathf.Max(m_fontSize, m_fontSizeMin) * 20 + 0.5f) / 20f;
2506 if (loopCountA > 20)
return;
2510 #endregion Text Auto-Sizing 2513 if (m_firstOverflowCharacterIndex == -1)
2514 m_firstOverflowCharacterIndex = m_characterCount;
2517 #region Text Overflow 2518 switch (m_overflowMode)
2520 case TextOverflowModes.Overflow:
2521 if (m_isMaskingEnabled)
2525 case TextOverflowModes.Ellipsis:
2526 if (m_isMaskingEnabled)
2529 if (m_lineNumber > 0)
2531 m_char_buffer[m_textInfo.characterInfo[ellipsisIndex].
index] = 8230;
2532 m_char_buffer[m_textInfo.characterInfo[ellipsisIndex].
index + 1] = (char)0;
2534 if (m_cached_Ellipsis_GlyphInfo !=
null)
2536 m_textInfo.characterInfo[ellipsisIndex].character = (char)8230;
2537 m_textInfo.characterInfo[ellipsisIndex].textElement = m_cached_Ellipsis_GlyphInfo;
2538 m_textInfo.characterInfo[ellipsisIndex].fontAsset = m_materialReferences[0].fontAsset;
2539 m_textInfo.characterInfo[ellipsisIndex].material = m_materialReferences[0].material;
2540 m_textInfo.characterInfo[ellipsisIndex].materialReferenceIndex = 0;
2544 Debug.LogWarning(
"Unable to use Ellipsis character since it wasn't found in the current Font Asset [" + m_fontAsset.name +
"]. Consider regenerating this font asset to include the Ellipsis character (u+2026).\nNote: Warnings can be disabled in the TMP Settings file.",
this);
2547 m_totalCharacterCount = ellipsisIndex + 1;
2550 m_isTextTruncated =
true;
2558 case TextOverflowModes.Masking:
2559 if (!m_isMaskingEnabled)
2562 case TextOverflowModes.ScrollRect:
2563 if (!m_isMaskingEnabled)
2566 case TextOverflowModes.Truncate:
2567 if (m_isMaskingEnabled)
2571 if (m_lineNumber > 0)
2573 m_char_buffer[m_textInfo.characterInfo[ellipsisIndex].
index + 1] = (char)0;
2575 m_totalCharacterCount = ellipsisIndex + 1;
2578 m_isTextTruncated =
true;
2586 case TextOverflowModes.Page:
2587 if (m_isMaskingEnabled)
2591 if (charCode == 13 || charCode == 10)
2600 else if (previousPageOverflowChar == i)
2602 m_char_buffer[i] = 0;
2603 m_isTextTruncated =
true;
2606 previousPageOverflowChar = i;
2612 m_xAdvance = 0 + tag_Indent;
2619 case TextOverflowModes.Linked:
2620 if (m_linkedTextComponent !=
null)
2628 if (m_lineNumber > 0)
2630 m_char_buffer[i] = (char)0;
2632 m_totalCharacterCount = m_characterCount;
2636 m_isTextTruncated =
true;
2645 #endregion End Text Overflow 2648 #endregion Check Vertical Bounds 2652 #region XAdvance, Tabulation & Stops 2655 float tabSize = m_currentFontAsset.
fontInfo.TabWidth * currentElementScale;
2656 float tabs = Mathf.Ceil(m_xAdvance / tabSize) * tabSize;
2657 m_xAdvance = tabs > m_xAdvance ? tabs : m_xAdvance + tabSize;
2659 else if (m_monoSpacing != 0)
2661 m_xAdvance += (m_monoSpacing - monoAdvance + ((m_characterSpacing + m_currentFontAsset.normalSpacingOffset) * currentElementScale) + m_cSpacing) * (1 - m_charWidthAdjDelta);
2663 if (
char.IsWhiteSpace((
char)charCode) || charCode == 0x200B)
2664 m_xAdvance += m_wordSpacing * currentElementScale;
2666 else if (!m_isRightToLeft)
2668 float scaleFXMultiplier = 1;
2669 if (m_isFXMatrixSet) scaleFXMultiplier = m_FXMatrix.m00;
2671 m_xAdvance += ((m_cached_TextElement.xAdvance * scaleFXMultiplier * bold_xAdvance_multiplier + m_characterSpacing + m_currentFontAsset.normalSpacingOffset + glyphAdjustments.xAdvance) * currentElementScale + m_cSpacing) * (1 - m_charWidthAdjDelta);
2673 if (
char.IsWhiteSpace((
char)charCode) || charCode == 0x200B)
2674 m_xAdvance += m_wordSpacing * currentElementScale;
2678 m_xAdvance -= glyphAdjustments.xAdvance * currentElementScale;
2683 m_textInfo.characterInfo[m_characterCount].xAdvance = m_xAdvance;
2685 #endregion Tabulation & Stops 2689 #region Carriage Return 2692 m_xAdvance = 0 + tag_Indent;
2694 #endregion Carriage Return 2698 #region Check for Line Feed and Last Character 2699 if (charCode == 10 || m_characterCount == totalCharacterCount - 1)
2702 if (m_lineNumber > 0 && !TMP_Math.Approximately(m_maxLineAscender, m_startOfLineAscender) && m_lineHeight == TMP_Math.FLOAT_UNSET && !m_isNewPage)
2705 float offsetDelta = m_maxLineAscender - m_startOfLineAscender;
2707 elementDescenderII -= offsetDelta;
2708 m_lineOffset += offsetDelta;
2710 m_isNewPage =
false;
2713 float lineAscender = m_maxLineAscender - m_lineOffset;
2714 float lineDescender = m_maxLineDescender - m_lineOffset;
2717 m_maxDescender = m_maxDescender < lineDescender ? m_maxDescender : lineDescender;
2718 if (!isMaxVisibleDescenderSet)
2719 maxVisibleDescender = m_maxDescender;
2721 if (m_useMaxVisibleDescender && (m_characterCount >= m_maxVisibleCharacters || m_lineNumber >= m_maxVisibleLines))
2722 isMaxVisibleDescenderSet =
true;
2725 m_textInfo.lineInfo[m_lineNumber].firstCharacterIndex = m_firstCharacterOfLine;
2726 m_textInfo.lineInfo[m_lineNumber].firstVisibleCharacterIndex = m_firstVisibleCharacterOfLine = m_firstCharacterOfLine > m_firstVisibleCharacterOfLine ? m_firstCharacterOfLine : m_firstVisibleCharacterOfLine;
2727 m_textInfo.lineInfo[m_lineNumber].lastCharacterIndex = m_lastCharacterOfLine = m_characterCount;
2728 m_textInfo.lineInfo[m_lineNumber].lastVisibleCharacterIndex = m_lastVisibleCharacterOfLine = m_lastVisibleCharacterOfLine < m_firstVisibleCharacterOfLine ? m_firstVisibleCharacterOfLine : m_lastVisibleCharacterOfLine;
2730 m_textInfo.lineInfo[m_lineNumber].characterCount = m_textInfo.lineInfo[m_lineNumber].lastCharacterIndex - m_textInfo.lineInfo[m_lineNumber].firstCharacterIndex + 1;
2731 m_textInfo.lineInfo[m_lineNumber].visibleCharacterCount = m_lineVisibleCharacterCount;
2732 m_textInfo.lineInfo[m_lineNumber].lineExtents.min =
new Vector2(m_textInfo.characterInfo[m_firstVisibleCharacterOfLine].bottomLeft.x, lineDescender);
2733 m_textInfo.lineInfo[m_lineNumber].lineExtents.max =
new Vector2(m_textInfo.characterInfo[m_lastVisibleCharacterOfLine].topRight.x, lineAscender);
2734 m_textInfo.lineInfo[m_lineNumber].length = m_textInfo.lineInfo[m_lineNumber].lineExtents.max.x - (padding * currentElementScale);
2735 m_textInfo.lineInfo[m_lineNumber].width = width;
2737 if (m_textInfo.lineInfo[m_lineNumber].characterCount == 1)
2738 m_textInfo.lineInfo[m_lineNumber].alignment = m_lineJustification;
2740 if (m_textInfo.characterInfo[m_lastVisibleCharacterOfLine].isVisible)
2741 m_textInfo.lineInfo[m_lineNumber].maxAdvance = m_textInfo.characterInfo[m_lastVisibleCharacterOfLine].xAdvance - (m_characterSpacing + m_currentFontAsset.normalSpacingOffset) * currentElementScale - m_cSpacing;
2743 m_textInfo.lineInfo[m_lineNumber].maxAdvance = m_textInfo.characterInfo[m_lastCharacterOfLine].xAdvance - (m_characterSpacing + m_currentFontAsset.normalSpacingOffset) * currentElementScale - m_cSpacing;
2745 m_textInfo.lineInfo[m_lineNumber].baseline = 0 - m_lineOffset;
2746 m_textInfo.lineInfo[m_lineNumber].ascender = lineAscender;
2747 m_textInfo.lineInfo[m_lineNumber].descender = lineDescender;
2748 m_textInfo.lineInfo[m_lineNumber].lineHeight = lineAscender - lineDescender + lineGap * baseScale;
2750 m_firstCharacterOfLine = m_characterCount + 1;
2751 m_lineVisibleCharacterCount = 0;
2762 isStartOfNewLine =
true;
2763 ignoreNonBreakingSpace =
false;
2767 if (m_lineNumber >= m_textInfo.lineInfo.Length)
2771 if (m_lineHeight == TMP_Math.FLOAT_UNSET)
2773 lineOffsetDelta = 0 - m_maxLineDescender + elementAscender + (lineGap + m_lineSpacing + m_paragraphSpacing + m_lineSpacingDelta) * baseScale;
2774 m_lineOffset += lineOffsetDelta;
2777 m_lineOffset += m_lineHeight + (m_lineSpacing + m_paragraphSpacing) * baseScale;
2779 m_maxLineAscender = k_LargeNegativeFloat;
2780 m_maxLineDescender = k_LargePositiveFloat;
2781 m_startOfLineAscender = elementAscender;
2783 m_xAdvance = 0 + tag_LineIndent + tag_Indent;
2785 ellipsisIndex = m_characterCount - 1;
2787 m_characterCount += 1;
2791 #endregion Check for Linefeed or Last Character 2795 #region Save CharacterInfo for the current character. 2797 if (m_textInfo.characterInfo[m_characterCount].isVisible)
2799 m_meshExtents.min.x = Mathf.Min(m_meshExtents.min.x, m_textInfo.characterInfo[m_characterCount].bottomLeft.x);
2800 m_meshExtents.min.y = Mathf.Min(m_meshExtents.min.y, m_textInfo.characterInfo[m_characterCount].bottomLeft.y);
2802 m_meshExtents.max.x = Mathf.Max(m_meshExtents.max.x, m_textInfo.characterInfo[m_characterCount].topRight.x);
2803 m_meshExtents.max.y = Mathf.Max(m_meshExtents.max.y, m_textInfo.characterInfo[m_characterCount].topRight.y);
2811 if (m_overflowMode == TextOverflowModes.Page && charCode != 13 && charCode != 10)
2814 if (m_pageNumber + 1 > m_textInfo.pageInfo.Length)
2815 TMP_TextInfo.Resize(ref m_textInfo.pageInfo, m_pageNumber + 1,
true);
2817 m_textInfo.pageInfo[m_pageNumber].ascender = pageAscender;
2818 m_textInfo.pageInfo[m_pageNumber].descender = elementDescender < m_textInfo.pageInfo[m_pageNumber].descender ? elementDescender : m_textInfo.pageInfo[m_pageNumber].descender;
2820 if (m_pageNumber == 0 && m_characterCount == 0)
2821 m_textInfo.pageInfo[m_pageNumber].firstCharacterIndex = m_characterCount;
2822 else if (m_characterCount > 0 && m_pageNumber != m_textInfo.characterInfo[m_characterCount - 1].pageNumber)
2824 m_textInfo.pageInfo[m_pageNumber - 1].lastCharacterIndex = m_characterCount - 1;
2825 m_textInfo.pageInfo[m_pageNumber].firstCharacterIndex = m_characterCount;
2827 else if (m_characterCount == totalCharacterCount - 1)
2828 m_textInfo.pageInfo[m_pageNumber].lastCharacterIndex = m_characterCount;
2830 #endregion Saving CharacterInfo 2834 #region Save Word Wrapping State 2835 if (m_enableWordWrapping || m_overflowMode == TextOverflowModes.Truncate || m_overflowMode == TextOverflowModes.Ellipsis)
2837 if ((
char.IsWhiteSpace((
char)charCode) || charCode == 0x200B || charCode == 0x2D || charCode == 0xAD) && (!m_isNonBreakingSpace || ignoreNonBreakingSpace) && charCode != 0xA0 && charCode != 0x2007 && charCode != 0x2011 && charCode != 0x202F && charCode != 0x2060)
2842 m_isCharacterWrappingEnabled =
false;
2843 isFirstWord =
false;
2846 else if (( charCode > 0x1100 && charCode < 0x11ff ||
2847 charCode > 0x2E80 && charCode < 0x9FFF ||
2848 charCode > 0xA960 && charCode < 0xA97F ||
2849 charCode > 0xAC00 && charCode < 0xD7FF ||
2850 charCode > 0xF900 && charCode < 0xFAFF ||
2851 charCode > 0xFE30 && charCode < 0xFE4F ||
2852 charCode > 0xFF00 && charCode < 0xFFEF)
2853 && !m_isNonBreakingSpace)
2856 (m_characterCount < totalCharacterCount - 1 &&
2860 m_isCharacterWrappingEnabled =
false;
2861 isFirstWord =
false;
2864 else if ((isFirstWord || m_isCharacterWrappingEnabled ==
true || isLastBreakingChar))
2867 #endregion Save Word Wrapping State 2869 m_characterCount += 1;
2873 #region Check Auto-Sizing (Upper Font Size Bounds) 2874 fontSizeDelta = m_maxFontSize - m_minFontSize;
2875 if (!m_isCharacterWrappingEnabled && m_enableAutoSizing && fontSizeDelta > 0.051f && m_fontSize < m_fontSizeMax)
2877 m_minFontSize = m_fontSize;
2878 m_fontSize += Mathf.Max((m_maxFontSize - m_fontSize) / 2, 0.05f);
2879 m_fontSize = (int)(Mathf.Min(m_fontSize, m_fontSizeMax) * 20 + 0.5f) / 20f;
2883 if (loopCountA > 20)
return;
2887 #endregion End Auto-sizing Check 2890 m_isCharacterWrappingEnabled =
false;
2898 if (m_characterCount == 0)
2903 TMPro_EventManager.ON_TEXT_CHANGED(
this);
2909 int last_vert_index = m_materialReferences[0].referenceCount * (!m_isVolumetricText ? 4 : 8);
2912 m_textInfo.meshInfo[0].
Clear(
false);
2915 #region Text Vertical Alignment 2916 Vector3 anchorOffset = Vector3.zero;
2917 Vector3[] corners = m_RectTransformCorners;
2920 switch (m_textAlignment)
2923 case TextAlignmentOptions.Top:
2924 case TextAlignmentOptions.TopLeft:
2925 case TextAlignmentOptions.TopRight:
2926 case TextAlignmentOptions.TopJustified:
2927 case TextAlignmentOptions.TopFlush:
2928 case TextAlignmentOptions.TopGeoAligned:
2929 if (m_overflowMode != TextOverflowModes.Page)
2930 anchorOffset = corners[1] +
new Vector3(0 + margins.x, 0 - m_maxAscender - margins.y, 0);
2932 anchorOffset = corners[1] +
new Vector3(0 + margins.x, 0 - m_textInfo.pageInfo[
pageToDisplay].ascender - margins.y, 0);
2936 case TextAlignmentOptions.Left:
2937 case TextAlignmentOptions.Right:
2938 case TextAlignmentOptions.Center:
2939 case TextAlignmentOptions.Justified:
2940 case TextAlignmentOptions.Flush:
2941 case TextAlignmentOptions.CenterGeoAligned:
2942 if (m_overflowMode != TextOverflowModes.Page)
2943 anchorOffset = (corners[0] + corners[1]) / 2 +
new Vector3(0 + margins.x, 0 - (m_maxAscender + margins.y + maxVisibleDescender - margins.w) / 2, 0);
2945 anchorOffset = (corners[0] + corners[1]) / 2 +
new Vector3(0 + margins.x, 0 - (m_textInfo.pageInfo[
pageToDisplay].ascender + margins.y + m_textInfo.pageInfo[
pageToDisplay].descender - margins.w) / 2, 0);
2949 case TextAlignmentOptions.Bottom:
2950 case TextAlignmentOptions.BottomLeft:
2951 case TextAlignmentOptions.BottomRight:
2952 case TextAlignmentOptions.BottomJustified:
2953 case TextAlignmentOptions.BottomFlush:
2954 case TextAlignmentOptions.BottomGeoAligned:
2955 if (m_overflowMode != TextOverflowModes.Page)
2956 anchorOffset = corners[0] +
new Vector3(0 + margins.x, 0 - maxVisibleDescender + margins.w, 0);
2958 anchorOffset = corners[0] +
new Vector3(0 + margins.x, 0 - m_textInfo.pageInfo[
pageToDisplay].descender + margins.w, 0);
2962 case TextAlignmentOptions.Baseline:
2963 case TextAlignmentOptions.BaselineLeft:
2964 case TextAlignmentOptions.BaselineRight:
2965 case TextAlignmentOptions.BaselineJustified:
2966 case TextAlignmentOptions.BaselineFlush:
2967 case TextAlignmentOptions.BaselineGeoAligned:
2968 anchorOffset = (corners[0] + corners[1]) / 2 +
new Vector3(0 + margins.x, 0, 0);
2972 case TextAlignmentOptions.MidlineLeft:
2973 case TextAlignmentOptions.Midline:
2974 case TextAlignmentOptions.MidlineRight:
2975 case TextAlignmentOptions.MidlineJustified:
2976 case TextAlignmentOptions.MidlineFlush:
2977 case TextAlignmentOptions.MidlineGeoAligned:
2978 anchorOffset = (corners[0] + corners[1]) / 2 +
new Vector3(0 + margins.x, 0 - (m_meshExtents.max.y + margins.y + m_meshExtents.min.y - margins.w) / 2, 0);
2982 case TextAlignmentOptions.CaplineLeft:
2983 case TextAlignmentOptions.Capline:
2984 case TextAlignmentOptions.CaplineRight:
2985 case TextAlignmentOptions.CaplineJustified:
2986 case TextAlignmentOptions.CaplineFlush:
2987 case TextAlignmentOptions.CaplineGeoAligned:
2988 anchorOffset = (corners[0] + corners[1]) / 2 +
new Vector3(0 + margins.x, 0 - (m_maxCapHeight - margins.y - margins.w) / 2, 0);
2995 Vector3 justificationOffset = Vector3.zero;
2996 Vector3 offset = Vector3.zero;
2997 int vert_index_X4 = 0;
2998 int sprite_index_X4 = 0;
3003 bool isFirstSeperator =
false;
3005 bool isStartOfWord =
false;
3006 int wordFirstChar = 0;
3007 int wordLastChar = 0;
3010 float lossyScale = m_previousLossyScaleY = this.
transform.lossyScale.y;
3012 Color32 underlineColor = Color.white;
3013 Color32 strikethroughColor = Color.white;
3014 Color32 highlightColor =
new Color32(255, 255, 0, 64);
3016 float underlineStartScale = 0;
3017 float underlineEndScale = 0;
3018 float underlineMaxScale = 0;
3019 float underlineBaseLine = k_LargePositiveFloat;
3022 float strikethroughPointSize = 0;
3023 float strikethroughScale = 0;
3024 float strikethroughBaseline = 0;
3027 #region Handle Line Justification & UV Mapping & Character Visibility & More 3028 for (
int i = 0; i < m_characterCount; i++)
3030 TMP_FontAsset currentFontAsset = characterInfos[i].fontAsset;
3032 char currentCharacter = characterInfos[i].character;
3034 int currentLine = characterInfos[i].lineNumber;
3035 TMP_LineInfo lineInfo = m_textInfo.lineInfo[currentLine];
3036 lineCount = currentLine + 1;
3038 TextAlignmentOptions lineAlignment = lineInfo.alignment;
3041 #region Handle Line Justification 3042 switch (lineAlignment)
3044 case TextAlignmentOptions.TopLeft:
3045 case TextAlignmentOptions.Left:
3046 case TextAlignmentOptions.BottomLeft:
3047 case TextAlignmentOptions.BaselineLeft:
3048 case TextAlignmentOptions.MidlineLeft:
3049 case TextAlignmentOptions.CaplineLeft:
3050 if (!m_isRightToLeft)
3051 justificationOffset =
new Vector3(0 + lineInfo.marginLeft, 0, 0);
3053 justificationOffset =
new Vector3(0 - lineInfo.maxAdvance, 0, 0);
3056 case TextAlignmentOptions.Top:
3057 case TextAlignmentOptions.Center:
3058 case TextAlignmentOptions.Bottom:
3059 case TextAlignmentOptions.Baseline:
3060 case TextAlignmentOptions.Midline:
3061 case TextAlignmentOptions.Capline:
3062 justificationOffset =
new Vector3(lineInfo.marginLeft + lineInfo.width / 2 - lineInfo.maxAdvance / 2, 0, 0);
3065 case TextAlignmentOptions.TopGeoAligned:
3066 case TextAlignmentOptions.CenterGeoAligned:
3067 case TextAlignmentOptions.BottomGeoAligned:
3068 case TextAlignmentOptions.BaselineGeoAligned:
3069 case TextAlignmentOptions.MidlineGeoAligned:
3070 case TextAlignmentOptions.CaplineGeoAligned:
3071 justificationOffset =
new Vector3(lineInfo.marginLeft + lineInfo.width / 2 - (lineInfo.lineExtents.min.x + lineInfo.lineExtents.max.x) / 2, 0, 0);
3074 case TextAlignmentOptions.TopRight:
3075 case TextAlignmentOptions.Right:
3076 case TextAlignmentOptions.BottomRight:
3077 case TextAlignmentOptions.BaselineRight:
3078 case TextAlignmentOptions.MidlineRight:
3079 case TextAlignmentOptions.CaplineRight:
3080 if (!m_isRightToLeft)
3081 justificationOffset =
new Vector3(lineInfo.marginLeft + lineInfo.width - lineInfo.maxAdvance, 0, 0);
3083 justificationOffset =
new Vector3(lineInfo.marginLeft + lineInfo.width, 0, 0);
3086 case TextAlignmentOptions.TopJustified:
3087 case TextAlignmentOptions.Justified:
3088 case TextAlignmentOptions.BottomJustified:
3089 case TextAlignmentOptions.BaselineJustified:
3090 case TextAlignmentOptions.MidlineJustified:
3091 case TextAlignmentOptions.CaplineJustified:
3092 case TextAlignmentOptions.TopFlush:
3093 case TextAlignmentOptions.Flush:
3094 case TextAlignmentOptions.BottomFlush:
3095 case TextAlignmentOptions.BaselineFlush:
3096 case TextAlignmentOptions.MidlineFlush:
3097 case TextAlignmentOptions.CaplineFlush:
3099 if (currentCharacter == 0xAD || currentCharacter == 0x200B || currentCharacter == 0x2060)
break;
3101 char lastCharOfCurrentLine = characterInfos[lineInfo.lastCharacterIndex].character;
3106 if (
char.IsControl(lastCharOfCurrentLine) ==
false && currentLine < m_lineNumber || isFlush || lineInfo.maxAdvance > lineInfo.width)
3109 if (currentLine != lastLine || i == 0 || i == m_firstVisibleCharacter)
3111 if (!m_isRightToLeft)
3112 justificationOffset =
new Vector3(lineInfo.marginLeft, 0, 0);
3114 justificationOffset =
new Vector3(lineInfo.marginLeft + lineInfo.width, 0, 0);
3116 if (
char.IsSeparator(currentCharacter))
3117 isFirstSeperator =
true;
3119 isFirstSeperator =
false;
3123 float gap = !m_isRightToLeft ? lineInfo.width - lineInfo.maxAdvance : lineInfo.width + lineInfo.maxAdvance;
3125 int visibleCount = lineInfo.visibleCharacterCount - 1 + lineInfo.controlCharacterCount;
3128 int spaces = (characterInfos[lineInfo.lastCharacterIndex].isVisible ? lineInfo.spaceCount : lineInfo.spaceCount - 1) - lineInfo.controlCharacterCount;
3130 if (isFirstSeperator) { spaces -= 1; visibleCount += 1; }
3132 float ratio = spaces > 0 ? m_wordWrappingRatios : 1;
3134 if (spaces < 1) spaces = 1;
3136 if (currentCharacter != 0xA0 && (currentCharacter == 9 ||
char.IsSeparator((
char)currentCharacter)))
3138 if (!m_isRightToLeft)
3139 justificationOffset +=
new Vector3(gap * (1 - ratio) / spaces, 0, 0);
3141 justificationOffset -=
new Vector3(gap * (1 - ratio) / spaces, 0, 0);
3145 if (!m_isRightToLeft)
3146 justificationOffset +=
new Vector3(gap * ratio / visibleCount, 0, 0);
3148 justificationOffset -=
new Vector3(gap * ratio / visibleCount, 0, 0);
3154 if (!m_isRightToLeft)
3155 justificationOffset =
new Vector3(lineInfo.marginLeft, 0, 0);
3157 justificationOffset =
new Vector3(lineInfo.marginLeft + lineInfo.width, 0, 0);
3162 #endregion End Text Justification 3164 offset = anchorOffset + justificationOffset;
3167 #region Handling of UV2 mapping & Scale packing 3168 bool isCharacterVisible = characterInfos[i].isVisible;
3169 if (isCharacterVisible)
3171 TMP_TextElementType elementType = characterInfos[i].elementType;
3172 switch (elementType)
3175 case TMP_TextElementType.Character:
3176 Extents lineExtents = lineInfo.lineExtents;
3177 float uvOffset = (m_uvLineOffset * currentLine) % 1;
3180 #region Handle UV Mapping Options 3181 switch (m_horizontalMapping)
3183 case TextureMappingOptions.Character:
3184 characterInfos[i].vertex_BL.uv2.x = 0;
3185 characterInfos[i].vertex_TL.uv2.x = 0;
3186 characterInfos[i].vertex_TR.uv2.x = 1;
3187 characterInfos[i].vertex_BR.uv2.x = 1;
3190 case TextureMappingOptions.Line:
3191 if (m_textAlignment != TextAlignmentOptions.Justified)
3193 characterInfos[i].vertex_BL.uv2.x = (characterInfos[i].vertex_BL.position.x - lineExtents.min.x) / (lineExtents.max.x - lineExtents.min.x) + uvOffset;
3194 characterInfos[i].vertex_TL.uv2.x = (characterInfos[i].vertex_TL.position.x - lineExtents.min.x) / (lineExtents.max.x - lineExtents.min.x) + uvOffset;
3195 characterInfos[i].vertex_TR.uv2.x = (characterInfos[i].vertex_TR.position.x - lineExtents.min.x) / (lineExtents.max.x - lineExtents.min.x) + uvOffset;
3196 characterInfos[i].vertex_BR.uv2.x = (characterInfos[i].vertex_BR.position.x - lineExtents.min.x) / (lineExtents.max.x - lineExtents.min.x) + uvOffset;
3201 characterInfos[i].vertex_BL.uv2.x = (characterInfos[i].vertex_BL.position.x + justificationOffset.x - m_meshExtents.min.x) / (m_meshExtents.max.x - m_meshExtents.min.x) + uvOffset;
3202 characterInfos[i].vertex_TL.uv2.x = (characterInfos[i].vertex_TL.position.x + justificationOffset.x - m_meshExtents.min.x) / (m_meshExtents.max.x - m_meshExtents.min.x) + uvOffset;
3203 characterInfos[i].vertex_TR.uv2.x = (characterInfos[i].vertex_TR.position.x + justificationOffset.x - m_meshExtents.min.x) / (m_meshExtents.max.x - m_meshExtents.min.x) + uvOffset;
3204 characterInfos[i].vertex_BR.uv2.x = (characterInfos[i].vertex_BR.position.x + justificationOffset.x - m_meshExtents.min.x) / (m_meshExtents.max.x - m_meshExtents.min.x) + uvOffset;
3208 case TextureMappingOptions.Paragraph:
3209 characterInfos[i].vertex_BL.uv2.x = (characterInfos[i].vertex_BL.position.x + justificationOffset.x - m_meshExtents.min.x) / (m_meshExtents.max.x - m_meshExtents.min.x) + uvOffset;
3210 characterInfos[i].vertex_TL.uv2.x = (characterInfos[i].vertex_TL.position.x + justificationOffset.x - m_meshExtents.min.x) / (m_meshExtents.max.x - m_meshExtents.min.x) + uvOffset;
3211 characterInfos[i].vertex_TR.uv2.x = (characterInfos[i].vertex_TR.position.x + justificationOffset.x - m_meshExtents.min.x) / (m_meshExtents.max.x - m_meshExtents.min.x) + uvOffset;
3212 characterInfos[i].vertex_BR.uv2.x = (characterInfos[i].vertex_BR.position.x + justificationOffset.x - m_meshExtents.min.x) / (m_meshExtents.max.x - m_meshExtents.min.x) + uvOffset;
3215 case TextureMappingOptions.MatchAspect:
3217 switch (m_verticalMapping)
3219 case TextureMappingOptions.Character:
3220 characterInfos[i].vertex_BL.uv2.y = 0;
3221 characterInfos[i].vertex_TL.uv2.y = 1;
3222 characterInfos[i].vertex_TR.uv2.y = 0;
3223 characterInfos[i].vertex_BR.uv2.y = 1;
3226 case TextureMappingOptions.Line:
3227 characterInfos[i].vertex_BL.uv2.y = (characterInfos[i].vertex_BL.position.y - lineExtents.min.y) / (lineExtents.max.y - lineExtents.min.y) + uvOffset;
3228 characterInfos[i].vertex_TL.uv2.y = (characterInfos[i].vertex_TL.position.y - lineExtents.min.y) / (lineExtents.max.y - lineExtents.min.y) + uvOffset;
3229 characterInfos[i].vertex_TR.uv2.y = characterInfos[i].vertex_BL.uv2.y;
3230 characterInfos[i].vertex_BR.uv2.y = characterInfos[i].vertex_TL.uv2.y;
3233 case TextureMappingOptions.Paragraph:
3234 characterInfos[i].vertex_BL.uv2.y = (characterInfos[i].vertex_BL.position.y - m_meshExtents.min.y) / (m_meshExtents.max.y - m_meshExtents.min.y) + uvOffset;
3235 characterInfos[i].vertex_TL.uv2.y = (characterInfos[i].vertex_TL.position.y - m_meshExtents.min.y) / (m_meshExtents.max.y - m_meshExtents.min.y) + uvOffset;
3236 characterInfos[i].vertex_TR.uv2.y = characterInfos[i].vertex_BL.uv2.y;
3237 characterInfos[i].vertex_BR.uv2.y = characterInfos[i].vertex_TL.uv2.y;
3240 case TextureMappingOptions.MatchAspect:
3241 Debug.Log(
"ERROR: Cannot Match both Vertical & Horizontal.");
3246 float xDelta = (1 - ((characterInfos[i].vertex_BL.uv2.y + characterInfos[i].vertex_TL.uv2.y) * characterInfos[i].aspectRatio)) / 2;
3248 characterInfos[i].vertex_BL.uv2.x = (characterInfos[i].vertex_BL.uv2.y * characterInfos[i].aspectRatio) + xDelta + uvOffset;
3249 characterInfos[i].vertex_TL.uv2.x = characterInfos[i].vertex_BL.uv2.x;
3250 characterInfos[i].vertex_TR.uv2.x = (characterInfos[i].vertex_TL.uv2.y * characterInfos[i].aspectRatio) + xDelta + uvOffset;
3251 characterInfos[i].vertex_BR.uv2.x = characterInfos[i].vertex_TR.uv2.x;
3255 switch (m_verticalMapping)
3257 case TextureMappingOptions.Character:
3258 characterInfos[i].vertex_BL.uv2.y = 0;
3259 characterInfos[i].vertex_TL.uv2.y = 1;
3260 characterInfos[i].vertex_TR.uv2.y = 1;
3261 characterInfos[i].vertex_BR.uv2.y = 0;
3264 case TextureMappingOptions.Line:
3265 characterInfos[i].vertex_BL.uv2.y = (characterInfos[i].vertex_BL.position.y - lineInfo.descender) / (lineInfo.ascender - lineInfo.descender);
3266 characterInfos[i].vertex_TL.uv2.y = (characterInfos[i].vertex_TL.position.y - lineInfo.descender) / (lineInfo.ascender - lineInfo.descender);
3267 characterInfos[i].vertex_TR.uv2.y = characterInfos[i].vertex_TL.uv2.y;
3268 characterInfos[i].vertex_BR.uv2.y = characterInfos[i].vertex_BL.uv2.y;
3271 case TextureMappingOptions.Paragraph:
3272 characterInfos[i].vertex_BL.uv2.y = (characterInfos[i].vertex_BL.position.y - m_meshExtents.min.y) / (m_meshExtents.max.y - m_meshExtents.min.y);
3273 characterInfos[i].vertex_TL.uv2.y = (characterInfos[i].vertex_TL.position.y - m_meshExtents.min.y) / (m_meshExtents.max.y - m_meshExtents.min.y);
3274 characterInfos[i].vertex_TR.uv2.y = characterInfos[i].vertex_TL.uv2.y;
3275 characterInfos[i].vertex_BR.uv2.y = characterInfos[i].vertex_BL.uv2.y;
3278 case TextureMappingOptions.MatchAspect:
3279 float yDelta = (1 - ((characterInfos[i].vertex_BL.uv2.x + characterInfos[i].vertex_TR.uv2.x) / characterInfos[i].aspectRatio)) / 2;
3281 characterInfos[i].vertex_BL.uv2.y = yDelta + (characterInfos[i].vertex_BL.uv2.x / characterInfos[i].aspectRatio);
3282 characterInfos[i].vertex_TL.uv2.y = yDelta + (characterInfos[i].vertex_TR.uv2.x / characterInfos[i].aspectRatio);
3283 characterInfos[i].vertex_BR.uv2.y = characterInfos[i].vertex_BL.uv2.y;
3284 characterInfos[i].vertex_TR.uv2.y = characterInfos[i].vertex_TL.uv2.y;
3290 #region Pack Scale into UV2 3291 xScale = characterInfos[i].scale * lossyScale * (1 - m_charWidthAdjDelta);
3292 if (!characterInfos[i].isUsingAlternateTypeface && (characterInfos[i].style & FontStyles.Bold) == FontStyles.Bold) xScale *= -1;
3301 float x0 = characterInfos[i].vertex_BL.uv2.x;
3302 float y0 = characterInfos[i].vertex_BL.uv2.y;
3303 float x1 = characterInfos[i].vertex_TR.uv2.x;
3304 float y1 = characterInfos[i].vertex_TR.uv2.y;
3315 characterInfos[i].vertex_BL.uv2.x =
PackUV(x0, y0); characterInfos[i].vertex_BL.uv2.y = xScale;
3316 characterInfos[i].vertex_TL.uv2.x =
PackUV(x0, y1); characterInfos[i].vertex_TL.uv2.y = xScale;
3317 characterInfos[i].vertex_TR.uv2.x =
PackUV(x1, y1); characterInfos[i].vertex_TR.uv2.y = xScale;
3318 characterInfos[i].vertex_BR.uv2.x =
PackUV(x1, y0); characterInfos[i].vertex_BR.uv2.y = xScale;
3323 case TMP_TextElementType.Sprite:
3329 #region Handle maxVisibleCharacters / maxVisibleLines / Page Mode 3330 if (i < m_maxVisibleCharacters && wordCount < m_maxVisibleWords && currentLine < m_maxVisibleLines && m_overflowMode != TextOverflowModes.Page)
3332 characterInfos[i].vertex_BL.position += offset;
3333 characterInfos[i].vertex_TL.position += offset;
3334 characterInfos[i].vertex_TR.position += offset;
3335 characterInfos[i].vertex_BR.position += offset;
3337 else if (i < m_maxVisibleCharacters && wordCount < m_maxVisibleWords && currentLine < m_maxVisibleLines && m_overflowMode == TextOverflowModes.Page && characterInfos[i].pageNumber ==
pageToDisplay)
3339 characterInfos[i].vertex_BL.position += offset;
3340 characterInfos[i].vertex_TL.position += offset;
3341 characterInfos[i].vertex_TR.position += offset;
3342 characterInfos[i].vertex_BR.position += offset;
3346 characterInfos[i].vertex_BL.position = Vector3.zero;
3347 characterInfos[i].vertex_TL.position = Vector3.zero;
3348 characterInfos[i].vertex_TR.position = Vector3.zero;
3349 characterInfos[i].vertex_BR.position = Vector3.zero;
3350 characterInfos[i].isVisible =
false;
3356 if (elementType == TMP_TextElementType.Character)
3360 else if (elementType == TMP_TextElementType.Sprite)
3368 m_textInfo.characterInfo[i].bottomLeft += offset;
3369 m_textInfo.characterInfo[i].topLeft += offset;
3370 m_textInfo.characterInfo[i].topRight += offset;
3371 m_textInfo.characterInfo[i].bottomRight += offset;
3373 m_textInfo.characterInfo[i].origin += offset.x;
3374 m_textInfo.characterInfo[i].xAdvance += offset.x;
3376 m_textInfo.characterInfo[i].ascender += offset.y;
3377 m_textInfo.characterInfo[i].descender += offset.y;
3378 m_textInfo.characterInfo[i].baseLine += offset.y;
3381 if (isCharacterVisible)
3388 #region Adjust lineExtents resulting from alignment offset 3389 if (currentLine != lastLine || i == m_characterCount - 1)
3392 if (currentLine != lastLine)
3394 m_textInfo.lineInfo[lastLine].baseline += offset.y;
3395 m_textInfo.lineInfo[lastLine].ascender += offset.y;
3396 m_textInfo.lineInfo[lastLine].descender += offset.y;
3398 m_textInfo.lineInfo[lastLine].lineExtents.min =
new Vector2(m_textInfo.characterInfo[m_textInfo.lineInfo[lastLine].firstCharacterIndex].bottomLeft.x, m_textInfo.lineInfo[lastLine].descender);
3399 m_textInfo.lineInfo[lastLine].lineExtents.max =
new Vector2(m_textInfo.characterInfo[m_textInfo.lineInfo[lastLine].lastVisibleCharacterIndex].topRight.x, m_textInfo.lineInfo[lastLine].ascender);
3403 if (i == m_characterCount - 1)
3405 m_textInfo.lineInfo[currentLine].baseline += offset.y;
3406 m_textInfo.lineInfo[currentLine].ascender += offset.y;
3407 m_textInfo.lineInfo[currentLine].descender += offset.y;
3409 m_textInfo.lineInfo[currentLine].lineExtents.min =
new Vector2(m_textInfo.characterInfo[m_textInfo.lineInfo[currentLine].firstCharacterIndex].bottomLeft.x, m_textInfo.lineInfo[currentLine].descender);
3410 m_textInfo.lineInfo[currentLine].lineExtents.max =
new Vector2(m_textInfo.characterInfo[m_textInfo.lineInfo[currentLine].lastVisibleCharacterIndex].topRight.x, m_textInfo.lineInfo[currentLine].ascender);
3417 #region Track Word Count 3418 if (
char.IsLetterOrDigit(currentCharacter) || currentCharacter == 0x2D || currentCharacter == 0xAD || currentCharacter == 0x2010 || currentCharacter == 0x2011)
3420 if (isStartOfWord ==
false)
3422 isStartOfWord =
true;
3427 if (isStartOfWord && i == m_characterCount - 1)
3429 int size = m_textInfo.wordInfo.Length;
3430 int index = m_textInfo.wordCount;
3432 if (m_textInfo.wordCount + 1 > size)
3433 TMP_TextInfo.Resize(ref m_textInfo.wordInfo, size + 1);
3437 m_textInfo.wordInfo[index].firstCharacterIndex = wordFirstChar;
3438 m_textInfo.wordInfo[index].lastCharacterIndex = wordLastChar;
3439 m_textInfo.wordInfo[index].characterCount = wordLastChar - wordFirstChar + 1;
3440 m_textInfo.wordInfo[index].textComponent =
this;
3443 m_textInfo.wordCount += 1;
3444 m_textInfo.lineInfo[currentLine].wordCount += 1;
3447 else if (isStartOfWord || i == 0 && (!
char.IsPunctuation(currentCharacter) ||
char.IsWhiteSpace(currentCharacter) || currentCharacter == 0x200B || i == m_characterCount - 1))
3449 if (i > 0 && i < characterInfos.Length - 1 && i < m_characterCount && (currentCharacter == 39 || currentCharacter == 8217) &&
char.IsLetterOrDigit(characterInfos[i - 1].character) &&
char.IsLetterOrDigit(characterInfos[i + 1].character))
3455 wordLastChar = i == m_characterCount - 1 &&
char.IsLetterOrDigit(currentCharacter) ? i : i - 1;
3456 isStartOfWord =
false;
3458 int size = m_textInfo.wordInfo.Length;
3459 int index = m_textInfo.wordCount;
3461 if (m_textInfo.wordCount + 1 > size)
3462 TMP_TextInfo.Resize(ref m_textInfo.wordInfo, size + 1);
3464 m_textInfo.wordInfo[index].firstCharacterIndex = wordFirstChar;
3465 m_textInfo.wordInfo[index].lastCharacterIndex = wordLastChar;
3466 m_textInfo.wordInfo[index].characterCount = wordLastChar - wordFirstChar + 1;
3467 m_textInfo.wordInfo[index].textComponent =
this;
3470 m_textInfo.wordCount += 1;
3471 m_textInfo.lineInfo[currentLine].wordCount += 1;
3480 bool isUnderline = (m_textInfo.characterInfo[i].style & FontStyles.Underline) == FontStyles.Underline;
3483 bool isUnderlineVisible =
true;
3484 int currentPage = m_textInfo.characterInfo[i].pageNumber;
3486 if (i > m_maxVisibleCharacters || currentLine > m_maxVisibleLines || (m_overflowMode == TextOverflowModes.Page && currentPage + 1 != m_pageToDisplay))
3487 isUnderlineVisible =
false;
3490 if (!
char.IsWhiteSpace(currentCharacter) && currentCharacter != 0x200B)
3492 underlineMaxScale = Mathf.Max(underlineMaxScale, m_textInfo.characterInfo[i].scale);
3493 underlineBaseLine = Mathf.Min(currentPage == lastPage ? underlineBaseLine : k_LargePositiveFloat, m_textInfo.characterInfo[i].baseLine +
font.
fontInfo.Underline * underlineMaxScale);
3494 lastPage = currentPage;
3497 if (beginUnderline ==
false && isUnderlineVisible ==
true && i <= lineInfo.lastVisibleCharacterIndex && currentCharacter != 10 && currentCharacter != 13)
3499 if (i == lineInfo.lastVisibleCharacterIndex &&
char.IsSeparator(currentCharacter))
3503 beginUnderline =
true;
3504 underlineStartScale = m_textInfo.characterInfo[i].scale;
3505 if (underlineMaxScale == 0) underlineMaxScale = underlineStartScale;
3506 underline_start =
new Vector3(m_textInfo.characterInfo[i].bottomLeft.x, underlineBaseLine, 0);
3507 underlineColor = m_textInfo.characterInfo[i].underlineColor;
3512 if (beginUnderline && m_characterCount == 1)
3514 beginUnderline =
false;
3515 underline_end =
new Vector3(m_textInfo.characterInfo[i].topRight.x, underlineBaseLine, 0);
3516 underlineEndScale = m_textInfo.characterInfo[i].scale;
3518 DrawUnderlineMesh(underline_start, underline_end, ref last_vert_index, underlineStartScale, underlineEndScale, underlineMaxScale, xScale, underlineColor);
3519 underlineMaxScale = 0;
3520 underlineBaseLine = k_LargePositiveFloat;
3522 else if (beginUnderline && (i == lineInfo.lastCharacterIndex || i >= lineInfo.lastVisibleCharacterIndex))
3525 if (
char.IsWhiteSpace(currentCharacter) || currentCharacter == 0x200B)
3527 int lastVisibleCharacterIndex = lineInfo.lastVisibleCharacterIndex;
3528 underline_end =
new Vector3(m_textInfo.characterInfo[lastVisibleCharacterIndex].topRight.x, underlineBaseLine, 0);
3529 underlineEndScale = m_textInfo.characterInfo[lastVisibleCharacterIndex].scale;
3533 underline_end =
new Vector3(m_textInfo.characterInfo[i].topRight.x, underlineBaseLine, 0);
3534 underlineEndScale = m_textInfo.characterInfo[i].scale;
3537 beginUnderline =
false;
3538 DrawUnderlineMesh(underline_start, underline_end, ref last_vert_index, underlineStartScale, underlineEndScale, underlineMaxScale, xScale, underlineColor);
3539 underlineMaxScale = 0;
3540 underlineBaseLine = k_LargePositiveFloat;
3542 else if (beginUnderline && !isUnderlineVisible)
3544 beginUnderline =
false;
3545 underline_end =
new Vector3(m_textInfo.characterInfo[i - 1].topRight.x, underlineBaseLine, 0);
3546 underlineEndScale = m_textInfo.characterInfo[i - 1].scale;
3548 DrawUnderlineMesh(underline_start, underline_end, ref last_vert_index, underlineStartScale, underlineEndScale, underlineMaxScale, xScale, underlineColor);
3549 underlineMaxScale = 0;
3550 underlineBaseLine = k_LargePositiveFloat;
3552 else if (beginUnderline && i < m_characterCount - 1 && !underlineColor.Compare(m_textInfo.characterInfo[i + 1].underlineColor))
3555 beginUnderline =
false;
3556 underline_end =
new Vector3(m_textInfo.characterInfo[i].topRight.x, underlineBaseLine, 0);
3557 underlineEndScale = m_textInfo.characterInfo[i].scale;
3559 DrawUnderlineMesh(underline_start, underline_end, ref last_vert_index, underlineStartScale, underlineEndScale, underlineMaxScale, xScale, underlineColor);
3560 underlineMaxScale = 0;
3561 underlineBaseLine = k_LargePositiveFloat;
3567 if (beginUnderline ==
true)
3569 beginUnderline =
false;
3570 underline_end =
new Vector3(m_textInfo.characterInfo[i - 1].topRight.x, underlineBaseLine, 0);
3571 underlineEndScale = m_textInfo.characterInfo[i - 1].scale;
3573 DrawUnderlineMesh(underline_start, underline_end, ref last_vert_index, underlineStartScale, underlineEndScale, underlineMaxScale, xScale, underlineColor);
3574 underlineMaxScale = 0;
3575 underlineBaseLine = k_LargePositiveFloat;
3582 #region Strikethrough 3584 bool isStrikethrough = (m_textInfo.characterInfo[i].style & FontStyles.Strikethrough) == FontStyles.Strikethrough;
3585 float strikethroughOffset = currentFontAsset.
fontInfo.strikethrough;
3587 if (isStrikethrough)
3589 bool isStrikeThroughVisible =
true;
3591 if (i > m_maxVisibleCharacters || currentLine > m_maxVisibleLines || (m_overflowMode == TextOverflowModes.Page && m_textInfo.characterInfo[i].pageNumber + 1 != m_pageToDisplay))
3592 isStrikeThroughVisible =
false;
3594 if (beginStrikethrough ==
false && isStrikeThroughVisible && i <= lineInfo.lastVisibleCharacterIndex && currentCharacter != 10 && currentCharacter != 13)
3596 if (i == lineInfo.lastVisibleCharacterIndex &&
char.IsSeparator(currentCharacter))
3600 beginStrikethrough =
true;
3601 strikethroughPointSize = m_textInfo.characterInfo[i].pointSize;
3602 strikethroughScale = m_textInfo.characterInfo[i].scale;
3603 strikethrough_start =
new Vector3(m_textInfo.characterInfo[i].bottomLeft.x, m_textInfo.characterInfo[i].baseLine + strikethroughOffset * strikethroughScale, 0);
3604 strikethroughColor = m_textInfo.characterInfo[i].strikethroughColor;
3605 strikethroughBaseline = m_textInfo.characterInfo[i].baseLine;
3611 if (beginStrikethrough && m_characterCount == 1)
3613 beginStrikethrough =
false;
3614 strikethrough_end =
new Vector3(m_textInfo.characterInfo[i].topRight.x, m_textInfo.characterInfo[i].baseLine + strikethroughOffset * strikethroughScale, 0);
3616 DrawUnderlineMesh(strikethrough_start, strikethrough_end, ref last_vert_index, strikethroughScale, strikethroughScale, strikethroughScale, xScale, strikethroughColor);
3618 else if (beginStrikethrough && i == lineInfo.lastCharacterIndex)
3621 if (
char.IsWhiteSpace(currentCharacter) || currentCharacter == 0x200B)
3623 int lastVisibleCharacterIndex = lineInfo.lastVisibleCharacterIndex;
3624 strikethrough_end =
new Vector3(m_textInfo.characterInfo[lastVisibleCharacterIndex].topRight.x, m_textInfo.characterInfo[lastVisibleCharacterIndex].baseLine + strikethroughOffset * strikethroughScale, 0);
3629 strikethrough_end =
new Vector3(m_textInfo.characterInfo[i].topRight.x, m_textInfo.characterInfo[i].baseLine + strikethroughOffset * strikethroughScale, 0);
3632 beginStrikethrough =
false;
3633 DrawUnderlineMesh(strikethrough_start, strikethrough_end, ref last_vert_index, strikethroughScale, strikethroughScale, strikethroughScale, xScale, strikethroughColor);
3635 else if (beginStrikethrough && i < m_characterCount && (m_textInfo.characterInfo[i + 1].pointSize != strikethroughPointSize || !TMP_Math.Approximately(m_textInfo.characterInfo[i + 1].baseLine + offset.y, strikethroughBaseline)))
3638 beginStrikethrough =
false;
3640 int lastVisibleCharacterIndex = lineInfo.lastVisibleCharacterIndex;
3641 if (i > lastVisibleCharacterIndex)
3642 strikethrough_end =
new Vector3(m_textInfo.characterInfo[lastVisibleCharacterIndex].topRight.x, m_textInfo.characterInfo[lastVisibleCharacterIndex].baseLine + strikethroughOffset * strikethroughScale, 0);
3644 strikethrough_end =
new Vector3(m_textInfo.characterInfo[i].topRight.x, m_textInfo.characterInfo[i].baseLine + strikethroughOffset * strikethroughScale, 0);
3646 DrawUnderlineMesh(strikethrough_start, strikethrough_end, ref last_vert_index, strikethroughScale, strikethroughScale, strikethroughScale, xScale, strikethroughColor);
3649 else if (beginStrikethrough && i < m_characterCount && currentFontAsset.GetInstanceID() != characterInfos[i + 1].fontAsset.GetInstanceID())
3652 beginStrikethrough =
false;
3653 strikethrough_end =
new Vector3(m_textInfo.characterInfo[i].topRight.x, m_textInfo.characterInfo[i].baseLine + strikethroughOffset * strikethroughScale, 0);
3655 DrawUnderlineMesh(strikethrough_start, strikethrough_end, ref last_vert_index, strikethroughScale, strikethroughScale, strikethroughScale, xScale, strikethroughColor);
3657 else if (beginStrikethrough && !isStrikeThroughVisible)
3660 beginStrikethrough =
false;
3661 strikethrough_end =
new Vector3(m_textInfo.characterInfo[i - 1].topRight.x, m_textInfo.characterInfo[i - 1].baseLine + strikethroughOffset * strikethroughScale, 0);
3663 DrawUnderlineMesh(strikethrough_start, strikethrough_end, ref last_vert_index, strikethroughScale, strikethroughScale, strikethroughScale, xScale, strikethroughColor);
3669 if (beginStrikethrough ==
true)
3671 beginStrikethrough =
false;
3672 strikethrough_end =
new Vector3(m_textInfo.characterInfo[i - 1].topRight.x, m_textInfo.characterInfo[i - 1].baseLine + strikethroughOffset * strikethroughScale, 0);
3674 DrawUnderlineMesh(strikethrough_start, strikethrough_end, ref last_vert_index, strikethroughScale, strikethroughScale, strikethroughScale, xScale, strikethroughColor);
3681 #region Text Highlighting 3682 bool isHighlight = (m_textInfo.characterInfo[i].style & FontStyles.Highlight) == FontStyles.Highlight;
3685 bool isHighlightVisible =
true;
3686 int currentPage = m_textInfo.characterInfo[i].pageNumber;
3688 if (i > m_maxVisibleCharacters || currentLine > m_maxVisibleLines || (m_overflowMode == TextOverflowModes.Page && currentPage + 1 != m_pageToDisplay))
3689 isHighlightVisible =
false;
3691 if (beginHighlight ==
false && isHighlightVisible ==
true && i <= lineInfo.lastVisibleCharacterIndex && currentCharacter != 10 && currentCharacter != 13)
3693 if (i == lineInfo.lastVisibleCharacterIndex &&
char.IsSeparator(currentCharacter))
3697 beginHighlight =
true;
3698 highlight_start = k_LargePositiveVector2;
3699 highlight_end = k_LargeNegativeVector2;
3700 highlightColor = m_textInfo.characterInfo[i].highlightColor;
3706 Color32 currentHighlightColor = m_textInfo.characterInfo[i].highlightColor;
3707 bool isColorTransition =
false;
3710 if (!highlightColor.Compare(currentHighlightColor))
3713 highlight_end.x = (highlight_end.x + m_textInfo.characterInfo[i].bottomLeft.x) / 2;
3715 highlight_start.y = Mathf.Min(highlight_start.y, m_textInfo.characterInfo[i].descender);
3716 highlight_end.y = Mathf.Max(highlight_end.y, m_textInfo.characterInfo[i].ascender);
3718 DrawTextHighlight(highlight_start, highlight_end, ref last_vert_index, highlightColor);
3720 beginHighlight =
true;
3721 highlight_start = highlight_end;
3723 highlight_end =
new Vector3(m_textInfo.characterInfo[i].topRight.x, m_textInfo.characterInfo[i].descender, 0);
3724 highlightColor = m_textInfo.characterInfo[i].highlightColor;
3726 isColorTransition =
true;
3729 if (!isColorTransition)
3732 highlight_start.x = Mathf.Min(highlight_start.x, m_textInfo.characterInfo[i].bottomLeft.x);
3733 highlight_start.y = Mathf.Min(highlight_start.y, m_textInfo.characterInfo[i].descender);
3735 highlight_end.x = Mathf.Max(highlight_end.x, m_textInfo.characterInfo[i].topRight.x);
3736 highlight_end.y = Mathf.Max(highlight_end.y, m_textInfo.characterInfo[i].ascender);
3741 if (beginHighlight && m_characterCount == 1)
3743 beginHighlight =
false;
3745 DrawTextHighlight(highlight_start, highlight_end, ref last_vert_index, highlightColor);
3747 else if (beginHighlight && (i == lineInfo.lastCharacterIndex || i >= lineInfo.lastVisibleCharacterIndex))
3749 beginHighlight =
false;
3750 DrawTextHighlight(highlight_start, highlight_end, ref last_vert_index, highlightColor);
3752 else if (beginHighlight && !isHighlightVisible)
3754 beginHighlight =
false;
3755 DrawTextHighlight(highlight_start, highlight_end, ref last_vert_index, highlightColor);
3761 if (beginHighlight ==
true)
3763 beginHighlight =
false;
3764 DrawTextHighlight(highlight_start, highlight_end, ref last_vert_index, highlightColor);
3770 lastLine = currentLine;
3776 m_textInfo.characterCount = m_characterCount;
3777 m_textInfo.spriteCount = m_spriteCount;
3778 m_textInfo.lineCount = lineCount;
3779 m_textInfo.wordCount = wordCount != 0 && m_characterCount > 0 ? wordCount : 1;
3780 m_textInfo.pageCount = m_pageNumber + 1;
3791 if (m_geometrySortingOrder != VertexSortingOrder.Normal)
3792 m_textInfo.meshInfo[0].SortGeometry(VertexSortingOrder.Reverse);
3795 m_mesh.MarkDynamic();
3796 m_mesh.vertices = m_textInfo.meshInfo[0].vertices;
3797 m_mesh.uv = m_textInfo.meshInfo[0].uvs0;
3798 m_mesh.uv2 = m_textInfo.meshInfo[0].uvs2;
3800 m_mesh.colors32 = m_textInfo.meshInfo[0].colors32;
3803 m_mesh.RecalculateBounds();
3806 for (
int i = 1; i < m_textInfo.materialCount; i++)
3811 if (m_subTextObjects[i] ==
null)
continue;
3814 if (m_geometrySortingOrder != VertexSortingOrder.Normal)
3815 m_textInfo.meshInfo[i].SortGeometry(VertexSortingOrder.Reverse);
3817 m_subTextObjects[i].mesh.vertices = m_textInfo.meshInfo[i].vertices;
3818 m_subTextObjects[i].mesh.uv = m_textInfo.meshInfo[i].uvs0;
3819 m_subTextObjects[i].mesh.uv2 = m_textInfo.meshInfo[i].uvs2;
3821 m_subTextObjects[i].mesh.colors32 = m_textInfo.meshInfo[i].colors32;
3823 m_subTextObjects[i].mesh.RecalculateBounds();
3831 TMPro_EventManager.ON_TEXT_CHANGED(
this);
3844 if (m_rectTransform ==
null) m_rectTransform = this.
rectTransform;
3846 m_rectTransform.GetLocalCorners(m_RectTransformCorners);
3848 return m_RectTransformCorners;
3858 if (m_meshFilter !=
null)
3861 m_meshFilter.sharedMesh = m_mesh;
3863 m_meshFilter.sharedMesh =
null;
3866 for (
int i = 1; i < m_subTextObjects.Length && m_subTextObjects[i] !=
null; i++)
3871 m_subTextObjects[i].meshFilter.sharedMesh = m_subTextObjects[i].mesh;
3873 m_subTextObjects[i].meshFilter.sharedMesh =
null;
3885 for (
int i = 1; i < m_subTextObjects.Length && m_subTextObjects[i] !=
null; i++)
3887 if (m_subTextObjects[i].enabled != state)
3888 m_subTextObjects[i].enabled = state;
3898 for (
int i = 1; i < m_subTextObjects.Length && m_subTextObjects[i] !=
null; i++)
3900 Debug.Log(
"Destroying Sub Text object[" + i +
"].");
3901 DestroyImmediate(m_subTextObjects[i]);
3912 Bounds mainBounds = m_mesh.bounds;
3913 Vector3 min = mainBounds.min;
3914 Vector3 max = mainBounds.max;
3916 for (
int i = 1; i < m_subTextObjects.Length && m_subTextObjects[i] !=
null; i++)
3918 Bounds subBounds = m_subTextObjects[i].mesh.bounds;
3919 min.x = min.x < subBounds.min.x ? min.x : subBounds.min.x;
3920 min.y = min.y < subBounds.min.y ? min.y : subBounds.min.y;
3922 max.x = max.x > subBounds.max.x ? max.x : subBounds.max.x;
3923 max.y = max.y > subBounds.max.y ? max.y : subBounds.max.y;
3926 Vector3 center = (min + max) / 2;
3927 Vector2 size = max - min;
3928 return new Bounds(center, size);
3940 for (
int i = 0; i < m_textInfo.characterCount; i++)
3943 if (m_textInfo.characterInfo[i].isVisible && m_textInfo.characterInfo[i].elementType == TMP_TextElementType.Character)
3945 float scale = lossyScale * m_textInfo.characterInfo[i].scale * (1 - m_charWidthAdjDelta);
3946 if (!m_textInfo.characterInfo[i].isUsingAlternateTypeface && (m_textInfo.characterInfo[i].style & FontStyles.Bold) == FontStyles.Bold) scale *= -1;
3948 int index = m_textInfo.characterInfo[i].materialReferenceIndex;
3949 int vertexIndex = m_textInfo.characterInfo[i].vertexIndex;
3951 m_textInfo.meshInfo[index].uvs2[vertexIndex + 0].y = scale;
3952 m_textInfo.meshInfo[index].uvs2[vertexIndex + 1].y = scale;
3953 m_textInfo.meshInfo[index].uvs2[vertexIndex + 2].y = scale;
3954 m_textInfo.meshInfo[index].uvs2[vertexIndex + 3].y = scale;
3959 for (
int i = 0; i < m_textInfo.meshInfo.Length; i++)
3962 m_mesh.uv2 = m_textInfo.meshInfo[0].uvs2;
3964 m_subTextObjects[i].mesh.uv2 = m_textInfo.meshInfo[i].uvs2;
3972 Vector3 vertexOffset =
new Vector3(0, offset, 0);
3974 for (
int i = startIndex; i <= endIndex; i++)
3976 m_textInfo.characterInfo[i].bottomLeft -= vertexOffset;
3977 m_textInfo.characterInfo[i].topLeft -= vertexOffset;
3978 m_textInfo.characterInfo[i].topRight -= vertexOffset;
3979 m_textInfo.characterInfo[i].bottomRight -= vertexOffset;
3981 m_textInfo.characterInfo[i].ascender -= vertexOffset.y;
3982 m_textInfo.characterInfo[i].baseLine -= vertexOffset.y;
3983 m_textInfo.characterInfo[i].descender -= vertexOffset.y;
3985 if (m_textInfo.characterInfo[i].isVisible)
3987 m_textInfo.characterInfo[i].vertex_BL.position -= vertexOffset;
3988 m_textInfo.characterInfo[i].vertex_TL.position -= vertexOffset;
3989 m_textInfo.characterInfo[i].vertex_TR.position -= vertexOffset;
3990 m_textInfo.characterInfo[i].vertex_BR.position -= vertexOffset;
Positional adjustments of a glyph
override void SetOutlineThickness(float thickness)
Function called internally to set the outline thickness property of the material. This will results i...
TextRenderFlags
Flags controlling what vertex data gets pushed to the mesh.
override void UpdateMeshPadding()
Function to be used to force recomputing of character padding when Shader / Material properties have ...
void Clear()
Function to clear and reset stack to first item.
void ClearUnusedVertices()
Function to clear the vertices while preserving the Triangles, Normals and Tangents.
void UpdateSDFScale(float lossyScale)
Method to Update Scale in UV2
override void ComputeMarginSize()
Update the margin width and height
int index
Index of the character in the raw string.
new Transform transform
Returns a reference to the Transform
void SetMeshFilters(bool state)
Method to disable the renderers.
override void LoadFontAsset()
Method which derived classes need to override to load Font Assets.
virtual void SaveGlyphVertexInfo(float padding, float style_padding, Color32 vertexColor)
Store vertex information for each character.
MaskingTypes maskType
Sets the mask type
override int SetArraySizes(int[] chars)
Method used to determine the number of visible characters and required buffer allocations.
Structure which contains information about the individual lines of text.
Class which contains information about every element contained within the text object.
virtual void ClearMesh()
Function to clear the geometry of the Primary and Sub Text objects.
void ParseInputText()
Method to parse the input text based on its source
virtual void FillSpriteVertexBuffers(int i, int index_X4)
Fill Vertex Buffers for Sprites
override void SetFaceColor(Color32 color)
Function called internally to set the face color of the material. This will results in an instance of...
override void SetVerticesDirty()
Schedule rebuilding of the text geometry.
TMP_SpriteAsset spriteAsset
Default Sprite Asset used by the text object.
override Bounds GetCompoundBounds()
Method returning the compound bounds of the text object and child sub objects.
virtual void SaveSpriteVertexInfo(Color32 vertexColor)
Store vertex information for each sprite.
TMP_FontAsset GetFontAssetForWeight(int fontWeight)
override void SetOutlineColor(Color32 color)
Function called internally to set the outline color of the material. This will results in an instance...
Renderer renderer
Returns the rendered assigned to the text object.
void ResizeMeshInfo(int size)
Function to resized the content of MeshData and re-assign normals, tangents and triangles.
override void SetSharedMaterials(Material[] materials)
Method used to assign new materials to the text and sub text objects.
override void ClearSubMeshObjects()
Destroy Sub Mesh Objects
static TMP_SpriteAsset SearchForSpriteByUnicode(TMP_SpriteAsset spriteAsset, int unicode, bool includeFallbacks, out int spriteIndex)
Search through the given sprite asset and its fallbacks for the specified sprite matching the given u...
void ClearLineInfo()
Function to clear and initialize the lineInfo array.
static TMP_FontAsset defaultFontAsset
Returns the Default Font Asset to be used by newly created text objects.
override Mesh mesh
Returns the mesh assigned to the text object.
Vector2 PackUV(float x, float y, float scale)
Function to pack scale information in the UV2 Channel.
override void SetMaterialDirty()
Schedule updating of the material used by the text object.
override Material [] GetSharedMaterials()
Method returning an array containing the materials used by the text object.
Material fontMaterial
The material to be assigned to this text object. An instance of the material will be assigned to the ...
void Clear()
Function to clear the vertices while preserving the Triangles, Normals and Tangents.
new RectTransform rectTransform
Returns are reference to the RectTransform
override Material GetMaterial(Material mat)
Function called internally when a new material is assigned via the fontMaterial property.
override void SetSharedMaterial(Material mat)
Function called internally when a new shared material is assigned via the fontSharedMaterial property...
static int AddMaterialReference(Material material, TMP_FontAsset fontAsset, MaterialReference[] materialReferences, Dictionary< int, int > materialReferenceIndexLookup)
Function to add a new material reference and returning its index in the material reference array.
void Clear()
Clear the basic XML tag stack.
static int missingGlyphCharacter
The character the will be used as a replacement for missing glyphs in a font asset.
void SetDefault(T item)
Function to set the first item on the stack and reset index.
int firstVisibleCharacter
The first character which should be made visible in conjunction with the Text Overflow Linked mode.
Dictionary< int, KerningPair > kerningDictionary
Dictionary containing the kerning data
override float GetPaddingForMaterial()
Get the padding value for the currently assigned material.
TMP_FontAsset font
The Font Asset to be assigned to this text object.
override void GenerateTextMesh()
This is the main function that is responsible for creating / displaying the text.
void ReadFontDefinition()
override void SetLayoutDirty()
virtual void ForceMeshUpdate()
Function to force the regeneration of the text object.
virtual void FillCharacterVertexBuffers(int i, int index_X4)
Store vertex attributes into the appropriate TMP_MeshInfo.
virtual void DrawUnderlineMesh(Vector3 start, Vector3 end, ref int index, float startScale, float endScale, float maxScale, float sdfScale, Color32 underlineColor)
Method to add the underline geometry.
override void AdjustLineOffset(int startIndex, int endIndex, float offset)
Method to adjust line spacing as a result of using different fonts or font point size.
override Vector3 [] GetTextContainerLocalCorners()
Method to return the local corners of the Text Container or RectTransform.
void Clear()
Function to clear the counters of the text object.
bool ValidateHtmlTag(int[] chars, int startIndex, out int endIndex)
Function to identify and validate the rich tag. Returns the position of the > if the tag was valid.
override void SetCulling()
Set the culling mode on the material.
Material material
The material used by this asset.
void ResizeLineExtents(int size)
Function to increase the size of the Line Extents Array.
Structure which contains the vertex attributes (geometry) of the text object.
static bool matchMaterialPreset
Controls whether or not TMP will create a matching material preset or use the default material of the...
void LateUpdate()
Unity standard function used to check if the transform or scale of the text object has changed.
TMP custom data type to represent 32 bit characters.
_HorizontalAlignmentOptions
Internal horizontal text alignment options.
int RestoreWordWrappingState(ref WordWrapState state)
Restore the State of various variables used in the mesh creation loop.
int pageToDisplay
Controls which page of text is shown
override void SetAllDirty()
override Material [] GetMaterials(Material[] mats)
Method returning instances of the materials used by the text object.
bool enableWordWrapping
Controls whether or not word wrapping is applied. When disabled, the text will be displayed on a sing...
void GetSpecialCharacters(TMP_FontAsset fontAsset)
Method used to find and cache references to the Underline and Ellipsis characters.
FaceInfo fontInfo
The general information about the font.
override Color color
This is the default vertex color assigned to each vertices. Color tags will override vertex colors un...
string text
A string containing the text to be displayed.
void LoadDefaultSettings()
Internal function used to load the default settings of text objects.
override void SetActiveSubMeshes(bool state)
Method to Enable or Disable child SubMesh objects.
static bool warningsDisabled
Controls the display of warning message in the console.
void SaveWordWrappingState(ref WordWrapState state, int index, int count)
Function used in conjunction with GetTextInfo to figure out Array allocations.
MeshFilter meshFilter
Returns the Mesh Filter of the text object.
void SetMask(MaskingTypes type, Vector4 maskCoords)
Function used to set the mask type and coordinates in World Space
static List< TMP_FontAsset > fallbackFontAssets
Returns the list of Fallback Fonts defined in the TMP Settings file.
void OnPreRenderObject()
Function called when the text needs to be updated.
static TMP_SpriteAsset defaultSpriteAsset
The Default Sprite Asset to be used by default.
override float GetPaddingForMaterial(Material mat)
Get the padding value for the currently assigned material.
override void SetShaderDepth()
Set the Render Queue and ZTest mode on the current material
static LineBreakingTable linebreakingRules