diff --git a/CHANGELOG.md b/CHANGELOG.md index 09e19fc..be2b0fe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,21 @@ # Changelog These are the release notes for the TextMesh Pro UPM package which was first introduced with Unity 2018.1. Please see the following link for the Release Notes for prior versions of TextMesh Pro. http://digitalnativestudios.com/forum/index.php?topic=1363.0 +## [1.5.0-preview.12] - 2020-05-09 +## [2.1.0-preview.12] +## [3.0.0-preview.12] +### Changes +- Added synchronization of the RaycastTarget property of the parent <TextMeshProUGUI> with potential child sub text objects. Case #1240784 +- Fixed Font Asset Bold Spacing adjustment scaling based on the text object point size instead of current point size. Case #1241132 +- Improved text alignment when using RTL in conjunction with character, word and other spacing adjustments. +- Fixed TMP Input Field caret potentially not being visible when reaching the right side of the viewport. See [forum post](https://forum.unity.com/threads/inputfield-bug-2.879244/) for more details. +- Fixed TMP Input Field incorrect text RectTransform horizontal adjustment when using the Backspace key. See [forum post](https://forum.unity.com/threads/inputfield-bug4-delete-and-backspace-bug.879283/) for more details. +- Fixed potential null reference in the TextMeshProUGUI.Cull function when using a workflow that involves enabling / disabling Canvases in the scene. +- Fixed ArgumentOutOfRangeException when using the "Update Sprite Asset" inspector option on a sprite asset that does not contain any sprites. Case #1242936 +- Fixed incorrect culling of the text geometry by the RectMask2D component on newly created text objects. Case #1245445 +- It is now possible to use the Material Context Menu options to Copy / Paste Material Properties or Atlas Texture originally created for TMP with all other non TMP specific materials. Case #1242671 +- Fixed NullReferenceException when setting the Atlas Texture to None in the Debug Settings of the Material Inspector of a text object. Case #1245104 + ## [1.5.0-preview.11] - 2020-04-22 ## [2.1.0-preview.11] ## [3.0.0-preview.11] diff --git a/Scripts/Editor/TMP_SettingsEditor.cs b/Scripts/Editor/TMP_SettingsEditor.cs index e4b8d5c..f8c601e 100644 --- a/Scripts/Editor/TMP_SettingsEditor.cs +++ b/Scripts/Editor/TMP_SettingsEditor.cs @@ -27,6 +27,7 @@ internal class Styles public static readonly GUIContent textMeshProUiLabel = new GUIContent("TextMeshPro UI"); public static readonly GUIContent enableRaycastTarget = new GUIContent("Enable Raycast Target"); public static readonly GUIContent autoSizeContainerLabel = new GUIContent("Auto Size Text Container", "Set the size of the text container to match the text."); + public static readonly GUIContent isTextObjectScaleStaticLabel = new GUIContent("Is Object Scale Static", "Disables calling InternalUpdate() when enabled. This can improve performance when text object scale is static."); public static readonly GUIContent textComponentDefaultSettingsLabel = new GUIContent("Text Component Default Settings"); public static readonly GUIContent defaultFontSize = new GUIContent("Default Font Size"); @@ -73,6 +74,7 @@ internal class Styles SerializedProperty m_PropDefaultTextMeshProUITextContainerSize; SerializedProperty m_PropAutoSizeTextContainer; SerializedProperty m_PropEnableRaycastTarget; + SerializedProperty m_PropIsTextObjectScaleStatic; SerializedProperty m_PropSpriteAsset; SerializedProperty m_PropMissingSpriteCharacterUnicode; @@ -120,6 +122,7 @@ public void OnEnable() m_PropDefaultTextMeshProUITextContainerSize = serializedObject.FindProperty("m_defaultTextMeshProUITextContainerSize"); m_PropAutoSizeTextContainer = serializedObject.FindProperty("m_autoSizeTextContainer"); m_PropEnableRaycastTarget = serializedObject.FindProperty("m_EnableRaycastTarget"); + m_PropIsTextObjectScaleStatic = serializedObject.FindProperty("m_IsTextObjectScaleStatic"); m_PropSpriteAsset = serializedObject.FindProperty("m_defaultSpriteAsset"); m_PropMissingSpriteCharacterUnicode = serializedObject.FindProperty("m_MissingCharacterSpriteUnicode"); @@ -223,6 +226,7 @@ public override void OnInspectorGUI() EditorGUILayout.PropertyField(m_PropDefaultTextMeshProUITextContainerSize, Styles.textMeshProUiLabel); EditorGUILayout.PropertyField(m_PropEnableRaycastTarget, Styles.enableRaycastTarget); EditorGUILayout.PropertyField(m_PropAutoSizeTextContainer, Styles.autoSizeContainerLabel); + EditorGUILayout.PropertyField(m_PropIsTextObjectScaleStatic, Styles.isTextObjectScaleStaticLabel); EditorGUI.indentLevel = 0; EditorGUILayout.Space(); diff --git a/Scripts/Editor/TMP_SpriteAssetMenu.cs b/Scripts/Editor/TMP_SpriteAssetMenu.cs index 0e46711..344150b 100644 --- a/Scripts/Editor/TMP_SpriteAssetMenu.cs +++ b/Scripts/Editor/TMP_SpriteAssetMenu.cs @@ -10,7 +10,6 @@ namespace TMPro.EditorUtilities { - public static class TMP_SpriteAssetMenu { // Add a Context Menu to the Sprite Asset Editor Panel to Create and Add a Default Material. @@ -48,39 +47,70 @@ internal static void UpdateSpriteAsset(TMP_SpriteAsset spriteAsset) if (string.IsNullOrEmpty(filePath)) return; - // Get all the Sprites sorted Left to Right / Top to Bottom - Sprite[] sprites = AssetDatabase.LoadAllAssetsAtPath(filePath).Select(x => x as Sprite).Where(x => x != null).OrderByDescending(x => x.rect.y).ThenBy(x => x.rect.x).ToArray(); + // Get all the sprites defined in the sprite sheet texture referenced by this sprite asset. + Sprite[] sprites = AssetDatabase.LoadAllAssetsAtPath(filePath).Select(x => x as Sprite).Where(x => x != null).ToArray(); + + // Return if sprite sheet texture does not have any sprites defined in it. + if (sprites.Length == 0) + { + Debug.Log("Sprite Asset [" + spriteAsset.name + "]'s atlas texture does not appear to have any sprites defined in it. Use the Unity Sprite Editor to define sprites for this texture.", spriteAsset.spriteSheet); + return; + } List spriteGlyphTable = spriteAsset.spriteGlyphTable; - // Finding available glyph indexes to insert new glyphs into. - var tempGlyphTable = spriteGlyphTable.OrderBy(glyph => glyph.index).ToList(); + // Find available glpyh indexes + uint[] existingGlyphIndexes = spriteGlyphTable.Select(x => x.index).ToArray(); List availableGlyphIndexes = new List(); + uint lastGlyphIndex = existingGlyphIndexes.Length > 0 ? existingGlyphIndexes.Last() : 0; int elementIndex = 0; - for (uint i = 0; i < tempGlyphTable[tempGlyphTable.Count - 1].index; i++) + for (uint i = 0; i < lastGlyphIndex; i++) { - uint currentElementIndex = tempGlyphTable[elementIndex].index; + uint existingGlyphIndex = existingGlyphIndexes[elementIndex]; - if (i == currentElementIndex) + if (i == existingGlyphIndex) elementIndex += 1; else availableGlyphIndexes.Add(i); } - // Iterate over each of the sprites in the texture to try to match them to existing sprites in the sprite asset. + // Iterate over sprites contained in the updated sprite sheet to identify new and / or modified sprites. for (int i = 0; i < sprites.Length; i++) { - int id = sprites[i].GetInstanceID(); + Sprite sprite = sprites[i]; - int glyphIndex = spriteGlyphTable.FindIndex(item => item.sprite.GetInstanceID() == id); + // Check if current sprites is already contained in the sprite glyph table of the sprite asset. + TMP_SpriteGlyph spriteGlyph = spriteGlyphTable.FirstOrDefault(x => x.sprite == sprite); - if (glyphIndex == -1) + if (spriteGlyph != null) { - // Add new Sprite Glyph to the table - Sprite sprite = sprites[i]; + // update existing sprite glyph + if (spriteGlyph.glyphRect.x != sprite.rect.x || spriteGlyph.glyphRect.y != sprite.rect.y || spriteGlyph.glyphRect.width != sprite.rect.width || spriteGlyph.glyphRect.height != sprite.rect.height) + spriteGlyph.glyphRect = new GlyphRect(sprite.rect); + } + else + { + TMP_SpriteCharacter spriteCharacter; + + // Check if this sprite potentially exists under the same name in the sprite character table. + if (spriteAsset.spriteCharacterTable != null && spriteAsset.spriteCharacterTable.Count > 0) + { + spriteCharacter = spriteAsset.spriteCharacterTable.FirstOrDefault(x => x.name == sprite.name); + spriteGlyph = spriteCharacter != null ? spriteGlyphTable[(int)spriteCharacter.glyphIndex] : null; - TMP_SpriteGlyph spriteGlyph = new TMP_SpriteGlyph(); + if (spriteGlyph != null) + { + // Update sprite reference and data + spriteGlyph.sprite = sprite; + + if (spriteGlyph.glyphRect.x != sprite.rect.x || spriteGlyph.glyphRect.y != sprite.rect.y || spriteGlyph.glyphRect.width != sprite.rect.width || spriteGlyph.glyphRect.height != sprite.rect.height) + spriteGlyph.glyphRect = new GlyphRect(sprite.rect); + } + } + + // Add new Sprite Glyph to the table + spriteGlyph = new TMP_SpriteGlyph(); // Get available glyph index if (availableGlyphIndexes.Count > 0) @@ -98,23 +128,12 @@ internal static void UpdateSpriteAsset(TMP_SpriteAsset spriteAsset) spriteGlyphTable.Add(spriteGlyph); - TMP_SpriteCharacter spriteCharacter = new TMP_SpriteCharacter(0xFFFE, spriteGlyph); + spriteCharacter = new TMP_SpriteCharacter(0xFFFE, spriteGlyph); spriteCharacter.name = sprite.name; spriteCharacter.scale = 1.0f; spriteAsset.spriteCharacterTable.Add(spriteCharacter); } - else - { - // Look for changes in existing Sprite Glyph - Sprite sprite = sprites[i]; - - TMP_SpriteGlyph spriteGlyph = spriteGlyphTable[glyphIndex]; - - // We only update changes to the sprite position / glyph rect. - if (spriteGlyph.glyphRect.x != sprite.rect.x || spriteGlyph.glyphRect.y != sprite.rect.y || spriteGlyph.glyphRect.width != sprite.rect.width || spriteGlyph.glyphRect.height != sprite.rect.height) - spriteGlyph.glyphRect = new GlyphRect(sprite.rect); - } } // Update Sprite Character Table to replace unicode 0x0 by 0xFFFE @@ -129,6 +148,7 @@ internal static void UpdateSpriteAsset(TMP_SpriteAsset spriteAsset) spriteAsset.SortGlyphTable(); spriteAsset.UpdateLookupTables(); TMPro_EventManager.ON_SPRITE_ASSET_PROPERTY_CHANGED(true, spriteAsset); + } @@ -365,7 +385,5 @@ private static List UpdateSpriteInfo(TMP_SpriteAsset spriteAsset) return spriteAsset.spriteInfoList; } - - } } diff --git a/Scripts/Editor/TMPro_ContextMenus.cs b/Scripts/Editor/TMPro_ContextMenus.cs index 21410f4..a01760d 100644 --- a/Scripts/Editor/TMPro_ContextMenus.cs +++ b/Scripts/Editor/TMPro_ContextMenus.cs @@ -50,14 +50,14 @@ static void DuplicateMaterial(MenuCommand command) return; } - string assetPath = AssetDatabase.GetAssetPath(source_Mat).Split('.')[0]; + string assetPath = AssetDatabase.GetAssetPath(source_Mat).Split('.')[0]; if (assetPath.IndexOf("Assets/", System.StringComparison.InvariantCultureIgnoreCase) == -1) { Debug.LogWarning("Material Preset cannot be created from a material that is located outside the project."); return; } - + Material duplicate = new Material(source_Mat); // Need to manually copy the shader keywords @@ -241,15 +241,24 @@ static void PasteAtlas(MenuCommand command) { Material mat = command.context as Material; + if (mat == null) + return; + if (m_copiedAtlasProperties != null) { Undo.RecordObject(mat, "Paste Texture"); ShaderUtilities.GetShaderPropertyIDs(); // Make sure we have valid Property IDs - mat.SetTexture(ShaderUtilities.ID_MainTex, m_copiedAtlasProperties.GetTexture(ShaderUtilities.ID_MainTex)); - mat.SetFloat(ShaderUtilities.ID_GradientScale, m_copiedAtlasProperties.GetFloat(ShaderUtilities.ID_GradientScale)); - mat.SetFloat(ShaderUtilities.ID_TextureWidth, m_copiedAtlasProperties.GetFloat(ShaderUtilities.ID_TextureWidth)); - mat.SetFloat(ShaderUtilities.ID_TextureHeight, m_copiedAtlasProperties.GetFloat(ShaderUtilities.ID_TextureHeight)); + + if (m_copiedAtlasProperties.HasProperty(ShaderUtilities.ID_MainTex)) + mat.SetTexture(ShaderUtilities.ID_MainTex, m_copiedAtlasProperties.GetTexture(ShaderUtilities.ID_MainTex)); + + if (m_copiedAtlasProperties.HasProperty(ShaderUtilities.ID_GradientScale)) + { + mat.SetFloat(ShaderUtilities.ID_GradientScale, m_copiedAtlasProperties.GetFloat(ShaderUtilities.ID_GradientScale)); + mat.SetFloat(ShaderUtilities.ID_TextureWidth, m_copiedAtlasProperties.GetFloat(ShaderUtilities.ID_TextureWidth)); + mat.SetFloat(ShaderUtilities.ID_TextureHeight, m_copiedAtlasProperties.GetFloat(ShaderUtilities.ID_TextureHeight)); + } } else if (m_copiedTexture != null) { @@ -294,7 +303,7 @@ static void ExtractAtlas(MenuCommand command) } /// - /// + /// /// /// [MenuItem("CONTEXT/TMP_FontAsset/Update Atlas Texture...", false, 2000)] @@ -355,4 +364,4 @@ static void CreateFontAsset(MenuCommand command) } } } -} \ No newline at end of file +} diff --git a/Scripts/Runtime/TMP_InputField.cs b/Scripts/Runtime/TMP_InputField.cs index 91db26f..51cce0c 100644 --- a/Scripts/Runtime/TMP_InputField.cs +++ b/Scripts/Runtime/TMP_InputField.cs @@ -3717,18 +3717,16 @@ private void AdjustRectTransformRelativeToViewport(Vector2 startPosition, float if (m_TextViewport == null) return; - Vector2 caretPosition = new Vector2(startPosition.x + m_TextComponent.rectTransform.localPosition.x + m_TextViewport.localPosition.x + transform.localPosition.x, startPosition.y + m_TextComponent.rectTransform.localPosition.y + m_TextViewport.localPosition.y + transform.localPosition.y); + Vector3 localPosition = transform.localPosition; + Vector3 textComponentLocalPosition = m_TextComponent.rectTransform.localPosition; + Vector3 textViewportLocalPosition = m_TextViewport.localPosition; + Rect textViewportRect = m_TextViewport.rect; - Rect viewportWSRect = new Rect(transform.localPosition.x + m_TextViewport.localPosition.x + m_TextViewport.rect.x, transform.localPosition.y + m_TextViewport.localPosition.y + m_TextViewport.rect.y, m_TextViewport.rect.width, m_TextViewport.rect.height); - //Rect textWSRect = new Rect(m_TextComponent.rectTransform.localPosition.x + m_TextComponent.rectTransform.rect.x, m_TextComponent.rectTransform.localPosition.y + m_TextComponent.rectTransform.rect.y, m_TextComponent.rectTransform.rect.width, m_TextComponent.rectTransform.rect.height); - - //Debug.Log("Caret: " + caretPositionWS.ToString("f4") + - // "\nViewport: " + m_TextViewport.position.ToString("f4") + " Rect: " + viewportMinWS.ToString("f4") + " Max: " + viewportMaxWS.ToString("f4") + - // "\nText: " + m_TextComponent.rectTransform.position.ToString("f4") + textRectMinWS.ToString("f4") + " Max: " + textRectMaxWS.ToString("f4")); + Vector2 caretPosition = new Vector2(startPosition.x + textComponentLocalPosition.x + textViewportLocalPosition.x + localPosition.x, startPosition.y + textComponentLocalPosition.y + textViewportLocalPosition.y + localPosition.y); + Rect viewportWSRect = new Rect(localPosition.x + textViewportLocalPosition.x + textViewportRect.x, localPosition.y + textViewportLocalPosition.y + textViewportRect.y, textViewportRect.width, textViewportRect.height); // Adjust the position of the RectTransform based on the caret position in the viewport. - float rightOffset = viewportWSRect.xMax - (caretPosition.x + m_TextComponent.margin.z); - //float rightOffset = viewportMaxWS.x - (caretPositionWS.x + m_TextComponent.margin.z); + float rightOffset = viewportWSRect.xMax - (caretPosition.x + m_TextComponent.margin.z + m_CaretWidth); if (rightOffset < 0f) { if (!multiLine || (multiLine && isCharVisible)) @@ -3775,10 +3773,10 @@ private void AdjustRectTransformRelativeToViewport(Vector2 startPosition, float { float anchoredPositionX = m_TextComponent.rectTransform.anchoredPosition.x; - float firstCharPosition = transform.localPosition.x + m_TextViewport.localPosition.x + m_TextComponent.rectTransform.localPosition.x + m_TextComponent.textInfo.characterInfo[0].origin - m_TextComponent.margin.x; - float lastCharPosition = transform.localPosition.x + m_TextViewport.localPosition.x + m_TextComponent.rectTransform.localPosition.x + m_TextComponent.textInfo.characterInfo[m_TextComponent.textInfo.characterCount - 1].origin + m_TextComponent.margin.z; + float firstCharPosition = localPosition.x + textViewportLocalPosition.x + textComponentLocalPosition.x + m_TextComponent.textInfo.characterInfo[0].origin - m_TextComponent.margin.x; + float lastCharPosition = localPosition.x + textViewportLocalPosition.x + textComponentLocalPosition.x + m_TextComponent.textInfo.characterInfo[m_TextComponent.textInfo.characterCount - 1].origin + m_TextComponent.margin.z + m_CaretWidth; - if (anchoredPositionX > 0.0001f) + if (anchoredPositionX > 0.0001f && firstCharPosition > viewportWSRect.xMin) { float offset = viewportWSRect.xMin - firstCharPosition; @@ -3788,7 +3786,7 @@ private void AdjustRectTransformRelativeToViewport(Vector2 startPosition, float m_TextComponent.rectTransform.anchoredPosition += new Vector2(offset, 0); AssignPositioningIfNeeded(); } - else if (anchoredPositionX < -0.0001f) + else if (anchoredPositionX < -0.0001f && lastCharPosition < viewportWSRect.xMax) { float offset = viewportWSRect.xMax - lastCharPosition; diff --git a/Scripts/Runtime/TMP_Settings.cs b/Scripts/Runtime/TMP_Settings.cs index c7ab798..d5909fb 100644 --- a/Scripts/Runtime/TMP_Settings.cs +++ b/Scripts/Runtime/TMP_Settings.cs @@ -200,6 +200,18 @@ public static bool autoSizeTextContainer [SerializeField] private bool m_autoSizeTextContainer; + /// + /// Disables InternalUpdate() calls when true. This can improve performance when the scale of the text object is static. + /// + public static bool isTextObjectScaleStatic + { + get { return instance.m_IsTextObjectScaleStatic; } + set { instance.m_IsTextObjectScaleStatic = value; } + } + [SerializeField] + private bool m_IsTextObjectScaleStatic; + + /// /// Returns the list of Fallback Fonts defined in the TMP Settings file. /// diff --git a/Scripts/Runtime/TMP_SpriteCharacter.cs b/Scripts/Runtime/TMP_SpriteCharacter.cs index fa91690..51faacb 100644 --- a/Scripts/Runtime/TMP_SpriteCharacter.cs +++ b/Scripts/Runtime/TMP_SpriteCharacter.cs @@ -70,5 +70,37 @@ public TMP_SpriteCharacter(uint unicode, TMP_SpriteGlyph glyph) this.scale = 1.0f; } + /// + /// Constructor for new sprite character. + /// + /// Unicode value of the sprite character. + /// Sprite Asset used by this sprite character. + /// Glyph used by the sprite character. + public TMP_SpriteCharacter(uint unicode, TMP_SpriteAsset spriteAsset, TMP_SpriteGlyph glyph) + { + m_ElementType = TextElementType.Sprite; + + this.unicode = unicode; + this.textAsset = spriteAsset; + this.glyph = glyph; + this.glyphIndex = glyph.index; + this.scale = 1.0f; + } + + /// + /// + /// + /// + /// + internal TMP_SpriteCharacter(uint unicode, uint glyphIndex) + { + m_ElementType = TextElementType.Sprite; + + this.unicode = unicode; + this.textAsset = null; + this.glyph = null; + this.glyphIndex = glyphIndex; + this.scale = 1.0f; + } } -} \ No newline at end of file +} diff --git a/Scripts/Runtime/TMP_SubMesh.cs b/Scripts/Runtime/TMP_SubMesh.cs index d0a4d02..e8272ac 100644 --- a/Scripts/Runtime/TMP_SubMesh.cs +++ b/Scripts/Runtime/TMP_SubMesh.cs @@ -1,6 +1,7 @@ using UnityEngine; using System; using System.Collections; +using Object = UnityEngine.Object; #pragma warning disable 0109 // Disable warning due to conflict between Unity Editor DLL and Runtime DLL related to .renderer property being available in one but not the other. @@ -391,9 +392,9 @@ void ON_SPRITE_ASSET_PROPERTY_CHANGED(bool isChanged, UnityEngine.Object obj) } // Event received when font asset properties are changed in Font Inspector - void ON_FONT_PROPERTY_CHANGED(bool isChanged, TMP_FontAsset font) + void ON_FONT_PROPERTY_CHANGED(bool isChanged, Object fontAsset) { - if (m_fontAsset != null && font.GetInstanceID() == m_fontAsset.GetInstanceID()) + if (m_fontAsset != null && fontAsset.GetInstanceID() == m_fontAsset.GetInstanceID()) { // Copy Normal and Bold Weight if (m_fallbackMaterial != null) diff --git a/Scripts/Runtime/TMP_SubMeshUI.cs b/Scripts/Runtime/TMP_SubMeshUI.cs index d17a44e..5a9068a 100644 --- a/Scripts/Runtime/TMP_SubMeshUI.cs +++ b/Scripts/Runtime/TMP_SubMeshUI.cs @@ -2,6 +2,7 @@ using UnityEngine.UI; using System.Collections; using System.Collections.Generic; +using Object = UnityEngine.Object; #pragma warning disable 0414 // Disabled a few warnings related to serialized variables not used in this script but used in the editor. @@ -452,9 +453,9 @@ void ON_SPRITE_ASSET_PROPERTY_CHANGED(bool isChanged, UnityEngine.Object obj) } // Event received when font asset properties are changed in Font Inspector - void ON_FONT_PROPERTY_CHANGED(bool isChanged, TMP_FontAsset font) + void ON_FONT_PROPERTY_CHANGED(bool isChanged, Object fontAsset) { - if (m_fontAsset != null && font.GetInstanceID() == m_fontAsset.GetInstanceID()) + if (m_fontAsset != null && fontAsset.GetInstanceID() == m_fontAsset.GetInstanceID()) { // Copy Normal and Bold Weight if (m_fallbackMaterial != null) diff --git a/Scripts/Runtime/TMP_Text.cs b/Scripts/Runtime/TMP_Text.cs index bc45dc0..d8b235a 100644 --- a/Scripts/Runtime/TMP_Text.cs +++ b/Scripts/Runtime/TMP_Text.cs @@ -841,7 +841,7 @@ public bool enableKerning } [SerializeField] protected bool m_enableKerning; - + protected float m_GlyphHorizontalAdvanceAdjustment; /// /// Adds extra padding around each character. This may be necessary when the displayed text is very small to prevent clipping. @@ -5826,7 +5826,7 @@ protected virtual Vector2 CalculatePreferredValues(ref float fontSize, Vector2 m } else { - m_xAdvance += ((currentGlyphMetrics.horizontalAdvance + glyphAdjustments.xAdvance) * currentElementScale + (m_currentFontAsset.normalSpacingOffset + characterSpacingAdjustment + boldSpacingAdjustment) * currentEmScale + m_cSpacing) * (1 - m_charWidthAdjDelta); + m_xAdvance += ((currentGlyphMetrics.horizontalAdvance + glyphAdjustments.xAdvance + boldSpacingAdjustment) * currentElementScale + (m_currentFontAsset.normalSpacingOffset + characterSpacingAdjustment) * currentEmScale + m_cSpacing) * (1 - m_charWidthAdjDelta); if (isWhiteSpace || charCode == 0x200B) m_xAdvance += m_wordSpacing * currentEmScale; @@ -6238,7 +6238,7 @@ public virtual void ComputeMarginSize() { } //} - protected void InsertNewLine(int i, float baseScale, float currentEmScale, float characterSpacingAdjustment, float width, float lineGap, ref bool isMaxVisibleDescenderSet, ref float maxVisibleDescender) + protected void InsertNewLine(int i, float baseScale, float currentElementScale, float currentEmScale, float glyphAdjustment, float boldSpacingAdjustment, float characterSpacingAdjustment, float width, float lineGap, ref bool isMaxVisibleDescenderSet, ref float maxVisibleDescender) { // Adjust line spacing if necessary float baselineAdjustmentDelta = m_maxLineAscender - m_startOfLineAscender; @@ -6264,7 +6264,7 @@ protected void InsertNewLine(int i, float baseScale, float currentEmScale, float // Track & Store lineInfo for the new line m_textInfo.lineInfo[m_lineNumber].firstCharacterIndex = m_firstCharacterOfLine; m_textInfo.lineInfo[m_lineNumber].firstVisibleCharacterIndex = m_firstVisibleCharacterOfLine = m_firstCharacterOfLine > m_firstVisibleCharacterOfLine ? m_firstCharacterOfLine : m_firstVisibleCharacterOfLine; - m_textInfo.lineInfo[m_lineNumber].lastCharacterIndex = m_lastCharacterOfLine = m_characterCount - 1 > 0 ? m_characterCount - 1 : 0; + int lastCharacterIndex = m_textInfo.lineInfo[m_lineNumber].lastCharacterIndex = m_lastCharacterOfLine = m_characterCount - 1 > 0 ? m_characterCount - 1 : 0; m_textInfo.lineInfo[m_lineNumber].lastVisibleCharacterIndex = m_lastVisibleCharacterOfLine = m_lastVisibleCharacterOfLine < m_firstVisibleCharacterOfLine ? m_firstVisibleCharacterOfLine : m_lastVisibleCharacterOfLine; m_textInfo.lineInfo[m_lineNumber].characterCount = m_textInfo.lineInfo[m_lineNumber].lastCharacterIndex - m_textInfo.lineInfo[m_lineNumber].firstCharacterIndex + 1; @@ -6274,7 +6274,9 @@ protected void InsertNewLine(int i, float baseScale, float currentEmScale, float m_textInfo.lineInfo[m_lineNumber].length = m_textInfo.lineInfo[m_lineNumber].lineExtents.max.x; m_textInfo.lineInfo[m_lineNumber].width = width; - m_textInfo.lineInfo[m_lineNumber].maxAdvance = m_textInfo.characterInfo[m_lastVisibleCharacterOfLine].xAdvance - (m_currentFontAsset.normalSpacingOffset + characterSpacingAdjustment) * currentEmScale - m_cSpacing; + float maxAdvanceOffset = ((glyphAdjustment + boldSpacingAdjustment) * currentElementScale + (m_currentFontAsset.normalSpacingOffset + characterSpacingAdjustment) * currentEmScale - m_cSpacing) * (1 - m_charWidthAdjDelta); + float adjustedHorizontalAdvance = m_textInfo.lineInfo[m_lineNumber].maxAdvance = m_textInfo.characterInfo[m_lastVisibleCharacterOfLine].xAdvance + (m_isRightToLeft ? maxAdvanceOffset : - maxAdvanceOffset); + m_textInfo.characterInfo[lastCharacterIndex].xAdvance = adjustedHorizontalAdvance; m_textInfo.lineInfo[m_lineNumber].baseline = 0 - m_lineOffset; m_textInfo.lineInfo[m_lineNumber].ascender = lineAscender; @@ -6363,6 +6365,7 @@ protected void SaveWordWrappingState(ref WordWrapState state, int index, int cou state.lineOffset = m_lineOffset; state.baselineOffset = m_baselineOffset; state.isDrivenLineSpacing = m_IsDrivenLineSpacing; + state.glyphHorizontalAdvanceAdjustment = m_GlyphHorizontalAdvanceAdjustment; state.cSpace = m_cSpacing; state.mSpace = m_monoSpacing; @@ -6371,7 +6374,6 @@ protected void SaveWordWrappingState(ref WordWrapState state, int index, int cou state.marginLeft = m_marginLeft; state.marginRight = m_marginRight; - state.vertexColor = m_htmlColor; state.underlineColor = m_underlineColor; state.strikethroughColor = m_strikethroughColor; @@ -6454,6 +6456,7 @@ protected int RestoreWordWrappingState(ref WordWrapState state) m_lineOffset = state.lineOffset; m_baselineOffset = state.baselineOffset; m_IsDrivenLineSpacing = state.isDrivenLineSpacing; + m_GlyphHorizontalAdvanceAdjustment = state.glyphHorizontalAdvanceAdjustment; m_cSpacing = state.cSpace; m_monoSpacing = state.mSpace; @@ -7210,6 +7213,7 @@ protected void LoadDefaultSettings() m_fontSizeMax = m_fontSize * TMP_Settings.defaultTextAutoSizingMaxRatio; m_isWaitingOnResourceLoad = false; raycastTarget = TMP_Settings.enableRaycastTarget; + m_IsTextObjectScaleStatic = TMP_Settings.isTextObjectScaleStatic; } else if ((int)m_textAlignment < 0xFF) { diff --git a/Scripts/Runtime/TMP_UpdateManager.cs b/Scripts/Runtime/TMP_UpdateManager.cs index 8d51686..3fbcf8a 100644 --- a/Scripts/Runtime/TMP_UpdateManager.cs +++ b/Scripts/Runtime/TMP_UpdateManager.cs @@ -1,4 +1,5 @@ using UnityEngine; +using UnityEngine.Profiling; using UnityEngine.UI; using System.Collections.Generic; @@ -10,14 +11,9 @@ public class TMP_UpdateManager { private static TMP_UpdateManager s_Instance; - private readonly List m_LayoutRebuildQueue = new List(); - private readonly HashSet m_LayoutQueueLookup = new HashSet(); - - private readonly List m_GraphicRebuildQueue = new List(); - private readonly HashSet m_GraphicQueueLookup = new HashSet(); - - private readonly List m_InternalUpdateQueue = new List(); - private readonly HashSet m_InternalUpdateLookup = new HashSet(); + private readonly HashSet m_LayoutRebuildQueue = new HashSet(); + private readonly HashSet m_GraphicRebuildQueue = new HashSet(); + private readonly HashSet m_InternalUpdateQueue = new HashSet(); /// @@ -48,17 +44,18 @@ static TMP_UpdateManager instance /// internal static void RegisterTextObjectForUpdate(TMP_Text textObject) { + Profiler.BeginSample("TMP.RegisterTextObjectForUpdate"); + instance.InternalRegisterTextObjectForUpdate(textObject); + + Profiler.EndSample(); } private void InternalRegisterTextObjectForUpdate(TMP_Text textObject) { - int id = textObject.GetInstanceID(); - - if (m_InternalUpdateLookup.Contains(id)) + if (m_InternalUpdateQueue.Contains(textObject)) return; - m_InternalUpdateLookup.Add(id); m_InternalUpdateQueue.Add(textObject); } @@ -73,12 +70,9 @@ public static void RegisterTextElementForLayoutRebuild(TMP_Text element) private void InternalRegisterTextElementForLayoutRebuild(TMP_Text element) { - int id = element.GetInstanceID(); - - if (m_LayoutQueueLookup.Contains(id)) + if (m_LayoutRebuildQueue.Contains(element)) return; - m_LayoutQueueLookup.Add(id); m_LayoutRebuildQueue.Add(element); } @@ -88,17 +82,18 @@ private void InternalRegisterTextElementForLayoutRebuild(TMP_Text element) /// public static void RegisterTextElementForGraphicRebuild(TMP_Text element) { + Profiler.BeginSample("TMP.RegisterTextElementForGraphicRebuild"); + instance.InternalRegisterTextElementForGraphicRebuild(element); + + Profiler.EndSample(); } private void InternalRegisterTextElementForGraphicRebuild(TMP_Text element) { - int id = element.GetInstanceID(); - - if (m_GraphicQueueLookup.Contains(id)) + if (m_GraphicRebuildQueue.Contains(element)) return; - m_GraphicQueueLookup.Add(id); m_GraphicRebuildQueue.Add(element); } @@ -115,41 +110,37 @@ void OnCameraPreCull() /// void DoRebuilds() { - // Handle text objects the require an update either as a result of scale changes or legacy animation. - for (int i = 0; i < m_InternalUpdateQueue.Count; i++) - { - m_InternalUpdateQueue[i].InternalUpdate(); - } + Profiler.BeginSample("TMP.DoRebuilds"); + + // Handle text objects that require an update either as a result of scale changes or legacy animation. + foreach (var textObject in m_InternalUpdateQueue) + textObject.InternalUpdate(); // Handle Layout Rebuild Phase - for (int i = 0; i < m_LayoutRebuildQueue.Count; i++) - { - m_LayoutRebuildQueue[i].Rebuild(CanvasUpdate.Prelayout); - } + foreach (var textObject in m_LayoutRebuildQueue) + textObject.Rebuild(CanvasUpdate.Prelayout); if (m_LayoutRebuildQueue.Count > 0) - { m_LayoutRebuildQueue.Clear(); - m_LayoutQueueLookup.Clear(); - } // Handle Graphic Rebuild Phase - for (int i = 0; i < m_GraphicRebuildQueue.Count; i++) - { - m_GraphicRebuildQueue[i].Rebuild(CanvasUpdate.PreRender); - } + foreach (var textObject in m_GraphicRebuildQueue) + textObject.Rebuild(CanvasUpdate.PreRender); // If there are no objects in the queue, we don't need to clear the lists again. if (m_GraphicRebuildQueue.Count > 0) - { m_GraphicRebuildQueue.Clear(); - m_GraphicQueueLookup.Clear(); - } + + Profiler.EndSample(); } internal static void UnRegisterTextObjectForUpdate(TMP_Text textObject) { + Profiler.BeginSample("TMP.UnRegisterTextObjectForUpdate"); + instance.InternalUnRegisterTextObjectForUpdate(textObject); + + Profiler.EndSample(); } /// @@ -165,26 +156,21 @@ public static void UnRegisterTextElementForRebuild(TMP_Text element) private void InternalUnRegisterTextElementForGraphicRebuild(TMP_Text element) { - int id = element.GetInstanceID(); + Profiler.BeginSample("TMP.InternalUnRegisterTextElementForGraphicRebuild"); - instance.m_GraphicRebuildQueue.Remove(element); - m_GraphicQueueLookup.Remove(id); + m_GraphicRebuildQueue.Remove(element); + + Profiler.EndSample(); } private void InternalUnRegisterTextElementForLayoutRebuild(TMP_Text element) { - int id = element.GetInstanceID(); - - instance.m_LayoutRebuildQueue.Remove(element); - m_LayoutQueueLookup.Remove(id); + m_LayoutRebuildQueue.Remove(element); } private void InternalUnRegisterTextObjectForUpdate(TMP_Text textObject) { - int id = textObject.GetInstanceID(); - - instance.m_InternalUpdateQueue.Remove(textObject); - m_InternalUpdateLookup.Remove(id); + m_InternalUpdateQueue.Remove(textObject); } } } diff --git a/Scripts/Runtime/TMPro_EventManager.cs b/Scripts/Runtime/TMPro_EventManager.cs index 5d2c9a9..be9d9a4 100644 --- a/Scripts/Runtime/TMPro_EventManager.cs +++ b/Scripts/Runtime/TMPro_EventManager.cs @@ -14,23 +14,23 @@ public static class TMPro_EventManager // Event & Delegate used to notify TextMesh Pro objects that Material properties have been changed. public static readonly FastAction MATERIAL_PROPERTY_EVENT = new FastAction(); - public static readonly FastAction FONT_PROPERTY_EVENT = new FastAction(); + public static readonly FastAction FONT_PROPERTY_EVENT = new FastAction(); public static readonly FastAction SPRITE_ASSET_PROPERTY_EVENT = new FastAction(); - public static readonly FastAction TEXTMESHPRO_PROPERTY_EVENT = new FastAction(); + public static readonly FastAction TEXTMESHPRO_PROPERTY_EVENT = new FastAction(); public static readonly FastAction DRAG_AND_DROP_MATERIAL_EVENT = new FastAction(); public static readonly FastAction TEXT_STYLE_PROPERTY_EVENT = new FastAction(); - public static readonly FastAction COLOR_GRADIENT_PROPERTY_EVENT = new FastAction(); + public static readonly FastAction COLOR_GRADIENT_PROPERTY_EVENT = new FastAction(); public static readonly FastAction TMP_SETTINGS_PROPERTY_EVENT = new FastAction(); public static readonly FastAction RESOURCE_LOAD_EVENT = new FastAction(); - public static readonly FastAction TEXTMESHPRO_UGUI_PROPERTY_EVENT = new FastAction(); + public static readonly FastAction TEXTMESHPRO_UGUI_PROPERTY_EVENT = new FastAction(); public static readonly FastAction OnPreRenderObject_Event = new FastAction(); @@ -57,9 +57,9 @@ public static void ON_MATERIAL_PROPERTY_CHANGED(bool isChanged, Material mat) MATERIAL_PROPERTY_EVENT.Call(isChanged, mat); } - public static void ON_FONT_PROPERTY_CHANGED(bool isChanged, TMP_FontAsset font) + public static void ON_FONT_PROPERTY_CHANGED(bool isChanged, Object obj) { - FONT_PROPERTY_EVENT.Call(isChanged, font); + FONT_PROPERTY_EVENT.Call(isChanged, obj); } public static void ON_SPRITE_ASSET_PROPERTY_CHANGED(bool isChanged, Object obj) @@ -67,7 +67,7 @@ public static void ON_SPRITE_ASSET_PROPERTY_CHANGED(bool isChanged, Object obj) SPRITE_ASSET_PROPERTY_EVENT.Call(isChanged, obj); } - public static void ON_TEXTMESHPRO_PROPERTY_CHANGED(bool isChanged, TextMeshPro obj) + public static void ON_TEXTMESHPRO_PROPERTY_CHANGED(bool isChanged, Object obj) { TEXTMESHPRO_PROPERTY_EVENT.Call(isChanged, obj); } @@ -82,9 +82,9 @@ public static void ON_TEXT_STYLE_PROPERTY_CHANGED(bool isChanged) TEXT_STYLE_PROPERTY_EVENT.Call(isChanged); } - public static void ON_COLOR_GRADIENT_PROPERTY_CHANGED(TMP_ColorGradient gradient) + public static void ON_COLOR_GRADIENT_PROPERTY_CHANGED(Object obj) { - COLOR_GRADIENT_PROPERTY_EVENT.Call(gradient); + COLOR_GRADIENT_PROPERTY_EVENT.Call(obj); } @@ -103,7 +103,7 @@ public static void ON_RESOURCES_LOADED() RESOURCE_LOAD_EVENT.Call(); } - public static void ON_TEXTMESHPRO_UGUI_PROPERTY_CHANGED(bool isChanged, TextMeshProUGUI obj) + public static void ON_TEXTMESHPRO_UGUI_PROPERTY_CHANGED(bool isChanged, Object obj) { TEXTMESHPRO_UGUI_PROPERTY_EVENT.Call(isChanged, obj); } @@ -147,4 +147,4 @@ public Compute_DT_EventArgs(Compute_DistanceTransform_EventTypes type, Color[] c } -} \ No newline at end of file +} diff --git a/Scripts/Runtime/TMPro_MeshUtilities.cs b/Scripts/Runtime/TMPro_MeshUtilities.cs index 88a8efd..80cce3a 100644 --- a/Scripts/Runtime/TMPro_MeshUtilities.cs +++ b/Scripts/Runtime/TMPro_MeshUtilities.cs @@ -384,6 +384,7 @@ public struct WordWrapState public float baselineOffset; public float lineOffset; public bool isDrivenLineSpacing; + public float glyphHorizontalAdvanceAdjustment; public float cSpace; public float mSpace; diff --git a/Scripts/Runtime/TMPro_Private.cs b/Scripts/Runtime/TMPro_Private.cs index dfbcd6f..6e7a7db 100644 --- a/Scripts/Runtime/TMPro_Private.cs +++ b/Scripts/Runtime/TMPro_Private.cs @@ -6,6 +6,7 @@ using System; using System.Collections; using System.Collections.Generic; +using Object = UnityEngine.Object; #if TMP_PROFILE_ON using UnityEngine.Profiling; @@ -333,12 +334,12 @@ void ON_MATERIAL_PROPERTY_CHANGED(bool isChanged, Material mat) Debug.LogWarning("No Font Asset assigned to " + name + ". Please assign a Font Asset.", this); } - if (m_fontAsset.atlasTexture != null && m_fontAsset.atlasTexture.GetInstanceID() != m_renderer.sharedMaterial.GetTexture(ShaderUtilities.ID_MainTex).GetInstanceID()) - { - m_renderer.sharedMaterial = m_sharedMaterial; - //m_renderer.sharedMaterial = m_fontAsset.material; - Debug.LogWarning("Font Asset Atlas doesn't match the Atlas in the newly assigned material. Select a matching material or a different font asset.", this); - } + // if (m_fontAsset.atlasTexture != null && m_fontAsset.atlasTexture.GetInstanceID() != m_renderer.sharedMaterial.GetTexture(ShaderUtilities.ID_MainTex).GetInstanceID()) + // { + // m_renderer.sharedMaterial = m_sharedMaterial; + // //m_renderer.sharedMaterial = m_fontAsset.material; + // Debug.LogWarning("Font Asset Atlas doesn't match the Atlas in the newly assigned material. Select a matching material or a different font asset.", this); + // } if (m_renderer.sharedMaterial != m_sharedMaterial) // || m_renderer.sharedMaterials.Contains(mat)) { @@ -358,11 +359,11 @@ void ON_MATERIAL_PROPERTY_CHANGED(bool isChanged, Material mat) // Event received when font asset properties are changed in Font Inspector - void ON_FONT_PROPERTY_CHANGED(bool isChanged, TMP_FontAsset font) + void ON_FONT_PROPERTY_CHANGED(bool isChanged, Object fontAsset) { //Debug.Log("ON_FONT_PROPERTY_CHANGED event received. Target is [" + font.name + "]"); - if (MaterialReference.Contains(m_materialReferences, font)) + if (MaterialReference.Contains(m_materialReferences, (TMP_FontAsset)fontAsset)) { //Debug.Log("ON_FONT_PROPERTY_CHANGED event received."); m_isInputParsingRequired = true; @@ -377,9 +378,9 @@ void ON_FONT_PROPERTY_CHANGED(bool isChanged, TMP_FontAsset font) // Event received when UNDO / REDO Event alters the properties of the object. - void ON_TEXTMESHPRO_PROPERTY_CHANGED(bool isChanged, TextMeshPro obj) + void ON_TEXTMESHPRO_PROPERTY_CHANGED(bool isChanged, Object textComponent) { - if (obj == this) + if (textComponent == this) { //Debug.Log("Undo / Redo Event Received by Object ID:" + GetInstanceID()); m_havePropertiesChanged = true; @@ -433,7 +434,7 @@ void ON_TEXT_STYLE_CHANGED(bool isChanged) /// Event received when a Color Gradient Preset is modified. /// /// - void ON_COLOR_GRADIENT_CHANGED(TMP_ColorGradient gradient) + void ON_COLOR_GRADIENT_CHANGED(Object gradient) { m_havePropertiesChanged = true; @@ -2015,6 +2016,7 @@ protected override void GenerateTextMesh() #region Handle Kerning TMP_GlyphValueRecord glyphAdjustments = new TMP_GlyphValueRecord(); float characterSpacingAdjustment = m_characterSpacing; + m_GlyphHorizontalAdvanceAdjustment = 0; if (m_enableKerning) { #if TMP_PROFILE_ON @@ -2048,6 +2050,8 @@ protected override void GenerateTextMesh() } } + m_GlyphHorizontalAdvanceAdjustment = glyphAdjustments.m_XAdvance; + #if TMP_PROFILE_ON Profiler.EndSample(); #endif @@ -2059,7 +2063,7 @@ protected override void GenerateTextMesh() #region Handle Right-to-Left if (m_isRightToLeft) { - m_xAdvance -= ((currentGlyphMetrics.horizontalAdvance * currentElementScale) + (m_currentFontAsset.normalSpacingOffset + characterSpacingAdjustment + m_wordSpacing + boldSpacingAdjustment) * currentEmScale + m_cSpacing) * (1 - m_charWidthAdjDelta); + m_xAdvance -= currentGlyphMetrics.horizontalAdvance * (1 - m_charWidthAdjDelta) * currentElementScale; if (isWhiteSpace || charCode == 0x200B) m_xAdvance -= m_wordSpacing * currentEmScale; @@ -2665,7 +2669,7 @@ protected override void GenerateTextMesh() Profiler.BeginSample("TMP - InsertNewLine()"); #endif - InsertNewLine(i, baseScale, currentEmScale, characterSpacingAdjustment, widthOfTextArea, lineGap, ref isMaxVisibleDescenderSet, ref maxVisibleDescender); + InsertNewLine(i, baseScale, currentElementScale, currentEmScale, m_GlyphHorizontalAdvanceAdjustment, boldSpacingAdjustment, characterSpacingAdjustment, widthOfTextArea, lineGap, ref isMaxVisibleDescenderSet, ref maxVisibleDescender); isStartOfNewLine = true; isFirstWordOfLine = true; @@ -2730,7 +2734,7 @@ protected override void GenerateTextMesh() // Add new page m_isNewPage = true; - InsertNewLine(i, baseScale, currentEmScale, characterSpacingAdjustment, widthOfTextArea, lineGap, ref isMaxVisibleDescenderSet, ref maxVisibleDescender); + InsertNewLine(i, baseScale, currentElementScale, currentEmScale, m_GlyphHorizontalAdvanceAdjustment, boldSpacingAdjustment, characterSpacingAdjustment, widthOfTextArea, lineGap, ref isMaxVisibleDescenderSet, ref maxVisibleDescender); m_startOfLineAscender = 0; m_lineOffset = 0; @@ -2774,7 +2778,7 @@ protected override void GenerateTextMesh() Profiler.BeginSample("TMP - InsertNewLine()"); #endif // New line of text does not exceed vertical bounds of text container - InsertNewLine(i, baseScale, currentEmScale, characterSpacingAdjustment, widthOfTextArea, lineGap, ref isMaxVisibleDescenderSet, ref maxVisibleDescender); + InsertNewLine(i, baseScale, currentElementScale, currentEmScale, m_GlyphHorizontalAdvanceAdjustment, boldSpacingAdjustment, characterSpacingAdjustment, widthOfTextArea, lineGap, ref isMaxVisibleDescenderSet, ref maxVisibleDescender); isStartOfNewLine = true; isFirstWordOfLine = true; @@ -3037,20 +3041,23 @@ protected override void GenerateTextMesh() if (isWhiteSpace || charCode == 0x200B) m_xAdvance += m_wordSpacing * currentEmScale; } - else if (!m_isRightToLeft) + else if (m_isRightToLeft) + { + m_xAdvance -= (((glyphAdjustments.m_XAdvance + boldSpacingAdjustment) * currentElementScale + (m_currentFontAsset.normalSpacingOffset + characterSpacingAdjustment) * currentEmScale + m_cSpacing) * (1 - m_charWidthAdjDelta)); + + if (isWhiteSpace || charCode == 0x200B) + m_xAdvance -= m_wordSpacing * currentEmScale; + } + else { float scaleFXMultiplier = 1; if (m_isFXMatrixSet) scaleFXMultiplier = m_FXMatrix.lossyScale.x; - m_xAdvance += ((currentGlyphMetrics.horizontalAdvance * scaleFXMultiplier + glyphAdjustments.m_XAdvance) * currentElementScale + (m_currentFontAsset.normalSpacingOffset + characterSpacingAdjustment + boldSpacingAdjustment) * currentEmScale + m_cSpacing) * (1 - m_charWidthAdjDelta); + m_xAdvance += ((currentGlyphMetrics.horizontalAdvance * scaleFXMultiplier + glyphAdjustments.m_XAdvance + boldSpacingAdjustment) * currentElementScale + (m_currentFontAsset.normalSpacingOffset + characterSpacingAdjustment) * currentEmScale + m_cSpacing) * (1 - m_charWidthAdjDelta); if (isWhiteSpace || charCode == 0x200B) m_xAdvance += m_wordSpacing * currentEmScale; } - else - { - m_xAdvance -= glyphAdjustments.m_XAdvance * currentElementScale; - } // Store xAdvance information m_textInfo.characterInfo[m_characterCount].xAdvance = m_xAdvance; @@ -3133,10 +3140,11 @@ protected override void GenerateTextMesh() if (m_textInfo.lineInfo[m_lineNumber].characterCount == 1) m_textInfo.lineInfo[m_lineNumber].alignment = m_lineJustification; + float maxAdvanceOffset = (boldSpacingAdjustment * currentElementScale + (m_currentFontAsset.normalSpacingOffset + characterSpacingAdjustment) * currentEmScale - m_cSpacing) * (1 - m_charWidthAdjDelta); if (m_textInfo.characterInfo[m_lastVisibleCharacterOfLine].isVisible) - m_textInfo.lineInfo[m_lineNumber].maxAdvance = m_textInfo.characterInfo[m_lastVisibleCharacterOfLine].xAdvance - (m_currentFontAsset.normalSpacingOffset + characterSpacingAdjustment) * currentEmScale - m_cSpacing; + m_textInfo.lineInfo[m_lineNumber].maxAdvance = m_textInfo.characterInfo[m_lastVisibleCharacterOfLine].xAdvance + (m_isRightToLeft ? maxAdvanceOffset : - maxAdvanceOffset); else - m_textInfo.lineInfo[m_lineNumber].maxAdvance = m_textInfo.characterInfo[m_lastCharacterOfLine].xAdvance - (m_currentFontAsset.normalSpacingOffset + characterSpacingAdjustment) * currentEmScale - m_cSpacing; + m_textInfo.lineInfo[m_lineNumber].maxAdvance = m_textInfo.characterInfo[m_lastCharacterOfLine].xAdvance + (m_isRightToLeft ? maxAdvanceOffset : - maxAdvanceOffset); m_textInfo.lineInfo[m_lineNumber].baseline = 0 - m_lineOffset; m_textInfo.lineInfo[m_lineNumber].ascender = lineAscender; diff --git a/Scripts/Runtime/TMPro_UGUI_Private.cs b/Scripts/Runtime/TMPro_UGUI_Private.cs index 532620c..e5adcb0 100644 --- a/Scripts/Runtime/TMPro_UGUI_Private.cs +++ b/Scripts/Runtime/TMPro_UGUI_Private.cs @@ -6,6 +6,7 @@ using System; using System.Collections.Generic; using UnityEngine.UI; +using Object = UnityEngine.Object; #pragma warning disable 0414 // Disabled a few warnings related to serialized variables not used in this script but used in the editor. #pragma warning disable 0618 // Disabled warning due to SetVertices being deprecated until new release with SetMesh() is available. @@ -418,9 +419,9 @@ void ON_MATERIAL_PROPERTY_CHANGED(bool isChanged, Material mat) // Event received when font asset properties are changed in Font Inspector - void ON_FONT_PROPERTY_CHANGED(bool isChanged, TMP_FontAsset font) + void ON_FONT_PROPERTY_CHANGED(bool isChanged, Object font) { - if (MaterialReference.Contains(m_materialReferences, font)) + if (MaterialReference.Contains(m_materialReferences, (TMP_FontAsset) font)) { //Debug.Log("ON_FONT_PROPERTY_CHANGED event received."); m_isInputParsingRequired = true; @@ -435,7 +436,7 @@ void ON_FONT_PROPERTY_CHANGED(bool isChanged, TMP_FontAsset font) // Event received when UNDO / REDO Event alters the properties of the object. - void ON_TEXTMESHPRO_UGUI_PROPERTY_CHANGED(bool isChanged, TextMeshProUGUI obj) + void ON_TEXTMESHPRO_UGUI_PROPERTY_CHANGED(bool isChanged, Object obj) { //Debug.Log("Event Received by " + obj); @@ -490,7 +491,7 @@ void ON_TEXT_STYLE_CHANGED(bool isChanged) /// Event received when a Color Gradient Preset is modified. /// /// - void ON_COLOR_GRADIENT_CHANGED(TMP_ColorGradient gradient) + void ON_COLOR_GRADIENT_CHANGED(Object gradient) { m_havePropertiesChanged = true; SetVerticesDirty(); @@ -2128,6 +2129,7 @@ protected override void GenerateTextMesh() #region Handle Kerning TMP_GlyphValueRecord glyphAdjustments = new TMP_GlyphValueRecord(); float characterSpacingAdjustment = m_characterSpacing; + m_GlyphHorizontalAdvanceAdjustment = 0; if (m_enableKerning) { #if TMP_PROFILE_ON @@ -2161,6 +2163,8 @@ protected override void GenerateTextMesh() } } + m_GlyphHorizontalAdvanceAdjustment = glyphAdjustments.xAdvance; + #if TMP_PROFILE_ON Profiler.EndSample(); #endif @@ -2172,7 +2176,7 @@ protected override void GenerateTextMesh() #region Handle Right-to-Left if (m_isRightToLeft) { - m_xAdvance -= ((currentGlyphMetrics.horizontalAdvance * currentElementScale) + (m_currentFontAsset.normalSpacingOffset + characterSpacingAdjustment + m_wordSpacing + boldSpacingAdjustment) * currentEmScale + m_cSpacing) * (1 - m_charWidthAdjDelta); + m_xAdvance -= currentGlyphMetrics.horizontalAdvance * (1 - m_charWidthAdjDelta) * currentElementScale; if (isWhiteSpace || charCode == 0x200B) m_xAdvance -= m_wordSpacing * currentEmScale; @@ -2778,7 +2782,7 @@ protected override void GenerateTextMesh() Profiler.BeginSample("TMP - InsertNewLine()"); #endif - InsertNewLine(i, baseScale, currentEmScale, characterSpacingAdjustment, widthOfTextArea, lineGap, ref isMaxVisibleDescenderSet, ref maxVisibleDescender); + InsertNewLine(i, baseScale, currentElementScale, currentEmScale, m_GlyphHorizontalAdvanceAdjustment, boldSpacingAdjustment, characterSpacingAdjustment, widthOfTextArea, lineGap, ref isMaxVisibleDescenderSet, ref maxVisibleDescender); isStartOfNewLine = true; isFirstWordOfLine = true; @@ -2843,7 +2847,7 @@ protected override void GenerateTextMesh() // Add new page m_isNewPage = true; - InsertNewLine(i, baseScale, currentEmScale, characterSpacingAdjustment, widthOfTextArea, lineGap, ref isMaxVisibleDescenderSet, ref maxVisibleDescender); + InsertNewLine(i, baseScale, currentElementScale, currentEmScale, m_GlyphHorizontalAdvanceAdjustment, boldSpacingAdjustment, characterSpacingAdjustment, widthOfTextArea, lineGap, ref isMaxVisibleDescenderSet, ref maxVisibleDescender); m_startOfLineAscender = 0; m_lineOffset = 0; @@ -2887,7 +2891,7 @@ protected override void GenerateTextMesh() Profiler.BeginSample("TMP - InsertNewLine()"); #endif // New line of text does not exceed vertical bounds of text container - InsertNewLine(i, baseScale, currentEmScale, characterSpacingAdjustment, widthOfTextArea, lineGap, ref isMaxVisibleDescenderSet, ref maxVisibleDescender); + InsertNewLine(i, baseScale, currentElementScale, currentEmScale, m_GlyphHorizontalAdvanceAdjustment, boldSpacingAdjustment, characterSpacingAdjustment, widthOfTextArea, lineGap, ref isMaxVisibleDescenderSet, ref maxVisibleDescender); isStartOfNewLine = true; isFirstWordOfLine = true; @@ -3150,20 +3154,23 @@ protected override void GenerateTextMesh() if (isWhiteSpace || charCode == 0x200B) m_xAdvance += m_wordSpacing * currentEmScale; } - else if (!m_isRightToLeft) + else if (m_isRightToLeft) + { + m_xAdvance -= (((glyphAdjustments.m_XAdvance + boldSpacingAdjustment) * currentElementScale + (m_currentFontAsset.normalSpacingOffset + characterSpacingAdjustment) * currentEmScale + m_cSpacing) * (1 - m_charWidthAdjDelta)); + + if (isWhiteSpace || charCode == 0x200B) + m_xAdvance -= m_wordSpacing * currentEmScale; + } + else { float scaleFXMultiplier = 1; if (m_isFXMatrixSet) scaleFXMultiplier = m_FXMatrix.lossyScale.x; - m_xAdvance += ((currentGlyphMetrics.horizontalAdvance * scaleFXMultiplier + glyphAdjustments.m_XAdvance) * currentElementScale + (m_currentFontAsset.normalSpacingOffset + characterSpacingAdjustment + boldSpacingAdjustment) * currentEmScale + m_cSpacing) * (1 - m_charWidthAdjDelta); + m_xAdvance += ((currentGlyphMetrics.horizontalAdvance * scaleFXMultiplier + glyphAdjustments.m_XAdvance + boldSpacingAdjustment) * currentElementScale + (m_currentFontAsset.normalSpacingOffset + characterSpacingAdjustment) * currentEmScale + m_cSpacing) * (1 - m_charWidthAdjDelta); if (isWhiteSpace || charCode == 0x200B) m_xAdvance += m_wordSpacing * currentEmScale; } - else - { - m_xAdvance -= glyphAdjustments.m_XAdvance * currentElementScale; - } // Store xAdvance information m_textInfo.characterInfo[m_characterCount].xAdvance = m_xAdvance; @@ -3246,10 +3253,11 @@ protected override void GenerateTextMesh() if (m_textInfo.lineInfo[m_lineNumber].characterCount == 1) m_textInfo.lineInfo[m_lineNumber].alignment = m_lineJustification; + float maxAdvanceOffset = ((m_currentFontAsset.normalSpacingOffset + characterSpacingAdjustment) * currentEmScale - m_cSpacing) * (1 - m_charWidthAdjDelta); if (m_textInfo.characterInfo[m_lastVisibleCharacterOfLine].isVisible) - m_textInfo.lineInfo[m_lineNumber].maxAdvance = m_textInfo.characterInfo[m_lastVisibleCharacterOfLine].xAdvance - (m_currentFontAsset.normalSpacingOffset + characterSpacingAdjustment) * currentEmScale - m_cSpacing; + m_textInfo.lineInfo[m_lineNumber].maxAdvance = m_textInfo.characterInfo[m_lastVisibleCharacterOfLine].xAdvance + (m_isRightToLeft ? maxAdvanceOffset : - maxAdvanceOffset); else - m_textInfo.lineInfo[m_lineNumber].maxAdvance = m_textInfo.characterInfo[m_lastCharacterOfLine].xAdvance - (m_currentFontAsset.normalSpacingOffset + characterSpacingAdjustment) * currentEmScale - m_cSpacing; + m_textInfo.lineInfo[m_lineNumber].maxAdvance = m_textInfo.characterInfo[m_lastCharacterOfLine].xAdvance + (m_isRightToLeft ? maxAdvanceOffset : - maxAdvanceOffset); m_textInfo.lineInfo[m_lineNumber].baseline = 0 - m_lineOffset; m_textInfo.lineInfo[m_lineNumber].ascender = lineAscender; @@ -4413,6 +4421,9 @@ protected override void GenerateTextMesh() // Make sure Cull Transparent Mesh of the sub objects matches the parent m_subTextObjects[i].canvasRenderer.cullTransparentMesh = isCullTransparentMeshEnabled; + + // Sync RaycastTarget property with parent text object + m_subTextObjects[i].raycastTarget = this.raycastTarget; } } diff --git a/Scripts/Runtime/TextMeshProUGUI.cs b/Scripts/Runtime/TextMeshProUGUI.cs index 3e354a2..263d4be 100644 --- a/Scripts/Runtime/TextMeshProUGUI.cs +++ b/Scripts/Runtime/TextMeshProUGUI.cs @@ -369,10 +369,16 @@ public override void RecalculateMasking() public override void Cull(Rect clipRect, bool validRect) { //Debug.Log("***** Cull (" + clipRect + ", " + validRect + ") Cull: " + m_canvasRenderer.cull + " *****"); + if (m_canvas == null) + return; // Get compound rect for the text object and sub text objects in local canvas space. Rect rect = GetCanvasSpaceClippingRect(); + // No point culling if geometry bounds have no width or height. + if (rect.width == 0 || rect.height == 0) + return; + var cull = !validRect || !clipRect.Overlaps(rect, true); if (m_canvasRenderer.cull != cull) { diff --git a/package.json b/package.json index abd2b2a..669ace2 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "com.unity.textmeshpro", "displayName": "TextMeshPro", - "version": "1.5.0-preview.11", + "version": "1.5.0-preview.12", "unity": "2018.3", "description": "TextMeshPro is the ultimate text solution for Unity. It's the perfect replacement for Unity's UI Text and the legacy Text Mesh.\n\nPowerful and easy to use, TextMeshPro (also known as TMP) uses Advanced Text Rendering techniques along with a set of custom shaders; delivering substantial visual quality improvements while giving users incredible flexibility when it comes to text styling and texturing.\n\nTextMeshPro provides Improved Control over text formatting and layout with features like character, word, line and paragraph spacing, kerning, justified text, Links, over 30 Rich Text Tags available, support for Multi Font & Sprites, Custom Styles and more.\n\nGreat performance. Since the geometry created by TextMeshPro uses two triangles per character just like Unity's text components, this improved visual quality and flexibility comes at no additional performance cost.", "keywords": [ @@ -16,9 +16,9 @@ "repository": { "type": "git", "url": "https://github.cds.internal.unity3d.com/unity/com.unity.textmeshpro.git", - "revision": "ee8ff60ea162f08134b77b00c077268396934db2" + "revision": "444244c864ff938304b3482bb64c3df3600770e4" }, "upmCi": { - "footprint": "f23115e24251a31330c02aee7a3d352cad80027e" + "footprint": "04a5529de6d5e282fa5137b3e48bc77fd9583f98" } }