7 using System.Collections.Generic;
10 #pragma warning disable 0414 // Disabled a few warnings related to serialized variables not used in this script but used in the editor. 11 #pragma warning disable 0618 // Disabled warning due to SetVertices being deprecated until new release with SetMesh() is available. 15 public partial class TextMeshProUGUI
18 private bool m_hasFontAssetChanged =
false;
21 protected TMP_SubMeshUI[] m_subTextObjects =
new TMP_SubMeshUI[8];
23 private float m_previousLossyScaleY = -1;
25 private Vector3[] m_RectTransformCorners =
new Vector3[4];
26 private CanvasRenderer m_canvasRenderer;
27 private Canvas m_canvas;
30 private bool m_isFirstAllocation;
31 private int m_max_characters = 8;
35 private bool m_isMaskingEnabled;
38 private Material m_baseMaterial;
41 private bool m_isScrollRegionSet;
43 private int m_stencilID = 0;
46 private Vector4 m_maskOffset;
49 private Matrix4x4 m_EnvMapMatrix =
new Matrix4x4();
54 private bool m_isRegisteredForEvents;
60 private int m_recursiveCountA = 0;
61 private int loopCountA = 0;
71 protected override void Awake()
77 if (TMP_Settings.instance ==
null)
79 if (m_isWaitingOnResourceLoad ==
false)
80 TMPro_EventManager.RESOURCE_LOAD_EVENT.Add(ON_RESOURCES_LOADED);
82 m_isWaitingOnResourceLoad =
true;
88 m_canvas = this.canvas;
90 m_isOrthographic =
true;
93 m_rectTransform = gameObject.GetComponent<RectTransform>();
94 if (m_rectTransform ==
null)
95 m_rectTransform = gameObject.AddComponent<RectTransform>();
98 m_canvasRenderer = GetComponent<CanvasRenderer>();
99 if (m_canvasRenderer ==
null)
100 m_canvasRenderer = gameObject.AddComponent<CanvasRenderer> ();
106 m_mesh.hideFlags = HideFlags.HideAndDontSave;
118 TMP_StyleSheet.LoadDefaultStyleSheet();
121 if (m_char_buffer ==
null)
122 m_char_buffer =
new int[m_max_characters];
124 m_cached_TextElement =
new TMP_Glyph();
125 m_isFirstAllocation =
true;
127 if (m_textInfo ==
null)
128 m_textInfo =
new TMP_TextInfo(
this);
131 if (m_fontAsset ==
null)
133 Debug.LogWarning(
"Please assign a Font Asset to this " +
transform.name +
" gameobject.",
this);
138 TMP_SubMeshUI[] subTextObjects = GetComponentsInChildren<TMP_SubMeshUI>();
139 if (subTextObjects.Length > 0)
141 for (
int i = 0; i < subTextObjects.Length; i++)
142 m_subTextObjects[i + 1] = subTextObjects[i];
146 m_isInputParsingRequired =
true;
147 m_havePropertiesChanged =
true;
148 m_isCalculateSizeRequired =
true;
154 protected override void OnEnable()
159 if (m_isAwake ==
false)
162 if (!m_isRegisteredForEvents)
168 TMPro_EventManager.MATERIAL_PROPERTY_EVENT.Add(ON_MATERIAL_PROPERTY_CHANGED);
169 TMPro_EventManager.FONT_PROPERTY_EVENT.Add(ON_FONT_PROPERTY_CHANGED);
170 TMPro_EventManager.TEXTMESHPRO_UGUI_PROPERTY_EVENT.Add(ON_TEXTMESHPRO_UGUI_PROPERTY_CHANGED);
171 TMPro_EventManager.DRAG_AND_DROP_MATERIAL_EVENT.Add(ON_DRAG_AND_DROP_MATERIAL);
172 TMPro_EventManager.TEXT_STYLE_PROPERTY_EVENT.Add(ON_TEXT_STYLE_CHANGED);
173 TMPro_EventManager.COLOR_GRADIENT_PROPERTY_EVENT.Add(ON_COLOR_GRADIENT_CHANGED);
174 TMPro_EventManager.TMP_SETTINGS_PROPERTY_EVENT.Add(ON_TMP_SETTINGS_CHANGED);
176 m_isRegisteredForEvents =
true;
185 GraphicRegistry.RegisterGraphicForCanvas(m_canvas,
this);
189 m_verticesAlreadyDirty =
false;
190 m_layoutAlreadyDirty =
false;
191 m_ShouldRecalculateStencil =
true;
192 m_isInputParsingRequired =
true;
199 protected override void OnDisable()
205 if (m_isAwake ==
false)
208 if (m_MaskMaterial !=
null)
210 TMP_MaterialManager.ReleaseStencilMaterial(m_MaskMaterial);
211 m_MaskMaterial =
null;
215 GraphicRegistry.UnregisterGraphicForCanvas(m_canvas,
this);
216 CanvasUpdateRegistry.UnRegisterCanvasElementForRebuild((ICanvasElement)
this);
218 if (m_canvasRenderer !=
null)
219 m_canvasRenderer.Clear();
223 LayoutRebuilder.MarkLayoutForRebuild(m_rectTransform);
228 protected override void OnDestroy()
234 GraphicRegistry.UnregisterGraphicForCanvas(m_canvas,
this);
238 DestroyImmediate(m_mesh);
241 if (m_MaskMaterial !=
null)
243 TMP_MaterialManager.ReleaseStencilMaterial(m_MaskMaterial);
244 m_MaskMaterial =
null;
249 TMPro_EventManager.MATERIAL_PROPERTY_EVENT.Remove(ON_MATERIAL_PROPERTY_CHANGED);
250 TMPro_EventManager.FONT_PROPERTY_EVENT.Remove(ON_FONT_PROPERTY_CHANGED);
251 TMPro_EventManager.TEXTMESHPRO_UGUI_PROPERTY_EVENT.Remove(ON_TEXTMESHPRO_UGUI_PROPERTY_CHANGED);
252 TMPro_EventManager.DRAG_AND_DROP_MATERIAL_EVENT.Remove(ON_DRAG_AND_DROP_MATERIAL);
253 TMPro_EventManager.TEXT_STYLE_PROPERTY_EVENT.Remove(ON_TEXT_STYLE_CHANGED);
254 TMPro_EventManager.COLOR_GRADIENT_PROPERTY_EVENT.Remove(ON_COLOR_GRADIENT_CHANGED);
255 TMPro_EventManager.TMP_SETTINGS_PROPERTY_EVENT.Remove(ON_TMP_SETTINGS_CHANGED);
256 TMPro_EventManager.RESOURCE_LOAD_EVENT.Remove(ON_RESOURCES_LOADED);
258 m_isRegisteredForEvents =
false;
263 protected override void Reset()
268 if (m_isAwake ==
false)
274 m_isInputParsingRequired =
true;
275 m_havePropertiesChanged =
true;
279 protected override void OnValidate()
284 if (m_isAwake ==
false)
288 if (m_fontAsset ==
null || m_hasFontAssetChanged)
291 m_isCalculateSizeRequired =
true;
292 m_hasFontAssetChanged =
false;
296 if (m_canvasRenderer ==
null || m_canvasRenderer.GetMaterial() ==
null || m_canvasRenderer.GetMaterial().GetTexture(ShaderUtilities.ID_MainTex) ==
null || m_fontAsset ==
null || m_fontAsset.atlas.GetInstanceID() != m_canvasRenderer.GetMaterial().GetTexture(ShaderUtilities.ID_MainTex).GetInstanceID())
299 m_isCalculateSizeRequired =
true;
300 m_hasFontAssetChanged =
false;
306 m_isInputParsingRequired =
true;
307 m_inputSource = TextInputSources.Text;
308 m_havePropertiesChanged =
true;
309 m_isCalculateSizeRequired =
true;
310 m_isPreferredWidthDirty =
true;
311 m_isPreferredHeightDirty =
true;
318 void ON_RESOURCES_LOADED()
320 TMPro_EventManager.RESOURCE_LOAD_EVENT.Remove(ON_RESOURCES_LOADED);
328 void ON_MATERIAL_PROPERTY_CHANGED(
bool isChanged, Material mat)
332 ShaderUtilities.GetShaderPropertyIDs();
334 int materialID = mat.GetInstanceID();
335 int sharedMaterialID = m_sharedMaterial.GetInstanceID();
336 int maskingMaterialID = m_MaskMaterial ==
null ? 0 : m_MaskMaterial.GetInstanceID();
338 if (m_canvasRenderer ==
null || m_canvasRenderer.GetMaterial() ==
null)
340 if (m_canvasRenderer ==
null)
return;
342 if (m_fontAsset !=
null)
344 m_canvasRenderer.SetMaterial(m_fontAsset.
material, m_sharedMaterial.GetTexture(ShaderUtilities.ID_MainTex));
348 Debug.LogWarning(
"No Font Asset assigned to " + name +
". Please assign a Font Asset.",
this);
352 if (m_canvasRenderer.GetMaterial() != m_sharedMaterial && m_fontAsset ==
null)
355 m_sharedMaterial = m_canvasRenderer.GetMaterial();
360 if (m_MaskMaterial !=
null)
362 UnityEditor.Undo.RecordObject(m_MaskMaterial,
"Material Property Changes");
363 UnityEditor.Undo.RecordObject(m_sharedMaterial,
"Material Property Changes");
365 if (materialID == sharedMaterialID)
368 float stencilID = m_MaskMaterial.GetFloat(ShaderUtilities.ID_StencilID);
369 float stencilComp = m_MaskMaterial.GetFloat(ShaderUtilities.ID_StencilComp);
374 m_MaskMaterial.CopyPropertiesFromMaterial(mat);
375 m_MaskMaterial.shaderKeywords = mat.shaderKeywords;
377 m_MaskMaterial.SetFloat(ShaderUtilities.ID_StencilID, stencilID);
378 m_MaskMaterial.SetFloat(ShaderUtilities.ID_StencilComp, stencilComp);
383 else if (materialID == maskingMaterialID)
388 m_sharedMaterial.CopyPropertiesFromMaterial(mat);
389 m_sharedMaterial.shaderKeywords = mat.shaderKeywords;
390 m_sharedMaterial.SetFloat(ShaderUtilities.ID_StencilID, 0);
391 m_sharedMaterial.SetFloat(ShaderUtilities.ID_StencilComp, 8);
400 m_havePropertiesChanged =
true;
407 void ON_FONT_PROPERTY_CHANGED(
bool isChanged, TMP_FontAsset
font)
409 if (MaterialReference.Contains(m_materialReferences,
font))
412 m_isInputParsingRequired =
true;
413 m_havePropertiesChanged =
true;
422 void ON_TEXTMESHPRO_UGUI_PROPERTY_CHANGED(
bool isChanged, TextMeshProUGUI obj)
429 m_havePropertiesChanged =
true;
430 m_isInputParsingRequired =
true;
439 void ON_DRAG_AND_DROP_MATERIAL(GameObject obj, Material currentMaterial, Material newMaterial)
444 #if UNITY_2018_2_OR_NEWER 445 if (obj == gameObject ||
UnityEditor.PrefabUtility.GetCorrespondingObjectFromSource(gameObject) == obj)
447 if (obj == gameObject ||
UnityEditor.PrefabUtility.GetPrefabParent(gameObject) == obj)
450 UnityEditor.Undo.RecordObject(
this,
"Material Assignment");
451 UnityEditor.Undo.RecordObject(m_canvasRenderer,
"Material Assignment");
453 m_sharedMaterial = newMaterial;
457 m_havePropertiesChanged =
true;
465 void ON_TEXT_STYLE_CHANGED(
bool isChanged)
467 m_havePropertiesChanged =
true;
468 m_isInputParsingRequired =
true;
477 void ON_COLOR_GRADIENT_CHANGED(TMP_ColorGradient gradient)
479 if (m_fontColorGradientPreset !=
null && gradient.GetInstanceID() == m_fontColorGradientPreset.GetInstanceID())
481 m_havePropertiesChanged =
true;
490 void ON_TMP_SETTINGS_CHANGED()
492 m_defaultSpriteAsset =
null;
493 m_havePropertiesChanged =
true;
494 m_isInputParsingRequired =
true;
505 ShaderUtilities.GetShaderPropertyIDs();
507 if (m_fontAsset ==
null)
512 m_fontAsset = Resources.Load<
TMP_FontAsset>(
"Fonts & Materials/LiberationSans SDF");
514 if (m_fontAsset ==
null)
516 Debug.LogWarning(
"The LiberationSans SDF Font Asset was not found. There is no Font Asset assigned to " + gameObject.name +
".",
this);
520 if (m_fontAsset.characterDictionary ==
null)
522 Debug.Log(
"Dictionary is Null!");
525 m_sharedMaterial = m_fontAsset.material;
530 if (m_fontAsset.characterDictionary ==
null)
531 m_fontAsset.ReadFontDefinition();
534 if (m_sharedMaterial ==
null && m_baseMaterial !=
null)
536 m_sharedMaterial = m_baseMaterial;
537 m_baseMaterial =
null;
541 if (m_sharedMaterial ==
null || m_sharedMaterial.GetTexture(ShaderUtilities.ID_MainTex) ==
null || m_fontAsset.atlas.GetInstanceID() != m_sharedMaterial.GetTexture(ShaderUtilities.ID_MainTex).GetInstanceID())
543 if (m_fontAsset.material ==
null)
544 Debug.LogWarning(
"The Font Atlas Texture of the Font Asset " + m_fontAsset.name +
" assigned to " + gameObject.name +
" is missing.",
this);
546 m_sharedMaterial = m_fontAsset.material;
565 Canvas canvas =
null;
566 var list = TMP_ListPool<Canvas>.Get();
568 gameObject.GetComponentsInParent(
false, list);
572 for (
int i = 0; i < list.Count; ++i)
574 if (list[i].isActiveAndEnabled)
582 TMP_ListPool<Canvas>.Release(list);
593 if (!m_sharedMaterial.HasProperty(ShaderUtilities.ID_EnvMap) || m_sharedMaterial.GetTexture(ShaderUtilities.ID_EnvMap) ==
null)
597 Vector3 rotation = m_sharedMaterial.GetVector(ShaderUtilities.ID_EnvMatrixRotation);
598 m_EnvMapMatrix = Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(rotation), Vector3.one);
600 m_sharedMaterial.SetMatrix(ShaderUtilities.ID_EnvMatrix, m_EnvMapMatrix);
607 if (m_fontMaterial ==
null)
610 m_canvasRenderer.SetMaterial(m_fontMaterial, m_sharedMaterial.GetTexture(ShaderUtilities.ID_MainTex));
613 m_sharedMaterial = m_fontMaterial;
614 if (m_sharedMaterial.HasProperty(ShaderUtilities.ID_ClipRect))
616 m_sharedMaterial.EnableKeyword(ShaderUtilities.Keyword_MASK_SOFT);
617 m_sharedMaterial.DisableKeyword(ShaderUtilities.Keyword_MASK_HARD);
618 m_sharedMaterial.DisableKeyword(ShaderUtilities.Keyword_MASK_TEX);
623 m_isMaskingEnabled =
true;
646 void DisableMasking()
648 if (m_fontMaterial !=
null)
651 m_sharedMaterial = m_MaskMaterial;
655 m_canvasRenderer.SetMaterial(m_sharedMaterial, m_sharedMaterial.GetTexture(ShaderUtilities.ID_MainTex));
657 DestroyImmediate(m_fontMaterial);
660 m_isMaskingEnabled =
false;
697 if (m_rectTransform !=
null)
703 if (!ShaderUtilities.isInitialized)
704 ShaderUtilities.GetShaderPropertyIDs();
708 m_isScrollRegionSet =
true;
710 float softnessX = Mathf.Min(Mathf.Min(m_margin.x, m_margin.z), m_sharedMaterial.GetFloat(ShaderUtilities.ID_MaskSoftnessX));
711 float softnessY = Mathf.Min(Mathf.Min(m_margin.y, m_margin.w), m_sharedMaterial.GetFloat(ShaderUtilities.ID_MaskSoftnessY));
713 softnessX = softnessX > 0 ? softnessX : 0;
714 softnessY = softnessY > 0 ? softnessY : 0;
716 float width = (m_rectTransform.rect.width - Mathf.Max(m_margin.x, 0) - Mathf.Max(m_margin.z, 0)) / 2 + softnessX;
717 float height = (m_rectTransform.rect.height - Mathf.Max(m_margin.y, 0) - Mathf.Max(m_margin.w, 0)) / 2 + softnessY;
720 Vector2 center = m_rectTransform.localPosition +
new Vector3((0.5f - m_rectTransform.pivot.x) * m_rectTransform.rect.width + (Mathf.Max(m_margin.x, 0) - Mathf.Max(m_margin.z, 0)) / 2, (0.5f - m_rectTransform.pivot.y) * m_rectTransform.rect.height + (-Mathf.Max(m_margin.y, 0) + Mathf.Max(m_margin.w, 0)) / 2);
723 Vector4 mask =
new Vector4(center.x, center.y, width, height);
730 m_sharedMaterial.SetVector(ShaderUtilities.ID_ClipRect, mask);
739 ShaderUtilities.GetShaderPropertyIDs();
747 if (m_fontMaterial ==
null || m_fontMaterial.GetInstanceID() != mat.GetInstanceID())
750 m_sharedMaterial = m_fontMaterial;
754 m_ShouldRecalculateStencil =
true;
758 return m_sharedMaterial;
768 int materialCount = m_textInfo.materialCount;
770 if (m_fontMaterials ==
null)
771 m_fontMaterials =
new Material[materialCount];
772 else if (m_fontMaterials.Length != materialCount)
773 TMP_TextInfo.Resize(ref m_fontMaterials, materialCount,
false);
776 for (
int i = 0; i < materialCount; i++)
781 m_fontMaterials[i] = m_subTextObjects[i].material;
784 m_fontSharedMaterials = m_fontMaterials;
786 return m_fontMaterials;
798 m_sharedMaterial = mat;
812 int materialCount = m_textInfo.materialCount;
814 if (m_fontSharedMaterials ==
null)
815 m_fontSharedMaterials =
new Material[materialCount];
816 else if (m_fontSharedMaterials.Length != materialCount)
817 TMP_TextInfo.Resize(ref m_fontSharedMaterials, materialCount,
false);
819 for (
int i = 0; i < materialCount; i++)
822 m_fontSharedMaterials[i] = m_sharedMaterial;
824 m_fontSharedMaterials[i] = m_subTextObjects[i].sharedMaterial;
827 return m_fontSharedMaterials;
836 int materialCount = m_textInfo.materialCount;
839 if (m_fontSharedMaterials ==
null)
840 m_fontSharedMaterials =
new Material[materialCount];
841 else if (m_fontSharedMaterials.Length != materialCount)
842 TMP_TextInfo.Resize(ref m_fontSharedMaterials, materialCount,
false);
845 for (
int i = 0; i < materialCount; i++)
850 if (materials[i].GetTexture(ShaderUtilities.ID_MainTex) ==
null || materials[i].GetTexture(ShaderUtilities.ID_MainTex).GetInstanceID() != m_sharedMaterial.GetTexture(ShaderUtilities.ID_MainTex).GetInstanceID())
853 m_sharedMaterial = m_fontSharedMaterials[i] = materials[i];
859 if (materials[i].GetTexture(ShaderUtilities.ID_MainTex) ==
null || materials[i].GetTexture(ShaderUtilities.ID_MainTex).GetInstanceID() != m_subTextObjects[i].sharedMaterial.GetTexture(ShaderUtilities.ID_MainTex).GetInstanceID())
863 if (m_subTextObjects[i].isDefaultMaterial)
864 m_subTextObjects[i].sharedMaterial = m_fontSharedMaterials[i] = materials[i];
874 if (m_fontMaterial !=
null && m_sharedMaterial.GetInstanceID() != m_fontMaterial.GetInstanceID())
876 m_sharedMaterial = m_fontMaterial;
877 m_canvasRenderer.SetMaterial(m_sharedMaterial, m_sharedMaterial.GetTexture(ShaderUtilities.ID_MainTex));
879 else if(m_fontMaterial ==
null)
882 m_sharedMaterial = m_fontMaterial;
883 m_canvasRenderer.SetMaterial(m_sharedMaterial, m_sharedMaterial.GetTexture(ShaderUtilities.ID_MainTex));
886 thickness = Mathf.Clamp01(thickness);
887 m_sharedMaterial.SetFloat(ShaderUtilities.ID_OutlineWidth, thickness);
896 if (m_fontMaterial ==
null)
899 m_sharedMaterial = m_fontMaterial;
902 m_sharedMaterial.SetColor(ShaderUtilities.ID_FaceColor,
color);
910 if (m_fontMaterial ==
null)
913 m_sharedMaterial = m_fontMaterial;
916 m_sharedMaterial.SetColor(ShaderUtilities.ID_OutlineColor,
color);
923 if (m_canvas ==
null || m_sharedMaterial ==
null)
926 if (m_canvas.renderMode == RenderMode.ScreenSpaceOverlay || m_isOverlay)
929 m_sharedMaterial.SetFloat(ShaderUtilities.ShaderTag_ZTestMode, 0);
933 m_sharedMaterial.SetFloat(ShaderUtilities.ShaderTag_ZTestMode, 4);
941 if (m_isCullingEnabled)
946 mat.SetFloat(
"_CullMode", 2);
948 for (
int i = 1; i < m_subTextObjects.Length && m_subTextObjects[i] !=
null; i++)
950 mat = m_subTextObjects[i].materialForRendering;
954 mat.SetFloat(ShaderUtilities.ShaderTag_CullMode, 2);
963 mat.SetFloat(
"_CullMode", 0);
965 for (
int i = 1; i < m_subTextObjects.Length && m_subTextObjects[i] !=
null; i++)
967 mat = m_subTextObjects[i].materialForRendering;
971 mat.SetFloat(ShaderUtilities.ShaderTag_CullMode, 0);
979 void SetPerspectiveCorrection()
981 if (m_isOrthographic)
982 m_sharedMaterial.SetFloat(ShaderUtilities.ID_PerspectiveFilter, 0.0f);
984 m_sharedMaterial.SetFloat(ShaderUtilities.ID_PerspectiveFilter, 0.875f);
994 m_padding = ShaderUtilities.GetPadding(mat, m_enableExtraPadding, m_isUsingBold);
995 m_isMaskingEnabled = ShaderUtilities.IsMaskingEnabled(m_sharedMaterial);
996 m_isSDFShader = mat.HasProperty(ShaderUtilities.ID_WeightNormal);
1008 ShaderUtilities.GetShaderPropertyIDs();
1010 m_padding = ShaderUtilities.GetPadding(m_sharedMaterial, m_enableExtraPadding, m_isUsingBold);
1011 m_isMaskingEnabled = ShaderUtilities.IsMaskingEnabled(m_sharedMaterial);
1012 m_isSDFShader = m_sharedMaterial.HasProperty(ShaderUtilities.ID_WeightNormal);
1018 void SetMeshArrays(
int size)
1022 m_canvasRenderer.SetMesh(m_textInfo.meshInfo[0].mesh);
1031 Profiler.BeginSample(
"SetArraySizes");
1035 int spriteCount = 0;
1037 m_totalCharacterCount = 0;
1038 m_isUsingBold =
false;
1039 m_isParsingText =
false;
1040 tag_NoParsing =
false;
1041 m_style = m_fontStyle;
1043 m_fontWeightInternal = (m_style & FontStyles.Bold) == FontStyles.Bold ? 700 : m_fontWeight;
1044 m_fontWeightStack.
SetDefault(m_fontWeightInternal);
1046 m_currentFontAsset = m_fontAsset;
1047 m_currentMaterial = m_sharedMaterial;
1048 m_currentMaterialIndex = 0;
1050 m_materialReferenceStack.SetDefault(
new MaterialReference(m_currentMaterialIndex, m_currentFontAsset,
null, m_currentMaterial, m_padding));
1052 m_materialReferenceIndexLookup.Clear();
1055 if (m_textInfo ==
null) m_textInfo =
new TMP_TextInfo();
1056 m_textElementType = TMP_TextElementType.Character;
1059 if (m_linkedTextComponent !=
null)
1061 m_linkedTextComponent.
text =
string.Empty;
1066 for (
int i = 0; i < chars.Length && chars[i] != 0; i++)
1069 if (m_textInfo.characterInfo ==
null || m_totalCharacterCount >= m_textInfo.characterInfo.Length)
1070 TMP_TextInfo.Resize(ref m_textInfo.characterInfo, m_totalCharacterCount + 1,
true);
1075 #region PARSE XML TAGS 1076 if (m_isRichText && c == 60)
1078 int prev_MaterialIndex = m_currentMaterialIndex;
1085 if ((m_style & FontStyles.Bold) == FontStyles.Bold) m_isUsingBold =
true;
1087 if (m_textElementType == TMP_TextElementType.Sprite)
1089 m_materialReferences[m_currentMaterialIndex].referenceCount += 1;
1091 m_textInfo.characterInfo[m_totalCharacterCount].character = (char)(57344 + m_spriteIndex);
1092 m_textInfo.characterInfo[m_totalCharacterCount].spriteIndex = m_spriteIndex;
1093 m_textInfo.characterInfo[m_totalCharacterCount].fontAsset = m_currentFontAsset;
1094 m_textInfo.characterInfo[m_totalCharacterCount].spriteAsset = m_currentSpriteAsset;
1095 m_textInfo.characterInfo[m_totalCharacterCount].materialReferenceIndex = m_currentMaterialIndex;
1096 m_textInfo.characterInfo[m_totalCharacterCount].elementType = m_textElementType;
1099 m_textElementType = TMP_TextElementType.Character;
1100 m_currentMaterialIndex = prev_MaterialIndex;
1103 m_totalCharacterCount += 1;
1112 bool isUsingFallback =
false;
1113 bool isUsingAlternativeTypeface =
false;
1118 Material prev_material = m_currentMaterial;
1119 int prev_materialIndex = m_currentMaterialIndex;
1123 #region Handling of LowerCase, UpperCase and SmallCaps Font Styles 1124 if (m_textElementType == TMP_TextElementType.Character)
1126 if ((m_style & FontStyles.UpperCase) == FontStyles.UpperCase)
1129 if (
char.IsLower((
char)c))
1130 c =
char.ToUpper((
char)c);
1133 else if ((m_style & FontStyles.LowerCase) == FontStyles.LowerCase)
1136 if (
char.IsUpper((
char)c))
1137 c =
char.ToLower((
char)c);
1139 else if ((m_fontStyle & FontStyles.SmallCaps) == FontStyles.SmallCaps || (m_style & FontStyles.SmallCaps) == FontStyles.SmallCaps)
1142 if (
char.IsLower((
char)c))
1143 c =
char.ToUpper((
char)c);
1150 #region HANDLING OF FONT WEIGHT 1152 if (tempFontAsset !=
null)
1154 isUsingFallback =
true;
1155 isUsingAlternativeTypeface =
true;
1156 m_currentFontAsset = tempFontAsset;
1163 #region LOOKUP GLYPH 1164 tempFontAsset = TMP_FontUtilities.SearchForGlyph(m_currentFontAsset, c, out glyph);
1171 if (spriteAsset !=
null)
1173 int spriteIndex = -1;
1178 if (spriteIndex != -1)
1180 m_textElementType = TMP_TextElementType.Sprite;
1181 m_textInfo.characterInfo[m_totalCharacterCount].elementType = m_textElementType;
1184 m_materialReferences[m_currentMaterialIndex].referenceCount += 1;
1186 m_textInfo.characterInfo[m_totalCharacterCount].character = (char)c;
1187 m_textInfo.characterInfo[m_totalCharacterCount].spriteIndex = spriteIndex;
1188 m_textInfo.characterInfo[m_totalCharacterCount].fontAsset = m_currentFontAsset;
1189 m_textInfo.characterInfo[m_totalCharacterCount].spriteAsset =
spriteAsset;
1190 m_textInfo.characterInfo[m_totalCharacterCount].materialReferenceIndex = m_currentMaterialIndex;
1193 m_textElementType = TMP_TextElementType.Character;
1194 m_currentMaterialIndex = prev_materialIndex;
1197 m_totalCharacterCount += 1;
1226 int spriteIndex = -1;
1231 if (spriteIndex != -1)
1233 m_textElementType = TMP_TextElementType.Sprite;
1234 m_textInfo.characterInfo[m_totalCharacterCount].elementType = m_textElementType;
1237 m_materialReferences[m_currentMaterialIndex].referenceCount += 1;
1239 m_textInfo.characterInfo[m_totalCharacterCount].character = (char)c;
1240 m_textInfo.characterInfo[m_totalCharacterCount].spriteIndex = spriteIndex;
1241 m_textInfo.characterInfo[m_totalCharacterCount].fontAsset = m_currentFontAsset;
1242 m_textInfo.characterInfo[m_totalCharacterCount].spriteAsset =
spriteAsset;
1243 m_textInfo.characterInfo[m_totalCharacterCount].materialReferenceIndex = m_currentMaterialIndex;
1246 m_textElementType = TMP_TextElementType.Character;
1247 m_currentMaterialIndex = prev_materialIndex;
1250 m_totalCharacterCount += 1;
1283 tempFontAsset = TMP_FontUtilities.SearchForGlyph(m_currentFontAsset, c, out glyph);
1303 tempFontAsset = TMP_FontUtilities.SearchForGlyph(m_currentFontAsset, c, out glyph);
1304 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);
1309 if (tempFontAsset !=
null)
1311 if (tempFontAsset.GetInstanceID() != m_currentFontAsset.GetInstanceID())
1313 isUsingFallback =
true;
1314 isUsingAlternativeTypeface =
false;
1315 m_currentFontAsset = tempFontAsset;
1321 m_textInfo.characterInfo[m_totalCharacterCount].elementType = TMP_TextElementType.Character;
1322 m_textInfo.characterInfo[m_totalCharacterCount].textElement = glyph;
1323 m_textInfo.characterInfo[m_totalCharacterCount].isUsingAlternateTypeface = isUsingAlternativeTypeface;
1324 m_textInfo.characterInfo[m_totalCharacterCount].character = (char)c;
1325 m_textInfo.characterInfo[m_totalCharacterCount].fontAsset = m_currentFontAsset;
1327 if (isUsingFallback)
1331 m_currentMaterial = TMP_MaterialManager.GetFallbackMaterial(m_currentMaterial, m_currentFontAsset.
material);
1333 m_currentMaterial = m_currentFontAsset.
material;
1338 if (!
char.IsWhiteSpace((
char)c) && c != 0x200B)
1341 if (m_materialReferences[m_currentMaterialIndex].referenceCount < 16383)
1342 m_materialReferences[m_currentMaterialIndex].referenceCount += 1;
1346 m_materialReferences[m_currentMaterialIndex].referenceCount += 1;
1350 m_textInfo.characterInfo[m_totalCharacterCount].material = m_currentMaterial;
1351 m_textInfo.characterInfo[m_totalCharacterCount].materialReferenceIndex = m_currentMaterialIndex;
1352 m_materialReferences[m_currentMaterialIndex].isFallbackMaterial = isUsingFallback;
1355 if (isUsingFallback)
1357 m_materialReferences[m_currentMaterialIndex].fallbackMaterial = prev_material;
1358 m_currentFontAsset = prev_fontAsset;
1359 m_currentMaterial = prev_material;
1360 m_currentMaterialIndex = prev_materialIndex;
1363 m_totalCharacterCount += 1;
1367 if (m_isCalculatingPreferredValues)
1369 m_isCalculatingPreferredValues =
false;
1370 m_isInputParsingRequired =
true;
1371 return m_totalCharacterCount;
1375 m_textInfo.spriteCount = spriteCount;
1376 int materialCount = m_textInfo.materialCount = m_materialReferenceIndexLookup.Count;
1379 if (materialCount > m_textInfo.meshInfo.Length)
1380 TMP_TextInfo.Resize(ref m_textInfo.meshInfo, materialCount,
false);
1383 if (materialCount > m_subTextObjects.Length)
1384 TMP_TextInfo.Resize(ref m_subTextObjects, Mathf.NextPowerOfTwo(materialCount + 1));
1387 if (m_textInfo.characterInfo.Length - m_totalCharacterCount > 256)
1388 TMP_TextInfo.Resize(ref m_textInfo.characterInfo, Mathf.Max(m_totalCharacterCount + 1, 256),
true);
1392 for (
int i = 0; i < materialCount; i++)
1397 if (m_subTextObjects[i] ==
null)
1402 m_textInfo.meshInfo[i].vertices =
null;
1408 if (m_rectTransform.pivot != m_subTextObjects[i].rectTransform.pivot)
1409 m_subTextObjects[i].rectTransform.pivot = m_rectTransform.pivot;
1412 if (m_subTextObjects[i].sharedMaterial ==
null || m_subTextObjects[i].sharedMaterial.GetInstanceID() != m_materialReferences[i].material.GetInstanceID())
1414 bool isDefaultMaterial = m_materialReferences[i].isDefaultMaterial;
1416 m_subTextObjects[i].isDefaultMaterial = isDefaultMaterial;
1419 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())
1421 m_subTextObjects[i].sharedMaterial = m_materialReferences[i].material;
1422 m_subTextObjects[i].fontAsset = m_materialReferences[i].fontAsset;
1423 m_subTextObjects[i].spriteAsset = m_materialReferences[i].spriteAsset;
1428 if (m_materialReferences[i].isFallbackMaterial)
1430 m_subTextObjects[i].fallbackMaterial = m_materialReferences[i].material;
1431 m_subTextObjects[i].fallbackSourceMaterial = m_materialReferences[i].fallbackMaterial;
1436 int referenceCount = m_materialReferences[i].referenceCount;
1439 if (m_textInfo.meshInfo[i].vertices ==
null || m_textInfo.meshInfo[i].vertices.Length < referenceCount * 4)
1441 if (m_textInfo.meshInfo[i].vertices ==
null)
1444 m_textInfo.meshInfo[i] =
new TMP_MeshInfo(m_mesh, referenceCount + 1);
1446 m_textInfo.meshInfo[i] =
new TMP_MeshInfo(m_subTextObjects[i].
mesh, referenceCount + 1);
1449 m_textInfo.meshInfo[i].
ResizeMeshInfo(referenceCount > 1024 ? referenceCount + 256 : Mathf.NextPowerOfTwo(referenceCount));
1451 else if (m_textInfo.meshInfo[i].vertices.Length - referenceCount * 4 > 1024)
1455 m_textInfo.meshInfo[i].
ResizeMeshInfo(referenceCount > 1024 ? referenceCount + 256 : Mathf.Max(Mathf.NextPowerOfTwo(referenceCount), 256));
1462 for (
int i = materialCount; i < m_subTextObjects.Length && m_subTextObjects[i] !=
null; i++)
1464 if (i < m_textInfo.meshInfo.Length)
1466 m_subTextObjects[i].canvasRenderer.SetMesh(
null);
1474 Profiler.EndSample();
1477 return m_totalCharacterCount;
1498 m_marginWidth = m_rectTransform.rect.width - m_margin.x - m_margin.z;
1499 m_marginHeight = m_rectTransform.rect.height - m_margin.y - m_margin.w;
1512 m_havePropertiesChanged =
true;
1519 protected override void OnCanvasHierarchyChanged()
1521 base.OnCanvasHierarchyChanged();
1522 m_canvas = this.canvas;
1526 protected override void OnTransformParentChanged()
1530 base.OnTransformParentChanged();
1532 m_canvas = this.canvas;
1535 m_havePropertiesChanged =
true;
1539 protected override void OnRectTransformDimensionsChange()
1544 if (!this.gameObject.activeInHierarchy)
1561 if (m_rectTransform.hasChanged)
1564 float lossyScaleY = m_rectTransform.lossyScale.y;
1565 if (!m_havePropertiesChanged && lossyScaleY != m_previousLossyScaleY && m_text !=
string.Empty && m_text !=
null)
1569 m_previousLossyScaleY = lossyScaleY;
1571 m_rectTransform.hasChanged =
false;
1575 if (m_isUsingLegacyAnimationComponent)
1578 m_havePropertiesChanged =
true;
1579 OnPreRenderCanvas();
1586 void OnPreRenderCanvas()
1591 if (!m_isAwake || (this.IsActive() ==
false && m_ignoreActiveState ==
false))
return;
1593 if (m_canvas ==
null) { m_canvas = this.canvas;
if (m_canvas ==
null)
return; }
1613 if (m_havePropertiesChanged || m_isLayoutDirty)
1618 if (checkPaddingRequired)
1622 if (m_isInputParsingRequired || m_isTextTruncated)
1626 if (m_enableAutoSizing)
1627 m_fontSize = Mathf.Clamp(m_fontSizeBase, m_fontSizeMin, m_fontSizeMax);
1629 m_maxFontSize = m_fontSizeMax;
1630 m_minFontSize = m_fontSizeMin;
1631 m_lineSpacingDelta = 0;
1632 m_charWidthAdjDelta = 0;
1635 m_isCharacterWrappingEnabled =
false;
1636 m_isTextTruncated =
false;
1638 m_havePropertiesChanged =
false;
1639 m_isLayoutDirty =
false;
1640 m_ignoreActiveState =
false;
1657 if (m_fontAsset ==
null || m_fontAsset.characterDictionary ==
null)
1659 Debug.LogWarning(
"Can't Generate Mesh! No Font Asset has been assigned to Object ID: " + this.GetInstanceID());
1664 if (m_textInfo !=
null)
1668 if (m_char_buffer ==
null || m_char_buffer.Length == 0 || m_char_buffer[0] == (
char)0)
1673 m_preferredWidth = 0;
1674 m_preferredHeight = 0;
1677 TMPro_EventManager.ON_TEXT_CHANGED(
this);
1682 m_currentFontAsset = m_fontAsset;
1683 m_currentMaterial = m_sharedMaterial;
1684 m_currentMaterialIndex = 0;
1685 m_materialReferenceStack.SetDefault(
new MaterialReference(m_currentMaterialIndex, m_currentFontAsset,
null, m_currentMaterial, m_padding));
1687 m_currentSpriteAsset = m_spriteAsset;
1690 if (m_spriteAnimator !=
null)
1691 m_spriteAnimator.StopAllAnimations();
1694 int totalCharacterCount = m_totalCharacterCount;
1698 float baseScale = m_fontScale = (m_fontSize / m_fontAsset.fontInfo.PointSize * m_fontAsset.fontInfo.Scale);
1699 float currentElementScale = baseScale;
1700 m_fontScaleMultiplier = 1;
1702 m_currentFontSize = m_fontSize;
1704 float fontSizeDelta = 0;
1708 m_style = m_fontStyle;
1709 m_fontWeightInternal = (m_style & FontStyles.Bold) == FontStyles.Bold ? 700 : m_fontWeight;
1710 m_fontWeightStack.
SetDefault(m_fontWeightInternal);
1711 m_fontStyleStack.
Clear();
1713 m_lineJustification = m_textAlignment;
1714 m_lineJustificationStack.
SetDefault(m_lineJustification);
1717 float style_padding = 0;
1718 float bold_xAdvance_multiplier = 1;
1720 m_baselineOffset = 0;
1721 m_baselineOffsetStack.
Clear();
1724 bool beginUnderline =
false;
1725 Vector3 underline_start = Vector3.zero;
1726 Vector3 underline_end = Vector3.zero;
1729 bool beginStrikethrough =
false;
1730 Vector3 strikethrough_start = Vector3.zero;
1731 Vector3 strikethrough_end = Vector3.zero;
1734 bool beginHighlight =
false;
1735 Vector3 highlight_start = Vector3.zero;
1736 Vector3 highlight_end = Vector3.zero;
1738 m_fontColor32 = m_fontColor;
1739 Color32 vertexColor;
1740 m_htmlColor = m_fontColor32;
1741 m_underlineColor = m_htmlColor;
1742 m_strikethroughColor = m_htmlColor;
1745 m_underlineColorStack.
SetDefault(m_htmlColor);
1746 m_strikethroughColorStack.
SetDefault(m_htmlColor);
1747 m_highlightColorStack.
SetDefault(m_htmlColor);
1749 m_colorGradientPreset =
null;
1750 m_colorGradientStack.SetDefault(
null);
1756 m_actionStack.
Clear();
1758 m_isFXMatrixSet =
false;
1761 m_lineHeight = TMP_Math.FLOAT_UNSET;
1762 float lineGap = m_currentFontAsset.
fontInfo.LineHeight - (m_currentFontAsset.
fontInfo.Ascender - m_currentFontAsset.
fontInfo.Descender);
1766 float lineOffsetDelta = 0;
1772 tag_NoParsing =
false;
1775 m_characterCount = 0;
1778 m_firstCharacterOfLine = 0;
1779 m_lastCharacterOfLine = 0;
1780 m_firstVisibleCharacterOfLine = 0;
1781 m_lastVisibleCharacterOfLine = 0;
1782 m_maxLineAscender = k_LargeNegativeFloat;
1783 m_maxLineDescender = k_LargePositiveFloat;
1785 m_lineVisibleCharacterCount = 0;
1786 bool isStartOfNewLine =
true;
1787 m_firstOverflowCharacterIndex = -1;
1790 int pageToDisplay = Mathf.Clamp(m_pageToDisplay - 1, 0, m_textInfo.pageInfo.Length - 1);
1791 int previousPageOverflowChar = 0;
1793 int ellipsisIndex = 0;
1795 Vector4 margins = m_margin;
1796 float marginWidth = m_marginWidth;
1797 float marginHeight = m_marginHeight;
1801 float width = marginWidth + 0.0001f - m_marginLeft - m_marginRight;
1804 m_meshExtents.min = k_LargePositiveVector2;
1805 m_meshExtents.max = k_LargeNegativeVector2;
1814 float pageAscender = 0;
1815 float maxVisibleDescender = 0;
1816 bool isMaxVisibleDescenderSet =
false;
1817 m_isNewPage =
false;
1820 bool isFirstWord =
true;
1821 m_isNonBreakingSpace =
false;
1822 bool ignoreNonBreakingSpace =
false;
1823 bool isLastBreakingChar =
false;
1824 float linebreakingWidth = 0;
1825 int wrappingIndex = 0;
1834 #if TMP_PROFILE_PHASES_ON 1835 Profiler.BeginSample(
"TMP Generate Text - Phase I");
1838 int endTagIndex = 0;
1840 for (
int i = 0; i < m_char_buffer.Length && m_char_buffer[i] != 0; i++)
1842 charCode = m_char_buffer[i];
1848 #region Parse Rich Text Tag 1849 if (m_isRichText && charCode == 60)
1851 m_isParsingText =
true;
1852 m_textElementType = TMP_TextElementType.Character;
1860 if (m_textElementType == TMP_TextElementType.Character)
1866 m_textElementType = m_textInfo.characterInfo[m_characterCount].elementType;
1867 m_currentMaterialIndex = m_textInfo.characterInfo[m_characterCount].materialReferenceIndex;
1868 m_currentFontAsset = m_textInfo.characterInfo[m_characterCount].fontAsset;
1871 #endregion End Parse Rich Text Tag 1873 int prev_MaterialIndex = m_currentMaterialIndex;
1874 bool isUsingAltTypeface = m_textInfo.characterInfo[m_characterCount].isUsingAlternateTypeface;
1876 m_isParsingText =
false;
1879 if (m_characterCount < m_firstVisibleCharacter)
1881 m_textInfo.characterInfo[m_characterCount].isVisible =
false;
1882 m_textInfo.characterInfo[m_characterCount].character = (char)0x200B;
1883 m_characterCount += 1;
1888 #region Handling of LowerCase, UpperCase and SmallCaps Font Styles 1890 Profiler.BeginSample(
"Handle Font Style");
1892 float smallCapsMultiplier = 1.0f;
1894 if (m_textElementType == TMP_TextElementType.Character)
1896 if ((m_style & FontStyles.UpperCase) == FontStyles.UpperCase)
1899 if (
char.IsLower((
char)charCode))
1900 charCode =
char.ToUpper((
char)charCode);
1903 else if ((m_style & FontStyles.LowerCase) == FontStyles.LowerCase)
1906 if (
char.IsUpper((
char)charCode))
1907 charCode =
char.ToLower((
char)charCode);
1909 else if ((m_fontStyle & FontStyles.SmallCaps) == FontStyles.SmallCaps || (m_style & FontStyles.SmallCaps) == FontStyles.SmallCaps)
1911 if (
char.IsLower((
char)charCode))
1913 smallCapsMultiplier = 0.8f;
1914 charCode =
char.ToUpper((
char)charCode);
1919 Profiler.EndSample();
1925 #region Look up Character Data 1927 Profiler.BeginSample(
"Lookup Character Data");
1929 if (m_textElementType == TMP_TextElementType.Sprite)
1932 m_currentSpriteAsset = m_textInfo.characterInfo[m_characterCount].spriteAsset;
1933 m_spriteIndex = m_textInfo.characterInfo[m_characterCount].spriteIndex;
1935 TMP_Sprite sprite = m_currentSpriteAsset.spriteInfoList[m_spriteIndex];
1936 if (sprite ==
null)
continue;
1940 charCode = 57344 + m_spriteIndex;
1942 m_spriteColor = s_colorWhite;
1945 float spriteScale = (m_currentFontSize / m_currentFontAsset.
fontInfo.PointSize * m_currentFontAsset.
fontInfo.Scale);
1946 currentElementScale = m_currentFontAsset.
fontInfo.Ascender / sprite.height * sprite.scale * spriteScale;
1948 m_cached_TextElement = sprite;
1950 m_textInfo.characterInfo[m_characterCount].elementType = TMP_TextElementType.Sprite;
1951 m_textInfo.characterInfo[m_characterCount].scale = spriteScale;
1952 m_textInfo.characterInfo[m_characterCount].spriteAsset = m_currentSpriteAsset;
1953 m_textInfo.characterInfo[m_characterCount].fontAsset = m_currentFontAsset;
1954 m_textInfo.characterInfo[m_characterCount].materialReferenceIndex = m_currentMaterialIndex;
1956 m_currentMaterialIndex = prev_MaterialIndex;
1960 else if (m_textElementType == TMP_TextElementType.Character)
1962 m_cached_TextElement = m_textInfo.characterInfo[m_characterCount].textElement;
1963 if (m_cached_TextElement ==
null)
continue;
1965 m_currentFontAsset = m_textInfo.characterInfo[m_characterCount].fontAsset;
1966 m_currentMaterial = m_textInfo.characterInfo[m_characterCount].material;
1967 m_currentMaterialIndex = m_textInfo.characterInfo[m_characterCount].materialReferenceIndex;
1970 m_fontScale = m_currentFontSize * smallCapsMultiplier / m_currentFontAsset.
fontInfo.PointSize * m_currentFontAsset.
fontInfo.Scale;
1972 currentElementScale = m_fontScale * m_fontScaleMultiplier * m_cached_TextElement.scale;
1974 m_textInfo.characterInfo[m_characterCount].elementType = TMP_TextElementType.Character;
1975 m_textInfo.characterInfo[m_characterCount].scale = currentElementScale;
1977 padding = m_currentMaterialIndex == 0 ? m_padding : m_subTextObjects[m_currentMaterialIndex].padding;
1980 Profiler.EndSample();
1986 #region Handle Soft Hyphen 1987 float old_scale = currentElementScale;
1988 if (charCode == 0xAD)
1990 currentElementScale = 0;
1996 m_textInfo.characterInfo[m_characterCount].character = (char)charCode;
1997 m_textInfo.characterInfo[m_characterCount].pointSize = m_currentFontSize;
1998 m_textInfo.characterInfo[m_characterCount].color = m_htmlColor;
1999 m_textInfo.characterInfo[m_characterCount].underlineColor = m_underlineColor;
2000 m_textInfo.characterInfo[m_characterCount].strikethroughColor = m_strikethroughColor;
2001 m_textInfo.characterInfo[m_characterCount].highlightColor = m_highlightColor;
2002 m_textInfo.characterInfo[m_characterCount].style = m_style;
2003 m_textInfo.characterInfo[m_characterCount].
index = i;
2008 #region Handle Kerning 2010 if (m_enableKerning)
2014 if (m_characterCount < totalCharacterCount - 1)
2016 uint nextGlyph = m_textInfo.characterInfo[m_characterCount + 1].character;
2019 m_currentFontAsset.
kerningDictionary.TryGetValue((
int)keyValue.key, out adjustmentPair);
2020 if (adjustmentPair !=
null)
2021 glyphAdjustments = adjustmentPair.firstGlyphAdjustments;
2024 if (m_characterCount >= 1)
2026 uint previousGlyph = m_textInfo.characterInfo[m_characterCount - 1].character;
2029 m_currentFontAsset.
kerningDictionary.TryGetValue((
int)keyValue.key, out adjustmentPair);
2030 if (adjustmentPair !=
null)
2031 glyphAdjustments += adjustmentPair.secondGlyphAdjustments;
2038 #region Handle Right-to-Left 2039 if (m_isRightToLeft)
2041 m_xAdvance -= ((m_cached_TextElement.xAdvance * bold_xAdvance_multiplier + m_characterSpacing + m_wordSpacing + m_currentFontAsset.normalSpacingOffset) * currentElementScale + m_cSpacing) * (1 - m_charWidthAdjDelta);
2043 if (
char.IsWhiteSpace((
char)charCode) || charCode == 0x200B)
2044 m_xAdvance -= m_wordSpacing * currentElementScale;
2050 #region Handle Mono Spacing 2051 float monoAdvance = 0;
2052 if (m_monoSpacing != 0)
2054 monoAdvance = (m_monoSpacing / 2 - (m_cached_TextElement.width / 2 + m_cached_TextElement.xOffset) * currentElementScale) * (1 - m_charWidthAdjDelta);
2055 m_xAdvance += monoAdvance;
2061 #region Handle Style Padding 2062 if (m_textElementType == TMP_TextElementType.Character && !isUsingAltTypeface && ((m_style & FontStyles.Bold) == FontStyles.Bold || (m_fontStyle & FontStyles.Bold) == FontStyles.Bold))
2064 if (m_currentMaterial.HasProperty(ShaderUtilities.ID_GradientScale))
2066 float gradientScale = m_currentMaterial.GetFloat(ShaderUtilities.ID_GradientScale);
2067 style_padding = m_currentFontAsset.boldStyle / 4.0f * gradientScale * m_currentMaterial.GetFloat(ShaderUtilities.ID_ScaleRatio_A);
2070 if (style_padding + padding > gradientScale)
2071 padding = gradientScale - style_padding;
2076 bold_xAdvance_multiplier = 1 + m_currentFontAsset.boldSpacing * 0.01f;
2080 if (m_currentMaterial.HasProperty(ShaderUtilities.ID_GradientScale))
2082 float gradientScale = m_currentMaterial.GetFloat(ShaderUtilities.ID_GradientScale);
2083 style_padding = m_currentFontAsset.normalStyle / 4.0f * gradientScale * m_currentMaterial.GetFloat(ShaderUtilities.ID_ScaleRatio_A);
2086 if (style_padding + padding > gradientScale)
2087 padding = gradientScale - style_padding;
2092 bold_xAdvance_multiplier = 1.0f;
2094 #endregion Handle Style Padding 2098 #region Calculate Vertices Position 2100 Profiler.BeginSample(
"Calculate Vertices Position");
2102 float fontBaseLineOffset = m_currentFontAsset.
fontInfo.Baseline * m_fontScale * m_fontScaleMultiplier * m_currentFontAsset.
fontInfo.Scale;
2104 top_left.x = m_xAdvance + ((m_cached_TextElement.xOffset - padding - style_padding + glyphAdjustments.xPlacement) * currentElementScale * (1 - m_charWidthAdjDelta));
2105 top_left.y = fontBaseLineOffset + (m_cached_TextElement.yOffset + padding + glyphAdjustments.yPlacement) * currentElementScale - m_lineOffset + m_baselineOffset;
2108 Vector3 bottom_left;
2109 bottom_left.x = top_left.x;
2110 bottom_left.y = top_left.y - ((m_cached_TextElement.height + padding * 2) * currentElementScale);
2114 top_right.x = bottom_left.x + ((m_cached_TextElement.width + padding * 2 + style_padding * 2) * currentElementScale * (1 - m_charWidthAdjDelta));
2115 top_right.y = top_left.y;
2118 Vector3 bottom_right;
2119 bottom_right.x = top_right.x;
2120 bottom_right.y = bottom_left.y;
2124 Profiler.EndSample();
2130 #region Handle Italic & Shearing 2131 if (m_textElementType == TMP_TextElementType.Character && !isUsingAltTypeface && ((m_style & FontStyles.Italic) == FontStyles.Italic || (m_fontStyle & FontStyles.Italic) == FontStyles.Italic))
2134 float shear_value = m_currentFontAsset.italicStyle * 0.01f;
2135 Vector3 topShear =
new Vector3(shear_value * ((m_cached_TextElement.yOffset + padding + style_padding) * currentElementScale), 0, 0);
2136 Vector3 bottomShear =
new Vector3(shear_value * (((m_cached_TextElement.yOffset - m_cached_TextElement.height - padding - style_padding)) * currentElementScale), 0, 0);
2138 top_left = top_left + topShear;
2139 bottom_left = bottom_left + bottomShear;
2140 top_right = top_right + topShear;
2141 bottom_right = bottom_right + bottomShear;
2143 #endregion Handle Italics & Shearing 2147 #region Handle Character Rotation 2148 if (m_isFXMatrixSet)
2151 if (m_FXMatrix.m00 != 1)
2159 Vector3 positionOffset = (top_right + bottom_left) / 2;
2161 top_left = m_FXMatrix.MultiplyPoint3x4(top_left - positionOffset) + positionOffset;
2162 bottom_left = m_FXMatrix.MultiplyPoint3x4(bottom_left - positionOffset) + positionOffset;
2163 top_right = m_FXMatrix.MultiplyPoint3x4(top_right - positionOffset) + positionOffset;
2164 bottom_right = m_FXMatrix.MultiplyPoint3x4(bottom_right - positionOffset) + positionOffset;
2170 m_textInfo.characterInfo[m_characterCount].bottomLeft = bottom_left;
2171 m_textInfo.characterInfo[m_characterCount].topLeft = top_left;
2172 m_textInfo.characterInfo[m_characterCount].topRight = top_right;
2173 m_textInfo.characterInfo[m_characterCount].bottomRight = bottom_right;
2175 m_textInfo.characterInfo[m_characterCount].origin = m_xAdvance;
2176 m_textInfo.characterInfo[m_characterCount].baseLine = fontBaseLineOffset - m_lineOffset + m_baselineOffset;
2177 m_textInfo.characterInfo[m_characterCount].aspectRatio = (top_right.x - bottom_left.x) / (top_left.y - bottom_left.y);
2181 float elementAscender = m_currentFontAsset.
fontInfo.Ascender * (m_textElementType == TMP_TextElementType.Character ? currentElementScale / smallCapsMultiplier : m_textInfo.characterInfo[m_characterCount].scale) + m_baselineOffset;
2182 m_textInfo.characterInfo[m_characterCount].ascender = elementAscender - m_lineOffset;
2183 m_maxLineAscender = elementAscender > m_maxLineAscender ? elementAscender : m_maxLineAscender;
2186 float elementDescender = m_currentFontAsset.
fontInfo.Descender * (m_textElementType == TMP_TextElementType.Character ? currentElementScale / smallCapsMultiplier : m_textInfo.characterInfo[m_characterCount].scale) + m_baselineOffset;
2187 float elementDescenderII = m_textInfo.characterInfo[m_characterCount].descender = elementDescender - m_lineOffset;
2188 m_maxLineDescender = elementDescender < m_maxLineDescender ? elementDescender : m_maxLineDescender;
2191 if ((m_style & FontStyles.Subscript) == FontStyles.Subscript || (m_style & FontStyles.Superscript) == FontStyles.Superscript)
2193 float baseAscender = (elementAscender - m_baselineOffset) / m_currentFontAsset.
fontInfo.SubSize;
2194 elementAscender = m_maxLineAscender;
2195 m_maxLineAscender = baseAscender > m_maxLineAscender ? baseAscender : m_maxLineAscender;
2197 float baseDescender = (elementDescender - m_baselineOffset) / m_currentFontAsset.
fontInfo.SubSize;
2198 elementDescender = m_maxLineDescender;
2199 m_maxLineDescender = baseDescender < m_maxLineDescender ? baseDescender : m_maxLineDescender;
2202 if (m_lineNumber == 0 || m_isNewPage)
2204 m_maxAscender = m_maxAscender > elementAscender ? m_maxAscender : elementAscender;
2205 m_maxCapHeight = Mathf.Max(m_maxCapHeight, m_currentFontAsset.
fontInfo.CapHeight * currentElementScale / smallCapsMultiplier);
2207 if (m_lineOffset == 0) pageAscender = pageAscender > elementAscender ? pageAscender : elementAscender;
2211 m_textInfo.characterInfo[m_characterCount].isVisible =
false;
2214 #region Handle Visible Characters 2218 if (charCode == 9 || charCode == 0xA0 || charCode == 0x2007 || (!
char.IsWhiteSpace((
char)charCode) && charCode != 0x200B) || m_textElementType == TMP_TextElementType.Sprite)
2220 m_textInfo.characterInfo[m_characterCount].isVisible =
true;
2222 #region Experimental Margin Shaper 2257 width = m_width != -1 ? Mathf.Min(marginWidth + 0.0001f - m_marginLeft - m_marginRight, m_width) : marginWidth + 0.0001f - m_marginLeft - m_marginRight;
2258 m_textInfo.lineInfo[m_lineNumber].marginLeft = m_marginLeft;
2263 linebreakingWidth = Mathf.Abs(m_xAdvance) + (!m_isRightToLeft ? m_cached_TextElement.xAdvance : 0) * (1 - m_charWidthAdjDelta) * (charCode != 0xAD ? currentElementScale : old_scale);
2266 #region Handle Line Breaking, Text Auto-Sizing and Horizontal Overflow 2267 if (linebreakingWidth > width * (isJustifiedOrFlush ? 1.05f : 1.0f))
2269 ellipsisIndex = m_characterCount - 1;
2272 #region Handle Word Wrapping 2276 #region Line Breaking Check 2277 if (wrappingIndex == m_SavedWordWrapState.previous_WordBreak || isFirstWord)
2280 if (m_enableAutoSizing && m_fontSize > m_fontSizeMin)
2283 #region Character Width Adjustments 2284 if (m_charWidthAdjDelta < m_charWidthMaxAdj / 100)
2287 m_charWidthAdjDelta += 0.01f;
2294 m_maxFontSize = m_fontSize;
2296 m_fontSize -= Mathf.Max((m_fontSize - m_minFontSize) / 2, 0.05f);
2297 m_fontSize = (int)(Mathf.Max(m_fontSize, m_fontSizeMin) * 20 + 0.5f) / 20f;
2299 if (loopCountA > 20)
return;
2305 if (m_isCharacterWrappingEnabled ==
false)
2307 if (ignoreNonBreakingSpace ==
false)
2308 ignoreNonBreakingSpace =
true;
2310 m_isCharacterWrappingEnabled =
true;
2313 isLastBreakingChar =
true;
2329 if (m_char_buffer[i] == 0xAD)
2331 m_isTextTruncated =
true;
2332 m_char_buffer[i] = 0x2D;
2340 if (m_lineNumber > 0 && !TMP_Math.Approximately(m_maxLineAscender, m_startOfLineAscender) && m_lineHeight == TMP_Math.FLOAT_UNSET && !m_isNewPage)
2343 float offsetDelta = m_maxLineAscender - m_startOfLineAscender;
2345 m_lineOffset += offsetDelta;
2346 m_SavedWordWrapState.lineOffset = m_lineOffset;
2347 m_SavedWordWrapState.previousLineAscender = m_maxLineAscender;
2351 m_isNewPage =
false;
2354 float lineAscender = m_maxLineAscender - m_lineOffset;
2355 float lineDescender = m_maxLineDescender - m_lineOffset;
2359 m_maxDescender = m_maxDescender < lineDescender ? m_maxDescender : lineDescender;
2360 if (!isMaxVisibleDescenderSet)
2361 maxVisibleDescender = m_maxDescender;
2363 if (m_useMaxVisibleDescender && (m_characterCount >= m_maxVisibleCharacters || m_lineNumber >= m_maxVisibleLines))
2364 isMaxVisibleDescenderSet =
true;
2367 m_textInfo.lineInfo[m_lineNumber].firstCharacterIndex = m_firstCharacterOfLine;
2368 m_textInfo.lineInfo[m_lineNumber].firstVisibleCharacterIndex = m_firstVisibleCharacterOfLine = m_firstCharacterOfLine > m_firstVisibleCharacterOfLine ? m_firstCharacterOfLine : m_firstVisibleCharacterOfLine;
2369 m_textInfo.lineInfo[m_lineNumber].lastCharacterIndex = m_lastCharacterOfLine = m_characterCount - 1 > 0 ? m_characterCount - 1 : 0;
2370 m_textInfo.lineInfo[m_lineNumber].lastVisibleCharacterIndex = m_lastVisibleCharacterOfLine = m_lastVisibleCharacterOfLine < m_firstVisibleCharacterOfLine ? m_firstVisibleCharacterOfLine : m_lastVisibleCharacterOfLine;
2372 m_textInfo.lineInfo[m_lineNumber].characterCount = m_textInfo.lineInfo[m_lineNumber].lastCharacterIndex - m_textInfo.lineInfo[m_lineNumber].firstCharacterIndex + 1;
2373 m_textInfo.lineInfo[m_lineNumber].visibleCharacterCount = m_lineVisibleCharacterCount;
2374 m_textInfo.lineInfo[m_lineNumber].lineExtents.min =
new Vector2(m_textInfo.characterInfo[m_firstVisibleCharacterOfLine].bottomLeft.x, lineDescender);
2375 m_textInfo.lineInfo[m_lineNumber].lineExtents.max =
new Vector2(m_textInfo.characterInfo[m_lastVisibleCharacterOfLine].topRight.x, lineAscender);
2376 m_textInfo.lineInfo[m_lineNumber].length = m_textInfo.lineInfo[m_lineNumber].lineExtents.max.x;
2377 m_textInfo.lineInfo[m_lineNumber].width = width;
2381 m_textInfo.lineInfo[m_lineNumber].maxAdvance = m_textInfo.characterInfo[m_lastVisibleCharacterOfLine].xAdvance - (m_characterSpacing + m_currentFontAsset.normalSpacingOffset) * currentElementScale - m_cSpacing;
2383 m_textInfo.lineInfo[m_lineNumber].baseline = 0 - m_lineOffset;
2384 m_textInfo.lineInfo[m_lineNumber].ascender = lineAscender;
2385 m_textInfo.lineInfo[m_lineNumber].descender = lineDescender;
2386 m_textInfo.lineInfo[m_lineNumber].lineHeight = lineAscender - lineDescender + lineGap * baseScale;
2388 m_firstCharacterOfLine = m_characterCount;
2389 m_lineVisibleCharacterCount = 0;
2395 isStartOfNewLine =
true;
2399 if (m_lineNumber >= m_textInfo.lineInfo.Length)
2403 if (m_lineHeight == TMP_Math.FLOAT_UNSET)
2405 float ascender = m_textInfo.characterInfo[m_characterCount].ascender - m_textInfo.characterInfo[m_characterCount].baseLine;
2406 lineOffsetDelta = 0 - m_maxLineDescender + ascender + (lineGap + m_lineSpacing + m_lineSpacingDelta) * baseScale;
2407 m_lineOffset += lineOffsetDelta;
2409 m_startOfLineAscender = ascender;
2412 m_lineOffset += m_lineHeight + m_lineSpacing * baseScale;
2414 m_maxLineAscender = k_LargeNegativeFloat;
2415 m_maxLineDescender = k_LargePositiveFloat;
2417 m_xAdvance = 0 + tag_Indent;
2421 #endregion End Word Wrapping 2425 #region Handle Text Auto-Sizing 2426 if (m_enableAutoSizing && m_fontSize > m_fontSizeMin)
2429 #region Character Width Adjustments 2430 if (m_charWidthAdjDelta < m_charWidthMaxAdj / 100)
2433 m_charWidthAdjDelta += 0.01f;
2440 m_maxFontSize = m_fontSize;
2442 m_fontSize -= Mathf.Max((m_fontSize - m_minFontSize) / 2, 0.05f);
2443 m_fontSize = (int)(Mathf.Max(m_fontSize, m_fontSizeMin) * 20 + 0.5f) / 20f;
2446 if (loopCountA > 20)
return;
2450 #endregion End Text Auto-Sizing 2454 #region Handle Text Overflow 2455 switch (m_overflowMode)
2457 case TextOverflowModes.Overflow:
2458 if (m_isMaskingEnabled)
2462 case TextOverflowModes.Ellipsis:
2463 if (m_isMaskingEnabled)
2466 m_isTextTruncated =
true;
2468 if (m_characterCount < 1)
2470 m_textInfo.characterInfo[m_characterCount].isVisible =
false;
2475 m_char_buffer[i - 1] = 8230;
2476 m_char_buffer[i] = (char)0;
2478 if (m_cached_Ellipsis_GlyphInfo !=
null)
2480 m_textInfo.characterInfo[ellipsisIndex].character = (char)8230;
2481 m_textInfo.characterInfo[ellipsisIndex].textElement = m_cached_Ellipsis_GlyphInfo;
2482 m_textInfo.characterInfo[ellipsisIndex].fontAsset = m_materialReferences[0].fontAsset;
2483 m_textInfo.characterInfo[ellipsisIndex].material = m_materialReferences[0].material;
2484 m_textInfo.characterInfo[ellipsisIndex].materialReferenceIndex = 0;
2488 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);
2491 m_totalCharacterCount = ellipsisIndex + 1;
2495 case TextOverflowModes.Masking:
2496 if (!m_isMaskingEnabled)
2499 case TextOverflowModes.ScrollRect:
2500 if (!m_isMaskingEnabled)
2503 case TextOverflowModes.Truncate:
2504 if (m_isMaskingEnabled)
2507 m_textInfo.characterInfo[m_characterCount].isVisible =
false;
2509 case TextOverflowModes.Linked:
2520 #endregion End Text Overflow 2523 #endregion End Check for Characters Exceeding Width of Text Container 2527 if (charCode == 9 || charCode == 0xA0 || charCode == 0x2007)
2529 m_textInfo.characterInfo[m_characterCount].isVisible =
false;
2530 m_lastVisibleCharacterOfLine = m_characterCount;
2531 m_textInfo.lineInfo[m_lineNumber].spaceCount += 1;
2532 m_textInfo.spaceCount += 1;
2534 if (charCode == 0xA0)
2535 m_textInfo.lineInfo[m_lineNumber].controlCharacterCount += 1;
2540 if (m_overrideHtmlColors)
2541 vertexColor = m_fontColor32;
2543 vertexColor = m_htmlColor;
2546 if (m_textElementType == TMP_TextElementType.Character)
2551 else if (m_textElementType == TMP_TextElementType.Sprite)
2559 if (m_textInfo.characterInfo[m_characterCount].isVisible && charCode != 0xAD)
2561 if (isStartOfNewLine) { isStartOfNewLine =
false; m_firstVisibleCharacterOfLine = m_characterCount; }
2563 m_lineVisibleCharacterCount += 1;
2564 m_lastVisibleCharacterOfLine = m_characterCount;
2571 if ((charCode == 10 ||
char.IsSeparator((
char)charCode)) && charCode != 0xAD && charCode != 0x200B && charCode != 0x2060)
2573 m_textInfo.lineInfo[m_lineNumber].spaceCount += 1;
2574 m_textInfo.spaceCount += 1;
2580 #endregion Handle Visible Characters 2584 #region Adjust Line Spacing 2586 Profiler.BeginSample(
"Adjust Line Spacing");
2588 if (m_lineNumber > 0 && !TMP_Math.Approximately(m_maxLineAscender, m_startOfLineAscender) && m_lineHeight == TMP_Math.FLOAT_UNSET && !m_isNewPage)
2593 float offsetDelta = m_maxLineAscender - m_startOfLineAscender;
2595 elementDescenderII -= offsetDelta;
2596 m_lineOffset += offsetDelta;
2598 m_startOfLineAscender += offsetDelta;
2599 m_SavedWordWrapState.lineOffset = m_lineOffset;
2600 m_SavedWordWrapState.previousLineAscender = m_startOfLineAscender;
2603 Profiler.EndSample();
2609 #region Store Character Data 2610 m_textInfo.characterInfo[m_characterCount].lineNumber = m_lineNumber;
2611 m_textInfo.characterInfo[m_characterCount].pageNumber = m_pageNumber;
2613 if (charCode != 10 && charCode != 13 && charCode != 8230 || m_textInfo.lineInfo[m_lineNumber].characterCount == 1)
2614 m_textInfo.lineInfo[m_lineNumber].alignment = m_lineJustification;
2615 #endregion Store Character Data 2619 #region Check Vertical Bounds & Auto-Sizing 2621 Profiler.BeginSample(
"Check Vertical Bounds");
2623 if (m_maxAscender - elementDescenderII > marginHeight + 0.0001f)
2626 #region Line Spacing Adjustments 2627 if (m_enableAutoSizing && m_lineSpacingDelta > m_lineSpacingMax && m_lineNumber > 0)
2631 m_lineSpacingDelta -= 1;
2639 #region Text Auto-Sizing (Text greater than vertical bounds) 2640 if (m_enableAutoSizing && m_fontSize > m_fontSizeMin)
2642 m_maxFontSize = m_fontSize;
2644 m_fontSize -= Mathf.Max((m_fontSize - m_minFontSize) / 2, 0.05f);
2645 m_fontSize = (int)(Mathf.Max(m_fontSize, m_fontSizeMin) * 20 + 0.5f) / 20f;
2648 if (loopCountA > 20)
return;
2652 #endregion Text Auto-Sizing 2655 if (m_firstOverflowCharacterIndex == -1)
2656 m_firstOverflowCharacterIndex = m_characterCount;
2659 #region Text Overflow 2660 switch (m_overflowMode)
2662 case TextOverflowModes.Overflow:
2663 if (m_isMaskingEnabled)
2667 case TextOverflowModes.Ellipsis:
2668 if (m_isMaskingEnabled)
2671 if (m_lineNumber > 0)
2673 m_char_buffer[m_textInfo.characterInfo[ellipsisIndex].
index] = 8230;
2674 m_char_buffer[m_textInfo.characterInfo[ellipsisIndex].
index + 1] = (char)0;
2676 if (m_cached_Ellipsis_GlyphInfo !=
null)
2678 m_textInfo.characterInfo[ellipsisIndex].character = (char)8230;
2679 m_textInfo.characterInfo[ellipsisIndex].textElement = m_cached_Ellipsis_GlyphInfo;
2680 m_textInfo.characterInfo[ellipsisIndex].fontAsset = m_materialReferences[0].fontAsset;
2681 m_textInfo.characterInfo[ellipsisIndex].material = m_materialReferences[0].material;
2682 m_textInfo.characterInfo[ellipsisIndex].materialReferenceIndex = 0;
2686 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);
2689 m_totalCharacterCount = ellipsisIndex + 1;
2692 m_isTextTruncated =
true;
2700 case TextOverflowModes.Masking:
2701 if (!m_isMaskingEnabled)
2704 case TextOverflowModes.ScrollRect:
2705 if (!m_isMaskingEnabled)
2708 case TextOverflowModes.Truncate:
2709 if (m_isMaskingEnabled)
2713 if (m_lineNumber > 0)
2715 m_char_buffer[m_textInfo.characterInfo[ellipsisIndex].
index + 1] = (char)0;
2717 m_totalCharacterCount = ellipsisIndex + 1;
2720 m_isTextTruncated =
true;
2728 case TextOverflowModes.Page:
2729 if (m_isMaskingEnabled)
2733 if (charCode == 13 || charCode == 10)
2742 else if (previousPageOverflowChar == i)
2744 m_char_buffer[i] = 0;
2745 m_isTextTruncated =
true;
2748 previousPageOverflowChar = i;
2754 m_xAdvance = 0 + tag_Indent;
2761 case TextOverflowModes.Linked:
2762 if (m_linkedTextComponent !=
null)
2770 if (m_lineNumber > 0)
2772 m_char_buffer[i] = (char)0;
2774 m_totalCharacterCount = m_characterCount;
2778 m_isTextTruncated =
true;
2787 #endregion End Text Overflow 2791 Profiler.EndSample();
2793 #endregion Check Vertical Bounds 2797 #region XAdvance, Tabulation & Stops 2800 float tabSize = m_currentFontAsset.
fontInfo.TabWidth * currentElementScale;
2801 float tabs = Mathf.Ceil(m_xAdvance / tabSize) * tabSize;
2802 m_xAdvance = tabs > m_xAdvance ? tabs : m_xAdvance + tabSize;
2804 else if (m_monoSpacing != 0)
2806 m_xAdvance += (m_monoSpacing - monoAdvance + ((m_characterSpacing + m_currentFontAsset.normalSpacingOffset) * currentElementScale) + m_cSpacing) * (1 - m_charWidthAdjDelta);
2808 if (
char.IsWhiteSpace((
char)charCode) || charCode == 0x200B)
2809 m_xAdvance += m_wordSpacing * currentElementScale;
2811 else if (!m_isRightToLeft)
2813 float scaleFXMultiplier = 1;
2814 if (m_isFXMatrixSet) scaleFXMultiplier = m_FXMatrix.m00;
2816 m_xAdvance += ((m_cached_TextElement.xAdvance * scaleFXMultiplier * bold_xAdvance_multiplier + m_characterSpacing + m_currentFontAsset.normalSpacingOffset + glyphAdjustments.xAdvance) * currentElementScale + m_cSpacing) * (1 - m_charWidthAdjDelta);
2818 if (
char.IsWhiteSpace((
char)charCode) || charCode == 0x200B)
2819 m_xAdvance += m_wordSpacing * currentElementScale;
2823 m_xAdvance -= glyphAdjustments.xAdvance * currentElementScale;
2828 m_textInfo.characterInfo[m_characterCount].xAdvance = m_xAdvance;
2830 #endregion Tabulation & Stops 2834 #region Carriage Return 2837 m_xAdvance = 0 + tag_Indent;
2839 #endregion Carriage Return 2843 #region Check for Line Feed and Last Character 2845 Profiler.BeginSample(
"Process Linefeed");
2847 if (charCode == 10 || m_characterCount == totalCharacterCount - 1)
2850 if (m_lineNumber > 0 && !TMP_Math.Approximately(m_maxLineAscender, m_startOfLineAscender) && m_lineHeight == TMP_Math.FLOAT_UNSET && !m_isNewPage)
2853 float offsetDelta = m_maxLineAscender - m_startOfLineAscender;
2855 elementDescenderII -= offsetDelta;
2856 m_lineOffset += offsetDelta;
2858 m_isNewPage =
false;
2861 float lineAscender = m_maxLineAscender - m_lineOffset;
2862 float lineDescender = m_maxLineDescender - m_lineOffset;
2865 m_maxDescender = m_maxDescender < lineDescender ? m_maxDescender : lineDescender;
2866 if (!isMaxVisibleDescenderSet)
2867 maxVisibleDescender = m_maxDescender;
2869 if (m_useMaxVisibleDescender && (m_characterCount >= m_maxVisibleCharacters || m_lineNumber >= m_maxVisibleLines))
2870 isMaxVisibleDescenderSet =
true;
2873 m_textInfo.lineInfo[m_lineNumber].firstCharacterIndex = m_firstCharacterOfLine;
2874 m_textInfo.lineInfo[m_lineNumber].firstVisibleCharacterIndex = m_firstVisibleCharacterOfLine = m_firstCharacterOfLine > m_firstVisibleCharacterOfLine ? m_firstCharacterOfLine : m_firstVisibleCharacterOfLine;
2875 m_textInfo.lineInfo[m_lineNumber].lastCharacterIndex = m_lastCharacterOfLine = m_characterCount;
2876 m_textInfo.lineInfo[m_lineNumber].lastVisibleCharacterIndex = m_lastVisibleCharacterOfLine = m_lastVisibleCharacterOfLine < m_firstVisibleCharacterOfLine ? m_firstVisibleCharacterOfLine : m_lastVisibleCharacterOfLine;
2878 m_textInfo.lineInfo[m_lineNumber].characterCount = m_textInfo.lineInfo[m_lineNumber].lastCharacterIndex - m_textInfo.lineInfo[m_lineNumber].firstCharacterIndex + 1;
2879 m_textInfo.lineInfo[m_lineNumber].visibleCharacterCount = m_lineVisibleCharacterCount;
2880 m_textInfo.lineInfo[m_lineNumber].lineExtents.min =
new Vector2(m_textInfo.characterInfo[m_firstVisibleCharacterOfLine].bottomLeft.x, lineDescender);
2881 m_textInfo.lineInfo[m_lineNumber].lineExtents.max =
new Vector2(m_textInfo.characterInfo[m_lastVisibleCharacterOfLine].topRight.x, lineAscender);
2882 m_textInfo.lineInfo[m_lineNumber].length = m_textInfo.lineInfo[m_lineNumber].lineExtents.max.x - (padding * currentElementScale);
2883 m_textInfo.lineInfo[m_lineNumber].width = width;
2885 if (m_textInfo.lineInfo[m_lineNumber].characterCount == 1)
2886 m_textInfo.lineInfo[m_lineNumber].alignment = m_lineJustification;
2888 if (m_textInfo.characterInfo[m_lastVisibleCharacterOfLine].isVisible)
2889 m_textInfo.lineInfo[m_lineNumber].maxAdvance = m_textInfo.characterInfo[m_lastVisibleCharacterOfLine].xAdvance - (m_characterSpacing + m_currentFontAsset.normalSpacingOffset) * currentElementScale - m_cSpacing;
2891 m_textInfo.lineInfo[m_lineNumber].maxAdvance = m_textInfo.characterInfo[m_lastCharacterOfLine].xAdvance - (m_characterSpacing + m_currentFontAsset.normalSpacingOffset) * currentElementScale - m_cSpacing;
2893 m_textInfo.lineInfo[m_lineNumber].baseline = 0 - m_lineOffset;
2894 m_textInfo.lineInfo[m_lineNumber].ascender = lineAscender;
2895 m_textInfo.lineInfo[m_lineNumber].descender = lineDescender;
2896 m_textInfo.lineInfo[m_lineNumber].lineHeight = lineAscender - lineDescender + lineGap * baseScale;
2898 m_firstCharacterOfLine = m_characterCount + 1;
2899 m_lineVisibleCharacterCount = 0;
2910 isStartOfNewLine =
true;
2911 ignoreNonBreakingSpace =
false;
2915 if (m_lineNumber >= m_textInfo.lineInfo.Length)
2919 if (m_lineHeight == TMP_Math.FLOAT_UNSET)
2921 lineOffsetDelta = 0 - m_maxLineDescender + elementAscender + (lineGap + m_lineSpacing + m_paragraphSpacing + m_lineSpacingDelta) * baseScale;
2922 m_lineOffset += lineOffsetDelta;
2925 m_lineOffset += m_lineHeight + (m_lineSpacing + m_paragraphSpacing) * baseScale;
2927 m_maxLineAscender = k_LargeNegativeFloat;
2928 m_maxLineDescender = k_LargePositiveFloat;
2929 m_startOfLineAscender = elementAscender;
2931 m_xAdvance = 0 + tag_LineIndent + tag_Indent;
2933 ellipsisIndex = m_characterCount - 1;
2935 m_characterCount += 1;
2940 Profiler.EndSample();
2942 #endregion Check for Linefeed or Last Character 2946 #region Save CharacterInfo for the current character. 2948 Profiler.BeginSample(
"Save CharacterInfo & Extents");
2951 if (m_textInfo.characterInfo[m_characterCount].isVisible)
2953 m_meshExtents.min.x = Mathf.Min(m_meshExtents.min.x, m_textInfo.characterInfo[m_characterCount].bottomLeft.x);
2954 m_meshExtents.min.y = Mathf.Min(m_meshExtents.min.y, m_textInfo.characterInfo[m_characterCount].bottomLeft.y);
2956 m_meshExtents.max.x = Mathf.Max(m_meshExtents.max.x, m_textInfo.characterInfo[m_characterCount].topRight.x);
2957 m_meshExtents.max.y = Mathf.Max(m_meshExtents.max.y, m_textInfo.characterInfo[m_characterCount].topRight.y);
2965 if (m_overflowMode == TextOverflowModes.Page && charCode != 13 && charCode != 10)
2968 if (m_pageNumber + 1 > m_textInfo.pageInfo.Length)
2969 TMP_TextInfo.Resize(ref m_textInfo.pageInfo, m_pageNumber + 1,
true);
2971 m_textInfo.pageInfo[m_pageNumber].ascender = pageAscender;
2972 m_textInfo.pageInfo[m_pageNumber].descender = elementDescender < m_textInfo.pageInfo[m_pageNumber].descender ? elementDescender : m_textInfo.pageInfo[m_pageNumber].descender;
2974 if (m_pageNumber == 0 && m_characterCount == 0)
2975 m_textInfo.pageInfo[m_pageNumber].firstCharacterIndex = m_characterCount;
2976 else if (m_characterCount > 0 && m_pageNumber != m_textInfo.characterInfo[m_characterCount - 1].pageNumber)
2978 m_textInfo.pageInfo[m_pageNumber - 1].lastCharacterIndex = m_characterCount - 1;
2979 m_textInfo.pageInfo[m_pageNumber].firstCharacterIndex = m_characterCount;
2981 else if (m_characterCount == totalCharacterCount - 1)
2982 m_textInfo.pageInfo[m_pageNumber].lastCharacterIndex = m_characterCount;
2985 Profiler.EndSample();
2987 #endregion Saving CharacterInfo 2991 #region Save Word Wrapping State 2993 Profiler.BeginSample(
"Save Word Wrapping State");
2995 if (m_enableWordWrapping || m_overflowMode == TextOverflowModes.Truncate || m_overflowMode == TextOverflowModes.Ellipsis)
2997 if ((
char.IsWhiteSpace((
char)charCode) || charCode == 0x200B || charCode == 0x2D || charCode == 0xAD) && (!m_isNonBreakingSpace || ignoreNonBreakingSpace) && charCode != 0xA0 && charCode != 0x2007 && charCode != 0x2011 && charCode != 0x202F && charCode != 0x2060)
3002 m_isCharacterWrappingEnabled =
false;
3003 isFirstWord =
false;
3006 else if (( charCode > 0x1100 && charCode < 0x11ff ||
3007 charCode > 0x2E80 && charCode < 0x9FFF ||
3008 charCode > 0xA960 && charCode < 0xA97F ||
3009 charCode > 0xAC00 && charCode < 0xD7FF ||
3010 charCode > 0xF900 && charCode < 0xFAFF ||
3011 charCode > 0xFE30 && charCode < 0xFE4F ||
3012 charCode > 0xFF00 && charCode < 0xFFEF)
3013 && !m_isNonBreakingSpace)
3016 (m_characterCount < totalCharacterCount - 1 &&
3020 m_isCharacterWrappingEnabled =
false;
3021 isFirstWord =
false;
3024 else if ((isFirstWord || m_isCharacterWrappingEnabled ==
true || isLastBreakingChar))
3029 Profiler.EndSample();
3031 #endregion Save Word Wrapping State 3033 m_characterCount += 1;
3037 #region Check Auto-Sizing (Upper Font Size Bounds) 3038 fontSizeDelta = m_maxFontSize - m_minFontSize;
3039 if (!m_isCharacterWrappingEnabled && m_enableAutoSizing && fontSizeDelta > 0.051f && m_fontSize < m_fontSizeMax)
3041 m_minFontSize = m_fontSize;
3042 m_fontSize += Mathf.Max((m_maxFontSize - m_fontSize) / 2, 0.05f);
3043 m_fontSize = (int)(Mathf.Min(m_fontSize, m_fontSizeMax) * 20 + 0.5f) / 20f;
3047 if (loopCountA > 20)
return;
3051 #endregion End Auto-sizing Check 3054 m_isCharacterWrappingEnabled =
false;
3056 #if TMP_PROFILE_PHASES_ON 3057 Profiler.EndSample();
3063 #if TMP_PROFILE_PHASES_ON 3064 Profiler.BeginSample(
"TMP Generate Text - Phase II");
3068 if (m_characterCount == 0)
3073 TMPro_EventManager.ON_TEXT_CHANGED(
this);
3079 int last_vert_index = m_materialReferences[0].referenceCount * 4;
3082 m_textInfo.meshInfo[0].
Clear(
false);
3085 #region Text Vertical Alignment 3087 Profiler.BeginSample(
"Vertical Text Alignment");
3089 Vector3 anchorOffset = Vector3.zero;
3090 Vector3[] corners = m_RectTransformCorners;
3092 switch (m_textAlignment)
3095 case TextAlignmentOptions.Top:
3096 case TextAlignmentOptions.TopLeft:
3097 case TextAlignmentOptions.TopRight:
3098 case TextAlignmentOptions.TopJustified:
3099 case TextAlignmentOptions.TopFlush:
3100 case TextAlignmentOptions.TopGeoAligned:
3101 if (m_overflowMode != TextOverflowModes.Page)
3102 anchorOffset = corners[1] +
new Vector3(0 + margins.x, 0 - m_maxAscender - margins.y, 0);
3104 anchorOffset = corners[1] +
new Vector3(0 + margins.x, 0 - m_textInfo.pageInfo[
pageToDisplay].ascender - margins.y, 0);
3108 case TextAlignmentOptions.Left:
3109 case TextAlignmentOptions.Right:
3110 case TextAlignmentOptions.Center:
3111 case TextAlignmentOptions.Justified:
3112 case TextAlignmentOptions.Flush:
3113 case TextAlignmentOptions.CenterGeoAligned:
3114 if (m_overflowMode != TextOverflowModes.Page)
3115 anchorOffset = (corners[0] + corners[1]) / 2 +
new Vector3(0 + margins.x, 0 - (m_maxAscender + margins.y + maxVisibleDescender - margins.w) / 2, 0);
3117 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);
3121 case TextAlignmentOptions.Bottom:
3122 case TextAlignmentOptions.BottomLeft:
3123 case TextAlignmentOptions.BottomRight:
3124 case TextAlignmentOptions.BottomJustified:
3125 case TextAlignmentOptions.BottomFlush:
3126 case TextAlignmentOptions.BottomGeoAligned:
3127 if (m_overflowMode != TextOverflowModes.Page)
3128 anchorOffset = corners[0] +
new Vector3(0 + margins.x, 0 - maxVisibleDescender + margins.w, 0);
3130 anchorOffset = corners[0] +
new Vector3(0 + margins.x, 0 - m_textInfo.pageInfo[
pageToDisplay].descender + margins.w, 0);
3134 case TextAlignmentOptions.Baseline:
3135 case TextAlignmentOptions.BaselineLeft:
3136 case TextAlignmentOptions.BaselineRight:
3137 case TextAlignmentOptions.BaselineJustified:
3138 case TextAlignmentOptions.BaselineFlush:
3139 case TextAlignmentOptions.BaselineGeoAligned:
3140 anchorOffset = (corners[0] + corners[1]) / 2 +
new Vector3(0 + margins.x, 0, 0);
3144 case TextAlignmentOptions.MidlineLeft:
3145 case TextAlignmentOptions.Midline:
3146 case TextAlignmentOptions.MidlineRight:
3147 case TextAlignmentOptions.MidlineJustified:
3148 case TextAlignmentOptions.MidlineFlush:
3149 case TextAlignmentOptions.MidlineGeoAligned:
3150 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);
3154 case TextAlignmentOptions.CaplineLeft:
3155 case TextAlignmentOptions.Capline:
3156 case TextAlignmentOptions.CaplineRight:
3157 case TextAlignmentOptions.CaplineJustified:
3158 case TextAlignmentOptions.CaplineFlush:
3159 case TextAlignmentOptions.CaplineGeoAligned:
3160 anchorOffset = (corners[0] + corners[1]) / 2 +
new Vector3(0 + margins.x, 0 - (m_maxCapHeight - margins.y - margins.w) / 2, 0);
3164 Profiler.EndSample();
3170 Vector3 justificationOffset = Vector3.zero;
3171 Vector3 offset = Vector3.zero;
3172 int vert_index_X4 = 0;
3173 int sprite_index_X4 = 0;
3178 bool isFirstSeperator =
false;
3180 bool isStartOfWord =
false;
3181 int wordFirstChar = 0;
3182 int wordLastChar = 0;
3185 #region Handle Line Justification & UV Mapping & Character Visibility & More 3188 bool isCameraAssigned = m_canvas.worldCamera ==
null ? false :
true;
3189 float lossyScale = m_previousLossyScaleY = this.
transform.lossyScale.y;
3190 RenderMode canvasRenderMode = m_canvas.renderMode;
3191 float canvasScaleFactor = m_canvas.scaleFactor;
3193 Color32 underlineColor = Color.white;
3194 Color32 strikethroughColor = Color.white;
3195 Color32 highlightColor =
new Color32(255, 255, 0, 64);
3197 float underlineStartScale = 0;
3198 float underlineEndScale = 0;
3199 float underlineMaxScale = 0;
3200 float underlineBaseLine = k_LargePositiveFloat;
3203 float strikethroughPointSize = 0;
3204 float strikethroughScale = 0;
3205 float strikethroughBaseline = 0;
3208 #region Handle Line Justification & UV Mapping & Character Visibility & More 3209 for (
int i = 0; i < m_characterCount; i++)
3211 TMP_FontAsset currentFontAsset = characterInfos[i].fontAsset;
3213 char currentCharacter = characterInfos[i].character;
3215 int currentLine = characterInfos[i].lineNumber;
3216 TMP_LineInfo lineInfo = m_textInfo.lineInfo[currentLine];
3217 lineCount = currentLine + 1;
3219 TextAlignmentOptions lineAlignment = lineInfo.alignment;
3222 #region Handle Line Justification 3224 Profiler.BeginSample(
"Horizontal Text Alignment");
3228 switch (lineAlignment)
3230 case TextAlignmentOptions.TopLeft:
3231 case TextAlignmentOptions.Left:
3232 case TextAlignmentOptions.BottomLeft:
3233 case TextAlignmentOptions.BaselineLeft:
3234 case TextAlignmentOptions.MidlineLeft:
3235 case TextAlignmentOptions.CaplineLeft:
3236 if (!m_isRightToLeft)
3237 justificationOffset =
new Vector3(0 + lineInfo.marginLeft, 0, 0);
3239 justificationOffset =
new Vector3(0 - lineInfo.maxAdvance, 0, 0);
3242 case TextAlignmentOptions.Top:
3243 case TextAlignmentOptions.Center:
3244 case TextAlignmentOptions.Bottom:
3245 case TextAlignmentOptions.Baseline:
3246 case TextAlignmentOptions.Midline:
3247 case TextAlignmentOptions.Capline:
3248 justificationOffset =
new Vector3(lineInfo.marginLeft + lineInfo.width / 2 - lineInfo.maxAdvance / 2, 0, 0);
3251 case TextAlignmentOptions.TopGeoAligned:
3252 case TextAlignmentOptions.CenterGeoAligned:
3253 case TextAlignmentOptions.BottomGeoAligned:
3254 case TextAlignmentOptions.BaselineGeoAligned:
3255 case TextAlignmentOptions.MidlineGeoAligned:
3256 case TextAlignmentOptions.CaplineGeoAligned:
3257 justificationOffset =
new Vector3(lineInfo.marginLeft + lineInfo.width / 2 - (lineInfo.lineExtents.min.x + lineInfo.lineExtents.max.x) / 2, 0, 0);
3260 case TextAlignmentOptions.TopRight:
3261 case TextAlignmentOptions.Right:
3262 case TextAlignmentOptions.BottomRight:
3263 case TextAlignmentOptions.BaselineRight:
3264 case TextAlignmentOptions.MidlineRight:
3265 case TextAlignmentOptions.CaplineRight:
3266 if (!m_isRightToLeft)
3267 justificationOffset =
new Vector3(lineInfo.marginLeft + lineInfo.width - lineInfo.maxAdvance, 0, 0);
3269 justificationOffset =
new Vector3(lineInfo.marginLeft + lineInfo.width, 0, 0);
3272 case TextAlignmentOptions.TopJustified:
3273 case TextAlignmentOptions.Justified:
3274 case TextAlignmentOptions.BottomJustified:
3275 case TextAlignmentOptions.BaselineJustified:
3276 case TextAlignmentOptions.MidlineJustified:
3277 case TextAlignmentOptions.CaplineJustified:
3278 case TextAlignmentOptions.TopFlush:
3279 case TextAlignmentOptions.Flush:
3280 case TextAlignmentOptions.BottomFlush:
3281 case TextAlignmentOptions.BaselineFlush:
3282 case TextAlignmentOptions.MidlineFlush:
3283 case TextAlignmentOptions.CaplineFlush:
3285 if (currentCharacter == 0xAD || currentCharacter == 0x200B || currentCharacter == 0x2060)
break;
3287 char lastCharOfCurrentLine = characterInfos[lineInfo.lastCharacterIndex].character;
3292 if (
char.IsControl(lastCharOfCurrentLine) ==
false && currentLine < m_lineNumber || isFlush || lineInfo.maxAdvance > lineInfo.width)
3295 if (currentLine != lastLine || i == 0 || i == m_firstVisibleCharacter)
3297 if (!m_isRightToLeft)
3298 justificationOffset =
new Vector3(lineInfo.marginLeft, 0, 0);
3300 justificationOffset =
new Vector3(lineInfo.marginLeft + lineInfo.width, 0, 0);
3302 if (
char.IsSeparator(currentCharacter))
3303 isFirstSeperator =
true;
3305 isFirstSeperator =
false;
3309 float gap = !m_isRightToLeft ? lineInfo.width - lineInfo.maxAdvance : lineInfo.width + lineInfo.maxAdvance;
3311 int visibleCount = lineInfo.visibleCharacterCount - 1 + lineInfo.controlCharacterCount;
3314 int spaces = (characterInfos[lineInfo.lastCharacterIndex].isVisible ? lineInfo.spaceCount : lineInfo.spaceCount - 1) - lineInfo.controlCharacterCount;
3316 if (isFirstSeperator) { spaces -= 1; visibleCount += 1; }
3318 float ratio = spaces > 0 ? m_wordWrappingRatios : 1;
3320 if (spaces < 1) spaces = 1;
3322 if (currentCharacter != 0xA0 && (currentCharacter == 9 ||
char.IsSeparator((
char)currentCharacter)))
3324 if (!m_isRightToLeft)
3325 justificationOffset +=
new Vector3(gap * (1 - ratio) / spaces, 0, 0);
3327 justificationOffset -=
new Vector3(gap * (1 - ratio) / spaces, 0, 0);
3331 if (!m_isRightToLeft)
3332 justificationOffset +=
new Vector3(gap * ratio / visibleCount, 0, 0);
3334 justificationOffset -=
new Vector3(gap * ratio / visibleCount, 0, 0);
3340 if (!m_isRightToLeft)
3341 justificationOffset =
new Vector3(lineInfo.marginLeft, 0, 0);
3343 justificationOffset =
new Vector3(lineInfo.marginLeft + lineInfo.width, 0, 0);
3350 Profiler.EndSample();
3352 #endregion End Text Justification 3354 offset = anchorOffset + justificationOffset;
3357 #region Handling of UV2 mapping & Scale packing 3358 bool isCharacterVisible = characterInfos[i].isVisible;
3359 if (isCharacterVisible)
3361 TMP_TextElementType elementType = characterInfos[i].elementType;
3362 switch (elementType)
3365 case TMP_TextElementType.Character:
3366 Extents lineExtents = lineInfo.lineExtents;
3367 float uvOffset = (m_uvLineOffset * currentLine) % 1;
3370 #region Handle UV Mapping Options 3372 Profiler.BeginSample(
"UV MAPPING");
3374 switch (m_horizontalMapping)
3376 case TextureMappingOptions.Character:
3377 characterInfos[i].vertex_BL.uv2.x = 0;
3378 characterInfos[i].vertex_TL.uv2.x = 0;
3379 characterInfos[i].vertex_TR.uv2.x = 1;
3380 characterInfos[i].vertex_BR.uv2.x = 1;
3383 case TextureMappingOptions.Line:
3384 if (m_textAlignment != TextAlignmentOptions.Justified)
3386 characterInfos[i].vertex_BL.uv2.x = (characterInfos[i].vertex_BL.position.x - lineExtents.min.x) / (lineExtents.max.x - lineExtents.min.x) + uvOffset;
3387 characterInfos[i].vertex_TL.uv2.x = (characterInfos[i].vertex_TL.position.x - lineExtents.min.x) / (lineExtents.max.x - lineExtents.min.x) + uvOffset;
3388 characterInfos[i].vertex_TR.uv2.x = (characterInfos[i].vertex_TR.position.x - lineExtents.min.x) / (lineExtents.max.x - lineExtents.min.x) + uvOffset;
3389 characterInfos[i].vertex_BR.uv2.x = (characterInfos[i].vertex_BR.position.x - lineExtents.min.x) / (lineExtents.max.x - lineExtents.min.x) + uvOffset;
3394 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;
3395 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;
3396 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;
3397 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;
3401 case TextureMappingOptions.Paragraph:
3402 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;
3403 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;
3404 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;
3405 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;
3408 case TextureMappingOptions.MatchAspect:
3410 switch (m_verticalMapping)
3412 case TextureMappingOptions.Character:
3413 characterInfos[i].vertex_BL.uv2.y = 0;
3414 characterInfos[i].vertex_TL.uv2.y = 1;
3415 characterInfos[i].vertex_TR.uv2.y = 0;
3416 characterInfos[i].vertex_BR.uv2.y = 1;
3419 case TextureMappingOptions.Line:
3420 characterInfos[i].vertex_BL.uv2.y = (characterInfos[i].vertex_BL.position.y - lineExtents.min.y) / (lineExtents.max.y - lineExtents.min.y) + uvOffset;
3421 characterInfos[i].vertex_TL.uv2.y = (characterInfos[i].vertex_TL.position.y - lineExtents.min.y) / (lineExtents.max.y - lineExtents.min.y) + uvOffset;
3422 characterInfos[i].vertex_TR.uv2.y = characterInfos[i].vertex_BL.uv2.y;
3423 characterInfos[i].vertex_BR.uv2.y = characterInfos[i].vertex_TL.uv2.y;
3426 case TextureMappingOptions.Paragraph:
3427 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;
3428 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;
3429 characterInfos[i].vertex_TR.uv2.y = characterInfos[i].vertex_BL.uv2.y;
3430 characterInfos[i].vertex_BR.uv2.y = characterInfos[i].vertex_TL.uv2.y;
3433 case TextureMappingOptions.MatchAspect:
3434 Debug.Log(
"ERROR: Cannot Match both Vertical & Horizontal.");
3439 float xDelta = (1 - ((characterInfos[i].vertex_BL.uv2.y + characterInfos[i].vertex_TL.uv2.y) * characterInfos[i].aspectRatio)) / 2;
3441 characterInfos[i].vertex_BL.uv2.x = (characterInfos[i].vertex_BL.uv2.y * characterInfos[i].aspectRatio) + xDelta + uvOffset;
3442 characterInfos[i].vertex_TL.uv2.x = characterInfos[i].vertex_BL.uv2.x;
3443 characterInfos[i].vertex_TR.uv2.x = (characterInfos[i].vertex_TL.uv2.y * characterInfos[i].aspectRatio) + xDelta + uvOffset;
3444 characterInfos[i].vertex_BR.uv2.x = characterInfos[i].vertex_TR.uv2.x;
3448 switch (m_verticalMapping)
3450 case TextureMappingOptions.Character:
3451 characterInfos[i].vertex_BL.uv2.y = 0;
3452 characterInfos[i].vertex_TL.uv2.y = 1;
3453 characterInfos[i].vertex_TR.uv2.y = 1;
3454 characterInfos[i].vertex_BR.uv2.y = 0;
3457 case TextureMappingOptions.Line:
3458 characterInfos[i].vertex_BL.uv2.y = (characterInfos[i].vertex_BL.position.y - lineInfo.descender) / (lineInfo.ascender - lineInfo.descender);
3459 characterInfos[i].vertex_TL.uv2.y = (characterInfos[i].vertex_TL.position.y - lineInfo.descender) / (lineInfo.ascender - lineInfo.descender);
3460 characterInfos[i].vertex_TR.uv2.y = characterInfos[i].vertex_TL.uv2.y;
3461 characterInfos[i].vertex_BR.uv2.y = characterInfos[i].vertex_BL.uv2.y;
3464 case TextureMappingOptions.Paragraph:
3465 characterInfos[i].vertex_BL.uv2.y = (characterInfos[i].vertex_BL.position.y - m_meshExtents.min.y) / (m_meshExtents.max.y - m_meshExtents.min.y);
3466 characterInfos[i].vertex_TL.uv2.y = (characterInfos[i].vertex_TL.position.y - m_meshExtents.min.y) / (m_meshExtents.max.y - m_meshExtents.min.y);
3467 characterInfos[i].vertex_TR.uv2.y = characterInfos[i].vertex_TL.uv2.y;
3468 characterInfos[i].vertex_BR.uv2.y = characterInfos[i].vertex_BL.uv2.y;
3471 case TextureMappingOptions.MatchAspect:
3472 float yDelta = (1 - ((characterInfos[i].vertex_BL.uv2.x + characterInfos[i].vertex_TR.uv2.x) / characterInfos[i].aspectRatio)) / 2;
3474 characterInfos[i].vertex_BL.uv2.y = yDelta + (characterInfos[i].vertex_BL.uv2.x / characterInfos[i].aspectRatio);
3475 characterInfos[i].vertex_TL.uv2.y = yDelta + (characterInfos[i].vertex_TR.uv2.x / characterInfos[i].aspectRatio);
3476 characterInfos[i].vertex_BR.uv2.y = characterInfos[i].vertex_BL.uv2.y;
3477 characterInfos[i].vertex_TR.uv2.y = characterInfos[i].vertex_TL.uv2.y;
3481 Profiler.EndSample();
3483 #endregion End UV Mapping Options 3486 #region Pack Scale into UV2 3488 Profiler.BeginSample(
"Pack UV");
3490 xScale = characterInfos[i].scale * (1 - m_charWidthAdjDelta);
3491 if (!characterInfos[i].isUsingAlternateTypeface && (characterInfos[i].style & FontStyles.Bold) == FontStyles.Bold) xScale *= -1;
3493 switch (canvasRenderMode)
3495 case RenderMode.ScreenSpaceOverlay:
3496 xScale *= lossyScale / canvasScaleFactor;
3498 case RenderMode.ScreenSpaceCamera:
3499 xScale *= isCameraAssigned ? lossyScale : 1;
3501 case RenderMode.WorldSpace:
3502 xScale *= lossyScale;
3513 float x0 = characterInfos[i].vertex_BL.uv2.x;
3514 float y0 = characterInfos[i].vertex_BL.uv2.y;
3515 float x1 = characterInfos[i].vertex_TR.uv2.x;
3516 float y1 = characterInfos[i].vertex_TR.uv2.y;
3527 characterInfos[i].vertex_BL.uv2.x =
PackUV(x0, y0); characterInfos[i].vertex_BL.uv2.y = xScale;
3528 characterInfos[i].vertex_TL.uv2.x =
PackUV(x0, y1); characterInfos[i].vertex_TL.uv2.y = xScale;
3529 characterInfos[i].vertex_TR.uv2.x =
PackUV(x1, y1); characterInfos[i].vertex_TR.uv2.y = xScale;
3530 characterInfos[i].vertex_BR.uv2.x =
PackUV(x1, y0); characterInfos[i].vertex_BR.uv2.y = xScale;
3532 Profiler.EndSample();
3538 case TMP_TextElementType.Sprite:
3544 #region Handle maxVisibleCharacters / maxVisibleLines / Page Mode 3546 Profiler.BeginSample(
"Process MaxVisible Characters & Lines");
3548 if (i < m_maxVisibleCharacters && wordCount < m_maxVisibleWords && currentLine < m_maxVisibleLines && m_overflowMode != TextOverflowModes.Page)
3550 characterInfos[i].vertex_BL.position += offset;
3551 characterInfos[i].vertex_TL.position += offset;
3552 characterInfos[i].vertex_TR.position += offset;
3553 characterInfos[i].vertex_BR.position += offset;
3555 else if (i < m_maxVisibleCharacters && wordCount < m_maxVisibleWords && currentLine < m_maxVisibleLines && m_overflowMode == TextOverflowModes.Page && characterInfos[i].pageNumber ==
pageToDisplay)
3557 characterInfos[i].vertex_BL.position += offset;
3558 characterInfos[i].vertex_TL.position += offset;
3559 characterInfos[i].vertex_TR.position += offset;
3560 characterInfos[i].vertex_BR.position += offset;
3564 characterInfos[i].vertex_BL.position = Vector3.zero;
3565 characterInfos[i].vertex_TL.position = Vector3.zero;
3566 characterInfos[i].vertex_TR.position = Vector3.zero;
3567 characterInfos[i].vertex_BR.position = Vector3.zero;
3568 characterInfos[i].isVisible =
false;
3571 Profiler.EndSample();
3577 if (elementType == TMP_TextElementType.Character)
3581 else if (elementType == TMP_TextElementType.Sprite)
3589 m_textInfo.characterInfo[i].bottomLeft += offset;
3590 m_textInfo.characterInfo[i].topLeft += offset;
3591 m_textInfo.characterInfo[i].topRight += offset;
3592 m_textInfo.characterInfo[i].bottomRight += offset;
3594 m_textInfo.characterInfo[i].origin += offset.x;
3595 m_textInfo.characterInfo[i].xAdvance += offset.x;
3597 m_textInfo.characterInfo[i].ascender += offset.y;
3598 m_textInfo.characterInfo[i].descender += offset.y;
3599 m_textInfo.characterInfo[i].baseLine += offset.y;
3602 if (isCharacterVisible)
3609 #region Adjust lineExtents resulting from alignment offset 3611 Profiler.BeginSample(
"Adjust LineExtents");
3613 if (currentLine != lastLine || i == m_characterCount - 1)
3616 if (currentLine != lastLine)
3618 m_textInfo.lineInfo[lastLine].baseline += offset.y;
3619 m_textInfo.lineInfo[lastLine].ascender += offset.y;
3620 m_textInfo.lineInfo[lastLine].descender += offset.y;
3622 m_textInfo.lineInfo[lastLine].lineExtents.min =
new Vector2(m_textInfo.characterInfo[m_textInfo.lineInfo[lastLine].firstCharacterIndex].bottomLeft.x, m_textInfo.lineInfo[lastLine].descender);
3623 m_textInfo.lineInfo[lastLine].lineExtents.max =
new Vector2(m_textInfo.characterInfo[m_textInfo.lineInfo[lastLine].lastVisibleCharacterIndex].topRight.x, m_textInfo.lineInfo[lastLine].ascender);
3627 if (i == m_characterCount - 1)
3629 m_textInfo.lineInfo[currentLine].baseline += offset.y;
3630 m_textInfo.lineInfo[currentLine].ascender += offset.y;
3631 m_textInfo.lineInfo[currentLine].descender += offset.y;
3633 m_textInfo.lineInfo[currentLine].lineExtents.min =
new Vector2(m_textInfo.characterInfo[m_textInfo.lineInfo[currentLine].firstCharacterIndex].bottomLeft.x, m_textInfo.lineInfo[currentLine].descender);
3634 m_textInfo.lineInfo[currentLine].lineExtents.max =
new Vector2(m_textInfo.characterInfo[m_textInfo.lineInfo[currentLine].lastVisibleCharacterIndex].topRight.x, m_textInfo.lineInfo[currentLine].ascender);
3638 Profiler.EndSample();
3644 #region Track Word Count 3646 Profiler.BeginSample(
"Track Word Count");
3648 if (
char.IsLetterOrDigit(currentCharacter) || currentCharacter == 0x2D || currentCharacter == 0xAD || currentCharacter == 0x2010 || currentCharacter == 0x2011)
3650 if (isStartOfWord ==
false)
3652 isStartOfWord =
true;
3657 if (isStartOfWord && i == m_characterCount - 1)
3659 int size = m_textInfo.wordInfo.Length;
3660 int index = m_textInfo.wordCount;
3662 if (m_textInfo.wordCount + 1 > size)
3663 TMP_TextInfo.Resize(ref m_textInfo.wordInfo, size + 1);
3667 m_textInfo.wordInfo[index].firstCharacterIndex = wordFirstChar;
3668 m_textInfo.wordInfo[index].lastCharacterIndex = wordLastChar;
3669 m_textInfo.wordInfo[index].characterCount = wordLastChar - wordFirstChar + 1;
3670 m_textInfo.wordInfo[index].textComponent =
this;
3673 m_textInfo.wordCount += 1;
3674 m_textInfo.lineInfo[currentLine].wordCount += 1;
3677 else if (isStartOfWord || i == 0 && (!
char.IsPunctuation(currentCharacter) ||
char.IsWhiteSpace(currentCharacter) || currentCharacter == 0x200B || i == m_characterCount - 1))
3679 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))
3685 wordLastChar = i == m_characterCount - 1 &&
char.IsLetterOrDigit(currentCharacter) ? i : i - 1;
3686 isStartOfWord =
false;
3688 int size = m_textInfo.wordInfo.Length;
3689 int index = m_textInfo.wordCount;
3691 if (m_textInfo.wordCount + 1 > size)
3692 TMP_TextInfo.Resize(ref m_textInfo.wordInfo, size + 1);
3694 m_textInfo.wordInfo[index].firstCharacterIndex = wordFirstChar;
3695 m_textInfo.wordInfo[index].lastCharacterIndex = wordLastChar;
3696 m_textInfo.wordInfo[index].characterCount = wordLastChar - wordFirstChar + 1;
3697 m_textInfo.wordInfo[index].textComponent =
this;
3700 m_textInfo.wordCount += 1;
3701 m_textInfo.lineInfo[currentLine].wordCount += 1;
3705 Profiler.EndSample();
3713 Profiler.BeginSample(
"Process Underline & Strikethrough");
3716 bool isUnderline = (m_textInfo.characterInfo[i].style & FontStyles.Underline) == FontStyles.Underline;
3719 bool isUnderlineVisible =
true;
3720 int currentPage = m_textInfo.characterInfo[i].pageNumber;
3722 if (i > m_maxVisibleCharacters || currentLine > m_maxVisibleLines || (m_overflowMode == TextOverflowModes.Page && currentPage + 1 != m_pageToDisplay))
3723 isUnderlineVisible =
false;
3726 if (!
char.IsWhiteSpace(currentCharacter) && currentCharacter != 0x200B)
3728 underlineMaxScale = Mathf.Max(underlineMaxScale, m_textInfo.characterInfo[i].scale);
3729 underlineBaseLine = Mathf.Min(currentPage == lastPage ? underlineBaseLine : k_LargePositiveFloat, m_textInfo.characterInfo[i].baseLine +
font.
fontInfo.Underline * underlineMaxScale);
3730 lastPage = currentPage;
3733 if (beginUnderline ==
false && isUnderlineVisible ==
true && i <= lineInfo.lastVisibleCharacterIndex && currentCharacter != 10 && currentCharacter != 13)
3735 if (i == lineInfo.lastVisibleCharacterIndex &&
char.IsSeparator(currentCharacter))
3739 beginUnderline =
true;
3740 underlineStartScale = m_textInfo.characterInfo[i].scale;
3741 if (underlineMaxScale == 0) underlineMaxScale = underlineStartScale;
3742 underline_start =
new Vector3(m_textInfo.characterInfo[i].bottomLeft.x, underlineBaseLine, 0);
3743 underlineColor = m_textInfo.characterInfo[i].underlineColor;
3748 if (beginUnderline && m_characterCount == 1)
3750 beginUnderline =
false;
3751 underline_end =
new Vector3(m_textInfo.characterInfo[i].topRight.x, underlineBaseLine, 0);
3752 underlineEndScale = m_textInfo.characterInfo[i].scale;
3754 DrawUnderlineMesh(underline_start, underline_end, ref last_vert_index, underlineStartScale, underlineEndScale, underlineMaxScale, xScale, underlineColor);
3755 underlineMaxScale = 0;
3756 underlineBaseLine = k_LargePositiveFloat;
3758 else if (beginUnderline && (i == lineInfo.lastCharacterIndex || i >= lineInfo.lastVisibleCharacterIndex))
3761 if (
char.IsWhiteSpace(currentCharacter) || currentCharacter == 0x200B)
3763 int lastVisibleCharacterIndex = lineInfo.lastVisibleCharacterIndex;
3764 underline_end =
new Vector3(m_textInfo.characterInfo[lastVisibleCharacterIndex].topRight.x, underlineBaseLine, 0);
3765 underlineEndScale = m_textInfo.characterInfo[lastVisibleCharacterIndex].scale;
3769 underline_end =
new Vector3(m_textInfo.characterInfo[i].topRight.x, underlineBaseLine, 0);
3770 underlineEndScale = m_textInfo.characterInfo[i].scale;
3773 beginUnderline =
false;
3774 DrawUnderlineMesh(underline_start, underline_end, ref last_vert_index, underlineStartScale, underlineEndScale, underlineMaxScale, xScale, underlineColor);
3775 underlineMaxScale = 0;
3776 underlineBaseLine = k_LargePositiveFloat;
3778 else if (beginUnderline && !isUnderlineVisible)
3780 beginUnderline =
false;
3781 underline_end =
new Vector3(m_textInfo.characterInfo[i - 1].topRight.x, underlineBaseLine, 0);
3782 underlineEndScale = m_textInfo.characterInfo[i - 1].scale;
3784 DrawUnderlineMesh(underline_start, underline_end, ref last_vert_index, underlineStartScale, underlineEndScale, underlineMaxScale, xScale, underlineColor);
3785 underlineMaxScale = 0;
3786 underlineBaseLine = k_LargePositiveFloat;
3788 else if (beginUnderline && i < m_characterCount - 1 && !underlineColor.Compare(m_textInfo.characterInfo[i + 1].underlineColor))
3791 beginUnderline =
false;
3792 underline_end =
new Vector3(m_textInfo.characterInfo[i].topRight.x, underlineBaseLine, 0);
3793 underlineEndScale = m_textInfo.characterInfo[i].scale;
3795 DrawUnderlineMesh(underline_start, underline_end, ref last_vert_index, underlineStartScale, underlineEndScale, underlineMaxScale, xScale, underlineColor);
3796 underlineMaxScale = 0;
3797 underlineBaseLine = k_LargePositiveFloat;
3803 if (beginUnderline ==
true)
3805 beginUnderline =
false;
3806 underline_end =
new Vector3(m_textInfo.characterInfo[i - 1].topRight.x, underlineBaseLine, 0);
3807 underlineEndScale = m_textInfo.characterInfo[i - 1].scale;
3809 DrawUnderlineMesh(underline_start, underline_end, ref last_vert_index, underlineStartScale, underlineEndScale, underlineMaxScale, xScale, underlineColor);
3810 underlineMaxScale = 0;
3811 underlineBaseLine = k_LargePositiveFloat;
3818 #region Strikethrough 3820 bool isStrikethrough = (m_textInfo.characterInfo[i].style & FontStyles.Strikethrough) == FontStyles.Strikethrough;
3821 float strikethroughOffset = currentFontAsset.
fontInfo.strikethrough;
3823 if (isStrikethrough)
3825 bool isStrikeThroughVisible =
true;
3827 if (i > m_maxVisibleCharacters || currentLine > m_maxVisibleLines || (m_overflowMode == TextOverflowModes.Page && m_textInfo.characterInfo[i].pageNumber + 1 != m_pageToDisplay))
3828 isStrikeThroughVisible =
false;
3830 if (beginStrikethrough ==
false && isStrikeThroughVisible && i <= lineInfo.lastVisibleCharacterIndex && currentCharacter != 10 && currentCharacter != 13)
3832 if (i == lineInfo.lastVisibleCharacterIndex &&
char.IsSeparator(currentCharacter))
3836 beginStrikethrough =
true;
3837 strikethroughPointSize = m_textInfo.characterInfo[i].pointSize;
3838 strikethroughScale = m_textInfo.characterInfo[i].scale;
3839 strikethrough_start =
new Vector3(m_textInfo.characterInfo[i].bottomLeft.x, m_textInfo.characterInfo[i].baseLine + strikethroughOffset * strikethroughScale, 0);
3840 strikethroughColor = m_textInfo.characterInfo[i].strikethroughColor;
3841 strikethroughBaseline = m_textInfo.characterInfo[i].baseLine;
3847 if (beginStrikethrough && m_characterCount == 1)
3849 beginStrikethrough =
false;
3850 strikethrough_end =
new Vector3(m_textInfo.characterInfo[i].topRight.x, m_textInfo.characterInfo[i].baseLine + strikethroughOffset * strikethroughScale, 0);
3852 DrawUnderlineMesh(strikethrough_start, strikethrough_end, ref last_vert_index, strikethroughScale, strikethroughScale, strikethroughScale, xScale, strikethroughColor);
3854 else if (beginStrikethrough && i == lineInfo.lastCharacterIndex)
3857 if (
char.IsWhiteSpace(currentCharacter) || currentCharacter == 0x200B)
3859 int lastVisibleCharacterIndex = lineInfo.lastVisibleCharacterIndex;
3860 strikethrough_end =
new Vector3(m_textInfo.characterInfo[lastVisibleCharacterIndex].topRight.x, m_textInfo.characterInfo[lastVisibleCharacterIndex].baseLine + strikethroughOffset * strikethroughScale, 0);
3865 strikethrough_end =
new Vector3(m_textInfo.characterInfo[i].topRight.x, m_textInfo.characterInfo[i].baseLine + strikethroughOffset * strikethroughScale, 0);
3868 beginStrikethrough =
false;
3869 DrawUnderlineMesh(strikethrough_start, strikethrough_end, ref last_vert_index, strikethroughScale, strikethroughScale, strikethroughScale, xScale, strikethroughColor);
3871 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)))
3874 beginStrikethrough =
false;
3876 int lastVisibleCharacterIndex = lineInfo.lastVisibleCharacterIndex;
3877 if (i > lastVisibleCharacterIndex)
3878 strikethrough_end =
new Vector3(m_textInfo.characterInfo[lastVisibleCharacterIndex].topRight.x, m_textInfo.characterInfo[lastVisibleCharacterIndex].baseLine + strikethroughOffset * strikethroughScale, 0);
3880 strikethrough_end =
new Vector3(m_textInfo.characterInfo[i].topRight.x, m_textInfo.characterInfo[i].baseLine + strikethroughOffset * strikethroughScale, 0);
3882 DrawUnderlineMesh(strikethrough_start, strikethrough_end, ref last_vert_index, strikethroughScale, strikethroughScale, strikethroughScale, xScale, strikethroughColor);
3885 else if (beginStrikethrough && i < m_characterCount && currentFontAsset.GetInstanceID() != characterInfos[i + 1].fontAsset.GetInstanceID())
3888 beginStrikethrough =
false;
3889 strikethrough_end =
new Vector3(m_textInfo.characterInfo[i].topRight.x, m_textInfo.characterInfo[i].baseLine + strikethroughOffset * strikethroughScale, 0);
3891 DrawUnderlineMesh(strikethrough_start, strikethrough_end, ref last_vert_index, strikethroughScale, strikethroughScale, strikethroughScale, xScale, strikethroughColor);
3893 else if (beginStrikethrough && !isStrikeThroughVisible)
3896 beginStrikethrough =
false;
3897 strikethrough_end =
new Vector3(m_textInfo.characterInfo[i - 1].topRight.x, m_textInfo.characterInfo[i - 1].baseLine + strikethroughOffset * strikethroughScale, 0);
3899 DrawUnderlineMesh(strikethrough_start, strikethrough_end, ref last_vert_index, strikethroughScale, strikethroughScale, strikethroughScale, xScale, strikethroughColor);
3905 if (beginStrikethrough ==
true)
3907 beginStrikethrough =
false;
3908 strikethrough_end =
new Vector3(m_textInfo.characterInfo[i - 1].topRight.x, m_textInfo.characterInfo[i - 1].baseLine + strikethroughOffset * strikethroughScale, 0);
3910 DrawUnderlineMesh(strikethrough_start, strikethrough_end, ref last_vert_index, strikethroughScale, strikethroughScale, strikethroughScale, xScale, strikethroughColor);
3917 #region Text Highlighting 3918 bool isHighlight = (m_textInfo.characterInfo[i].style & FontStyles.Highlight) == FontStyles.Highlight;
3921 bool isHighlightVisible =
true;
3922 int currentPage = m_textInfo.characterInfo[i].pageNumber;
3924 if (i > m_maxVisibleCharacters || currentLine > m_maxVisibleLines || (m_overflowMode == TextOverflowModes.Page && currentPage + 1 != m_pageToDisplay))
3925 isHighlightVisible =
false;
3927 if (beginHighlight ==
false && isHighlightVisible ==
true && i <= lineInfo.lastVisibleCharacterIndex && currentCharacter != 10 && currentCharacter != 13)
3929 if (i == lineInfo.lastVisibleCharacterIndex &&
char.IsSeparator(currentCharacter))
3933 beginHighlight =
true;
3934 highlight_start = k_LargePositiveVector2;
3935 highlight_end = k_LargeNegativeVector2;
3936 highlightColor = m_textInfo.characterInfo[i].highlightColor;
3942 Color32 currentHighlightColor = m_textInfo.characterInfo[i].highlightColor;
3943 bool isColorTransition =
false;
3946 if (!highlightColor.Compare(currentHighlightColor))
3949 highlight_end.x = (highlight_end.x + m_textInfo.characterInfo[i].bottomLeft.x) / 2;
3951 highlight_start.y = Mathf.Min(highlight_start.y, m_textInfo.characterInfo[i].descender);
3952 highlight_end.y = Mathf.Max(highlight_end.y, m_textInfo.characterInfo[i].ascender);
3954 DrawTextHighlight(highlight_start, highlight_end, ref last_vert_index, highlightColor);
3956 beginHighlight =
true;
3957 highlight_start = highlight_end;
3959 highlight_end =
new Vector3(m_textInfo.characterInfo[i].topRight.x, m_textInfo.characterInfo[i].descender, 0);
3960 highlightColor = m_textInfo.characterInfo[i].highlightColor;
3962 isColorTransition =
true;
3965 if (!isColorTransition)
3968 highlight_start.x = Mathf.Min(highlight_start.x, m_textInfo.characterInfo[i].bottomLeft.x);
3969 highlight_start.y = Mathf.Min(highlight_start.y, m_textInfo.characterInfo[i].descender);
3971 highlight_end.x = Mathf.Max(highlight_end.x, m_textInfo.characterInfo[i].topRight.x);
3972 highlight_end.y = Mathf.Max(highlight_end.y, m_textInfo.characterInfo[i].ascender);
3977 if (beginHighlight && m_characterCount == 1)
3979 beginHighlight =
false;
3981 DrawTextHighlight(highlight_start, highlight_end, ref last_vert_index, highlightColor);
3983 else if (beginHighlight && (i == lineInfo.lastCharacterIndex || i >= lineInfo.lastVisibleCharacterIndex))
3985 beginHighlight =
false;
3986 DrawTextHighlight(highlight_start, highlight_end, ref last_vert_index, highlightColor);
3988 else if (beginHighlight && !isHighlightVisible)
3990 beginHighlight =
false;
3991 DrawTextHighlight(highlight_start, highlight_end, ref last_vert_index, highlightColor);
3997 if (beginHighlight ==
true)
3999 beginHighlight =
false;
4000 DrawTextHighlight(highlight_start, highlight_end, ref last_vert_index, highlightColor);
4005 Profiler.EndSample();
4009 lastLine = currentLine;
4015 m_textInfo.characterCount = m_characterCount;
4016 m_textInfo.spriteCount = m_spriteCount;
4017 m_textInfo.lineCount = lineCount;
4018 m_textInfo.wordCount = wordCount != 0 && m_characterCount > 0 ? wordCount : 1;
4019 m_textInfo.pageCount = m_pageNumber + 1;
4021 #if TMP_PROFILE_PHASES_ON 4022 Profiler.EndSample();
4027 #if TMP_PROFILE_PHASES_ON 4028 Profiler.BeginSample(
"TMP Generate Text - Phase III");
4036 if (m_canvas.additionalShaderChannels != (AdditionalCanvasShaderChannels)25)
4037 m_canvas.additionalShaderChannels |= (AdditionalCanvasShaderChannels)25;
4040 if (m_geometrySortingOrder != VertexSortingOrder.Normal)
4041 m_textInfo.meshInfo[0].SortGeometry(VertexSortingOrder.Reverse);
4044 m_mesh.MarkDynamic();
4045 m_mesh.vertices = m_textInfo.meshInfo[0].vertices;
4046 m_mesh.uv = m_textInfo.meshInfo[0].uvs0;
4047 m_mesh.uv2 = m_textInfo.meshInfo[0].uvs2;
4049 m_mesh.colors32 = m_textInfo.meshInfo[0].colors32;
4052 m_mesh.RecalculateBounds();
4055 m_canvasRenderer.SetMesh(m_mesh);
4058 Color parentBaseColor = m_canvasRenderer.GetColor();
4060 for (
int i = 1; i < m_textInfo.materialCount; i++)
4065 if (m_subTextObjects[i] ==
null)
continue;
4068 if (m_geometrySortingOrder != VertexSortingOrder.Normal)
4069 m_textInfo.meshInfo[i].SortGeometry(VertexSortingOrder.Reverse);
4072 m_subTextObjects[i].mesh.vertices = m_textInfo.meshInfo[i].vertices;
4073 m_subTextObjects[i].mesh.uv = m_textInfo.meshInfo[i].uvs0;
4074 m_subTextObjects[i].mesh.uv2 = m_textInfo.meshInfo[i].uvs2;
4076 m_subTextObjects[i].mesh.colors32 = m_textInfo.meshInfo[i].colors32;
4078 m_subTextObjects[i].mesh.RecalculateBounds();
4080 m_subTextObjects[i].canvasRenderer.SetMesh(m_subTextObjects[i].
mesh);
4083 m_subTextObjects[i].canvasRenderer.SetColor(parentBaseColor);
4088 TMPro_EventManager.ON_TEXT_CHANGED(
this);
4091 #if TMP_PROFILE_PHASES_ON 4092 Profiler.EndSample();
4105 if (m_rectTransform ==
null) m_rectTransform = this.
rectTransform;
4107 m_rectTransform.GetLocalCorners(m_RectTransformCorners);
4109 return m_RectTransformCorners;
4119 for (
int i = 1; i < m_subTextObjects.Length && m_subTextObjects[i] !=
null; i++)
4121 if (m_subTextObjects[i].enabled != state)
4122 m_subTextObjects[i].enabled = state;
4133 Bounds mainBounds = m_mesh.bounds;
4134 Vector3 min = mainBounds.min;
4135 Vector3 max = mainBounds.max;
4137 for (
int i = 1; i < m_subTextObjects.Length && m_subTextObjects[i] !=
null; i++)
4139 Bounds subBounds = m_subTextObjects[i].mesh.bounds;
4140 min.x = min.x < subBounds.min.x ? min.x : subBounds.min.x;
4141 min.y = min.y < subBounds.min.y ? min.y : subBounds.min.y;
4143 max.x = max.x > subBounds.max.x ? max.x : subBounds.max.x;
4144 max.y = max.y > subBounds.max.y ? max.y : subBounds.max.y;
4147 Vector3 center = (min + max) / 2;
4148 Vector2 size = max - min;
4149 return new Bounds(center, size);
4167 if (m_canvas ==
null)
4170 if (m_canvas ==
null)
return;
4173 lossyScale = lossyScale == 0 ? 1 : lossyScale;
4176 float canvasScaleFactor = m_canvas.scaleFactor;
4178 if (m_canvas.renderMode == RenderMode.ScreenSpaceOverlay)
4179 xScale = lossyScale / canvasScaleFactor;
4180 else if (m_canvas.renderMode == RenderMode.ScreenSpaceCamera)
4181 xScale = m_canvas.worldCamera !=
null ? lossyScale : 1;
4183 xScale = lossyScale;
4186 for (
int i = 0; i < m_textInfo.characterCount; i++)
4189 if (m_textInfo.characterInfo[i].isVisible && m_textInfo.characterInfo[i].elementType == TMP_TextElementType.Character)
4191 float scale = xScale * m_textInfo.characterInfo[i].scale * (1 - m_charWidthAdjDelta);
4192 if (!m_textInfo.characterInfo[i].isUsingAlternateTypeface && (m_textInfo.characterInfo[i].style & FontStyles.Bold) == FontStyles.Bold) scale *= -1;
4194 int index = m_textInfo.characterInfo[i].materialReferenceIndex;
4195 int vertexIndex = m_textInfo.characterInfo[i].vertexIndex;
4197 m_textInfo.meshInfo[index].uvs2[vertexIndex + 0].y = scale;
4198 m_textInfo.meshInfo[index].uvs2[vertexIndex + 1].y = scale;
4199 m_textInfo.meshInfo[index].uvs2[vertexIndex + 2].y = scale;
4200 m_textInfo.meshInfo[index].uvs2[vertexIndex + 3].y = scale;
4205 for (
int i = 0; i < m_textInfo.materialCount; i++)
4209 m_mesh.uv2 = m_textInfo.meshInfo[0].uvs2;
4210 m_canvasRenderer.SetMesh(m_mesh);
4214 m_subTextObjects[i].mesh.uv2 = m_textInfo.meshInfo[i].uvs2;
4215 m_subTextObjects[i].canvasRenderer.SetMesh(m_subTextObjects[i].
mesh);
4224 Vector3 vertexOffset =
new Vector3(0, offset, 0);
4226 for (
int i = startIndex; i <= endIndex; i++)
4228 m_textInfo.characterInfo[i].bottomLeft -= vertexOffset;
4229 m_textInfo.characterInfo[i].topLeft -= vertexOffset;
4230 m_textInfo.characterInfo[i].topRight -= vertexOffset;
4231 m_textInfo.characterInfo[i].bottomRight -= vertexOffset;
4233 m_textInfo.characterInfo[i].ascender -= vertexOffset.y;
4234 m_textInfo.characterInfo[i].baseLine -= vertexOffset.y;
4235 m_textInfo.characterInfo[i].descender -= vertexOffset.y;
4237 if (m_textInfo.characterInfo[i].isVisible)
4239 m_textInfo.characterInfo[i].vertex_BL.position -= vertexOffset;
4240 m_textInfo.characterInfo[i].vertex_TL.position -= vertexOffset;
4241 m_textInfo.characterInfo[i].vertex_TR.position -= vertexOffset;
4242 m_textInfo.characterInfo[i].vertex_BR.position -= vertexOffset;
Positional adjustments of a glyph
override void GenerateTextMesh()
This is the main function that is responsible for creating / displaying the text.
TextRenderFlags
Flags controlling what vertex data gets pushed to the mesh.
override void SetSharedMaterials(Material[] materials)
Method used to assign new materials to the text and sub text objects.
void Clear()
Function to clear and reset stack to first item.
override void SetOutlineThickness(float thickness)
Function called internally to set the outline thickness property of the material. This will results i...
void ClearUnusedVertices()
Function to clear the vertices while preserving the Triangles, Normals and Tangents.
int index
Index of the character in the raw string.
virtual void SaveGlyphVertexInfo(float padding, float style_padding, Color32 vertexColor)
Store vertex information for each character.
Structure which contains information about the individual lines of text.
override void SetLayoutDirty()
override Material GetMaterial(Material mat)
Function called internally when a new material is assigned via the fontMaterial property.
Class which contains information about every element contained within the text object.
override void SetOutlineColor(Color32 color)
Function called internally to set the outline color of the material. This will results in an instance...
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 SetMaterialDirty()
override Material materialForRendering
Get the material that will be used for rendering.
TMP_SpriteAsset spriteAsset
Default Sprite Asset used by the text object.
virtual void SaveSpriteVertexInfo(Color32 vertexColor)
Store vertex information for each sprite.
TMP_FontAsset GetFontAssetForWeight(int fontWeight)
Canvas GetCanvas()
Method to retrieve the parent Canvas.
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.
void UpdateSDFScale(float lossyScale)
Method to Update Scale in UV2
void ResizeMeshInfo(int size)
Function to resized the content of MeshData and re-assign normals, tangents and triangles.
override void SetCulling()
Set the culling mode on the material.
new Transform transform
Returns are reference to the Transform
virtual Material CreateMaterialInstance(Material source)
Method to set the materials of the text and sub text objects.
override void SetShaderDepth()
Set the Render Queue and ZTest mode on the current material
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
Reference to the Mesh used by the text object.
Vector2 PackUV(float x, float y, float scale)
Function to pack scale information in the UV2 Channel.
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
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.
override void SetAllDirty()
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.
override void SetActiveSubMeshes(bool state)
Method to Enable or Disable child SubMesh objects.
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
TMP_FontAsset font
The Font Asset to be assigned to this text object.
void LateUpdate()
Unity standard function used to check if the transform or scale of the text object has changed.
override void LoadFontAsset()
Method which derived classes need to override to load Font Assets.
virtual void ForceMeshUpdate()
Function to force the regeneration of the text object.
override void ClearMesh()
Function to clear the geometry of the Primary and Sub Text objects.
override void UpdateMeshPadding()
Function to be used to force recomputing of character padding when Shader / Material properties have ...
override int SetArraySizes(int[] chars)
Method used to determine the number of visible characters and required buffer allocations.
static TMP_SubMeshUI AddSubTextObject(TextMeshProUGUI textComponent, MaterialReference materialReference)
Function to add a new sub text object.
virtual void FillCharacterVertexBuffers(int i, int index_X4)
Store vertex attributes into the appropriate TMP_MeshInfo.
override float GetPaddingForMaterial()
Get the padding value for the currently assigned material.
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.
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 Vector3 [] GetTextContainerLocalCorners()
Method to return the local corners of the Text Container or RectTransform.
Material material
The material used by this asset.
override void RecalculateClipping()
Method called when the state of a parent changes.
override void OnDidApplyAnimationProperties()
void UpdateEnvMapMatrix()
Method used when animating the Env Map on the material.
void ResizeLineExtents(int size)
Function to increase the size of the Line Extents Array.
override void ComputeMarginSize()
Update the margin width and height
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...
TMP custom data type to represent 32 bit characters.
override Material [] GetMaterials(Material[] mats)
Method returning instances of the materials used by the text object.
_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
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.
void UpdateSubObjectPivot()
Method to keep the pivot of the sub text objects in sync with the parent pivot.
override Material [] GetSharedMaterials()
Method returning an array containing the materials used by the text object.
override void SetFaceColor(Color32 color)
Function called internally to set the face color of the material. This will results in an instance of...
static bool warningsDisabled
Controls the display of warning message in the console.
override float GetPaddingForMaterial(Material mat)
Get the padding value for the currently assigned material.
override Bounds GetCompoundBounds()
Method returning the compound bounds of the text object and child sub objects.
void SaveWordWrappingState(ref WordWrapState state, int index, int count)
Function used in conjunction with GetTextInfo to figure out Array allocations.
static List< TMP_FontAsset > fallbackFontAssets
Returns the list of Fallback Fonts defined in the TMP Settings file.
static TMP_SpriteAsset defaultSpriteAsset
The Default Sprite Asset to be used by default.
override void SetSharedMaterial(Material mat)
Function called internally when a new shared material is assigned via the fontSharedMaterial property...
static LineBreakingTable linebreakingRules