Skip to content

Commit 49623db

Browse files
author
Unity Technologies
committed
com.unity.textmeshpro@3.2.0-pre.11
## [3.2.0-pre.11] - 2024-12-09 ### Changes - Fix TMP crash on Hyphen wrapping. - Fixed incorrect character caching when font styles and weights are used. UUM-87529 - Fixed the iOS crash when using fallback fonts created at runtime. - Fix exception thrown when pasting text into TMP inputfield with custom validator. - Avoid creating a new submesh if the previous one still has space. - Fixed the broken URL of the help button on the TextMesh Pro Settings page.
1 parent 053c344 commit 49623db

16 files changed

+376
-115
lines changed

CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,15 @@
11
# Changelog
22
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
33

4+
## [3.2.0-pre.11] - 2024-12-09
5+
### Changes
6+
- Fix TMP crash on Hyphen wrapping.
7+
- Fixed incorrect character caching when font styles and weights are used. UUM-87529
8+
- Fixed the iOS crash when using fallback fonts created at runtime.
9+
- Fix exception thrown when pasting text into TMP inputfield with custom validator.
10+
- Avoid creating a new submesh if the previous one still has space.
11+
- Fixed the broken URL of the help button on the TextMesh Pro Settings page.
12+
413
## [3.2.0-pre.10] - 2024-05-27
514
### Changes
615
- Ensure space and underline are always added to Static FontAsset. (UUM-45512)
Binary file not shown.

Scripts/Editor/TMP_BaseShaderGUI.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -438,7 +438,7 @@ protected void DoColor(string name, string label)
438438
{
439439
MaterialProperty property = BeginProperty(name);
440440
s_TempLabel.text = label;
441-
Color value = EditorGUI.ColorField(EditorGUILayout.GetControlRect(), s_TempLabel, property.colorValue, false, true, true);
441+
Color value = EditorGUI.ColorField(EditorGUILayout.GetControlRect(), s_TempLabel, property.colorValue, false, true, false);
442442
if (EndProperty())
443443
{
444444
property.colorValue = value;

Scripts/Editor/TMP_EditorResourceManager.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ internal static void InitializeFontAssetResourceChangeCallBacks()
3131
string fontAssetPath = AssetDatabase.GUIDToAssetPath(fontAssetGUIDs[i]);
3232
TMP_FontAsset fontAsset = AssetDatabase.LoadAssetAtPath<TMP_FontAsset>(fontAssetPath);
3333

34-
if (fontAsset != null && (fontAsset.atlasPopulationMode == AtlasPopulationMode.Dynamic || fontAsset.atlasPopulationMode == AtlasPopulationMode.DynamicOS) && fontAsset.clearDynamicDataOnBuild && fontAsset.atlasTexture.width != 0)
34+
if (fontAsset != null && (fontAsset.atlasPopulationMode == AtlasPopulationMode.Dynamic || fontAsset.atlasPopulationMode == AtlasPopulationMode.DynamicOS) && fontAsset.clearDynamicDataOnBuild && fontAsset.atlasTexture.width > 1)
3535
{
3636
Debug.Log("Clearing [" + fontAsset.name + "] dynamic font asset data.");
3737
fontAsset.ClearCharacterAndGlyphTablesInternal();

Scripts/Editor/TMP_SettingsEditor.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -457,7 +457,7 @@ public override void OnGUI(string searchContext)
457457
{
458458
// Lazy creation that supports domain reload
459459
if (m_ResourceImporter == null)
460-
m_ResourceImporter = new TMP_PackageResourceImporter();
460+
m_ResourceImporter = new TMP_PackageResourceImporter(logErrors: false);
461461

462462
m_ResourceImporter.OnGUI();
463463
}

Scripts/Editor/TMP_SpriteAssetEditor.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ public override void OnInspectorGUI()
122122
if (GUI.Button(rect, new GUIContent("Update Sprite Asset")))
123123
{
124124
TMP_SpriteAssetMenu.UpdateSpriteAsset(m_SpriteAsset);
125+
ResetSelectionNextFrame();
125126
}
126127
EditorGUI.indentLevel = 1;
127128

@@ -677,6 +678,19 @@ public override void OnInspectorGUI()
677678

678679
}
679680

681+
private void ResetSelectionNextFrame()
682+
{
683+
var activeObject = Selection.activeObject;
684+
EditorApplication.delayCall += () =>
685+
{
686+
Selection.activeObject = null;
687+
EditorApplication.delayCall += () =>
688+
{
689+
Selection.activeObject = activeObject;
690+
};
691+
};
692+
}
693+
680694

681695
/// <summary>
682696
///

Scripts/Editor/TMPro_FontAssetCreatorWindow.cs

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -206,8 +206,7 @@ public void OnEnable()
206206
}
207207

208208
// Get potential font face and styles for the current font.
209-
if (m_SourceFont != null)
210-
m_SourceFontFaces = GetFontFaces();
209+
m_SourceFontFaces = GetFontFaces();
211210

212211
ClearGeneratedData();
213212
}
@@ -438,8 +437,7 @@ void DrawControls()
438437
{
439438
m_SelectedFontAsset = null;
440439
m_IsFontAtlasInvalid = true;
441-
if (m_SourceFont != null)
442-
m_SourceFontFaces = GetFontFaces();
440+
m_SourceFontFaces = GetFontFaces();
443441
m_SourceFontFaceIndex = 0;
444442
}
445443

@@ -1220,7 +1218,8 @@ void ClearGeneratedData()
12201218
/// <returns></returns>
12211219
string[] GetFontFaces()
12221220
{
1223-
FontEngine.LoadFontFace(m_SourceFont, 0, 0);
1221+
if (FontEngine.LoadFontFace(m_SourceFont, 0, 0) != FontEngineError.Success)
1222+
return Array.Empty<string>();
12241223
return FontEngine.GetFontFaces();
12251224
}
12261225

@@ -1845,8 +1844,7 @@ void LoadFontCreationSettings(FontAssetCreationSettings settings)
18451844
{
18461845
m_SourceFont = AssetDatabase.LoadAssetAtPath<Font>(AssetDatabase.GUIDToAssetPath(settings.sourceFontFileGUID));
18471846
m_SourceFontFaceIndex = settings.faceIndex;
1848-
if (m_SourceFont != null)
1849-
m_SourceFontFaces = GetFontFaces();
1847+
m_SourceFontFaces = GetFontFaces();
18501848
m_PointSizeSamplingMode = settings.pointSizeSamplingMode;
18511849
m_PointSize = settings.pointSize;
18521850
m_Padding = settings.padding;

Scripts/Runtime/TMP_FontAsset.cs

Lines changed: 70 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -678,6 +678,36 @@ static TMP_FontAsset CreateFontAssetInstance(Font font, int atlasPadding, GlyphR
678678
internal static Func<Font, string> SetSourceFontGUID;
679679
#endif
680680

681+
/// <summary>
682+
/// Weak reference to all <see cref="TMP_FontAsset"/> instances.
683+
/// </summary>
684+
static readonly List<WeakReference<TMP_FontAsset>> s_CallbackInstances = new();
685+
686+
/// <summary>
687+
/// Register an instance for static lookup.
688+
/// </summary>
689+
/// <param name="instance">The instance to register.</param>
690+
void RegisterCallbackInstance(TMP_FontAsset instance)
691+
{
692+
// Verify that it is not already registered.
693+
for (var i = 0; i < s_CallbackInstances.Count; i++)
694+
{
695+
if (s_CallbackInstances[i].TryGetTarget(out TMP_FontAsset fa) && fa == instance)
696+
return;
697+
}
698+
699+
for (var i = 0; i < s_CallbackInstances.Count; i++)
700+
{
701+
if (!s_CallbackInstances[i].TryGetTarget(out _))
702+
{
703+
s_CallbackInstances[i] = new WeakReference<TMP_FontAsset>(instance);
704+
return;
705+
}
706+
}
707+
708+
s_CallbackInstances.Add(new WeakReference<TMP_FontAsset>(this));
709+
}
710+
681711
// Profiler Marker declarations
682712
private static ProfilerMarker k_ReadFontAssetDefinitionMarker = new ProfilerMarker("TMP.ReadFontAssetDefinition");
683713
private static ProfilerMarker k_AddSynthesizedCharactersMarker = new ProfilerMarker("TMP.AddSynthesizedCharacters");
@@ -794,6 +824,8 @@ public void ReadFontAssetDefinition()
794824

795825
IsFontAssetLookupTablesDirty = false;
796826

827+
RegisterCallbackInstance(this);
828+
797829
k_ReadFontAssetDefinitionMarker.End();
798830
}
799831

@@ -893,6 +925,28 @@ internal void InitializeCharacterLookupDictionary()
893925
m_MissingUnicodesFromFontFile.Clear();
894926
}
895927

928+
internal void ClearFallbackCharacterTable()
929+
{
930+
var keysToRemove = new List<uint>();
931+
932+
foreach (var characterLookup in m_CharacterLookupDictionary)
933+
{
934+
var character = characterLookup.Value;
935+
936+
// Collect the keys to remove
937+
if (character.textAsset != this)
938+
{
939+
keysToRemove.Add(characterLookup.Key);
940+
}
941+
}
942+
943+
// Now remove the collected keys
944+
foreach (var key in keysToRemove)
945+
{
946+
m_CharacterLookupDictionary.Remove(key);
947+
}
948+
}
949+
896950
internal void InitializeLigatureSubstitutionLookupDictionary()
897951
{
898952
if (m_FontFeatureTable.m_LigatureSubstitutionRecordLookup == null)
@@ -1091,12 +1145,15 @@ void AddSynthesizedCharacter(uint unicode, bool isFontFaceLoaded, bool addImmedi
10911145

10921146
//internal HashSet<int> FallbackSearchQueryLookup = new HashSet<int>();
10931147

1094-
internal void AddCharacterToLookupCache(uint unicode, TMP_Character character)
1148+
internal void AddCharacterToLookupCache(uint unicode, TMP_Character character, FontStyles fontStyle = FontStyles.Normal, FontWeight fontWeight = FontWeight.Regular, bool isAlternativeTypeface = false)
10951149
{
1096-
m_CharacterLookupDictionary.Add(unicode, character);
1150+
uint lookupKey = unicode;
1151+
1152+
// Compute composite lookup key if a font style or weight is used.
1153+
if (fontStyle != FontStyles.Normal || fontWeight != FontWeight.Regular)
1154+
lookupKey = (((isAlternativeTypeface ? 0x80u : 0u) | ((uint)fontStyle << 4) | ((uint)fontWeight / 100)) << 24) | unicode;
10971155

1098-
// Add font asset to fallback references.
1099-
//FallbackSearchQueryLookup.Add(character.textAsset.instanceID);
1156+
m_CharacterLookupDictionary.TryAdd(lookupKey, character);
11001157
}
11011158

11021159
/// <summary>
@@ -2381,7 +2438,7 @@ internal bool TryAddGlyphInternal(uint glyphIndex, out Glyph glyph)
23812438
}
23822439

23832440
// Add glyph which did not fit in current atlas texture to new atlas texture.
2384-
if (m_IsMultiAtlasTexturesEnabled)
2441+
if (m_IsMultiAtlasTexturesEnabled && m_UsedGlyphRects.Count > 0)
23852442
{
23862443
// Create new atlas texture
23872444
SetupNewAtlasTexture();
@@ -2588,7 +2645,7 @@ internal bool TryAddCharacterInternal(uint unicode, out TMP_Character character)
25882645
}
25892646

25902647
// Add glyph which did not fit in current atlas texture to new atlas texture.
2591-
if (m_IsMultiAtlasTexturesEnabled)
2648+
if (m_IsMultiAtlasTexturesEnabled && m_UsedGlyphRects.Count > 0)
25922649
{
25932650
// Create new atlas texture
25942651
SetupNewAtlasTexture();
@@ -3375,6 +3432,13 @@ public void ClearFontAssetData(bool setAtlasSizeToZero = false)
33753432

33763433
ReadFontAssetDefinition();
33773434

3435+
// Clear fallback character table for all other fontAssets, in case they were refereing this one.
3436+
for (var i = 0; i < s_CallbackInstances.Count; i++)
3437+
if (s_CallbackInstances[i].TryGetTarget(out var target) && target != this)
3438+
target.ClearFallbackCharacterTable();
3439+
3440+
TMPro_EventManager.ON_FONT_PROPERTY_CHANGED(true, this);
3441+
33783442
//TMP_ResourceManager.RebuildFontAssetCache();
33793443

33803444
#if UNITY_EDITOR

Scripts/Runtime/TMP_FontAssetUtilities.cs

Lines changed: 61 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -65,14 +65,39 @@ public static TMP_Character GetCharacterFromFontAsset(uint unicode, TMP_FontAsse
6565
private static TMP_Character GetCharacterFromFontAsset_Internal(uint unicode, TMP_FontAsset sourceFontAsset, bool includeFallbacks, FontStyles fontStyle, FontWeight fontWeight, out bool isAlternativeTypeface)
6666
{
6767
isAlternativeTypeface = false;
68-
TMP_Character character = null;
68+
TMP_Character character;
6969

7070
#region FONT WEIGHT AND FONT STYLE HANDLING
7171
// Determine if a font weight or style is used. If so check if an alternative typeface is assigned for the given weight and / or style.
7272
bool isItalic = (fontStyle & FontStyles.Italic) == FontStyles.Italic;
7373

7474
if (isItalic || fontWeight != FontWeight.Regular)
7575
{
76+
// Check if character is already cached using the composite unicode value the takes into consideration the font style and weight
77+
uint compositeUnicodeLookupKey = ((0x80u | ((uint)fontStyle << 4) | ((uint)fontWeight / 100)) << 24) | unicode;
78+
if (sourceFontAsset.characterLookupTable.TryGetValue(compositeUnicodeLookupKey, out character))
79+
{
80+
// Set isAlternativeTypeface
81+
isAlternativeTypeface = true;
82+
83+
if (character.textAsset is not null)
84+
return character;
85+
86+
// Remove character from lookup table
87+
sourceFontAsset.characterLookupTable.Remove(unicode);
88+
}
89+
else if (sourceFontAsset.characterLookupTable.TryGetValue(compositeUnicodeLookupKey & 0x7FFFFFFF, out character))
90+
{
91+
// Set isAlternativeTypeface
92+
isAlternativeTypeface = false;
93+
94+
if (character.textAsset is not null)
95+
return character;
96+
97+
// Remove character from lookup table
98+
sourceFontAsset.characterLookupTable.Remove(unicode);
99+
}
100+
76101
// Get reference to the font weight pairs of the given font asset.
77102
TMP_FontWeightPair[] fontWeights = sourceFontAsset.fontWeightTable;
78103

@@ -114,7 +139,7 @@ private static TMP_Character GetCharacterFromFontAsset_Internal(uint unicode, TM
114139
{
115140
if (temp.characterLookupTable.TryGetValue(unicode, out character))
116141
{
117-
if (character.textAsset != null)
142+
if (character.textAsset is not null)
118143
{
119144
isAlternativeTypeface = true;
120145
return character;
@@ -132,32 +157,21 @@ private static TMP_Character GetCharacterFromFontAsset_Internal(uint unicode, TM
132157

133158
return character;
134159
}
135-
136-
// Check if the source font file contains the requested character.
137-
//if (TryGetCharacterFromFontFile(unicode, fontAsset, out characterData))
138-
//{
139-
// isAlternativeTypeface = true;
140-
141-
// return characterData;
142-
//}
143-
144-
// If we find the requested character, we add it to the font asset character table
145-
// and return its character data.
146-
// We also add this character to the list of characters we will need to add to the font atlas.
147-
// We assume the font atlas has room otherwise this font asset should not be marked as dynamic.
148-
// Alternatively, we could also add multiple pages of font atlas textures (feature consideration).
149160
}
150-
151-
// At this point, we were not able to find the requested character in the alternative typeface
152-
// so we check the source font asset and its potential fallbacks.
153161
}
162+
163+
// Search potential fallbacks of the source font asset
164+
if (includeFallbacks && sourceFontAsset.fallbackFontAssetTable != null)
165+
return SearchFallbacksForCharacter(unicode, sourceFontAsset, fontStyle, fontWeight, out isAlternativeTypeface);
166+
167+
return null;
154168
}
155169
#endregion
156170

157-
// Search the source font asset for the requested character.
171+
// Search the source font asset for the requested character
158172
if (sourceFontAsset.characterLookupTable.TryGetValue(unicode, out character))
159173
{
160-
if (character.textAsset != null)
174+
if (character.textAsset is not null)
161175
return character;
162176

163177
// Remove character from lookup table
@@ -171,36 +185,40 @@ private static TMP_Character GetCharacterFromFontAsset_Internal(uint unicode, TM
171185
}
172186

173187
// Search fallback font assets if we still don't have a valid character and include fallback is set to true.
174-
if (character == null && includeFallbacks && sourceFontAsset.fallbackFontAssetTable != null)
175-
{
176-
// Get reference to the list of fallback font assets.
177-
List<TMP_FontAsset> fallbackFontAssets = sourceFontAsset.fallbackFontAssetTable;
178-
int fallbackCount = fallbackFontAssets.Count;
188+
if (includeFallbacks && sourceFontAsset.fallbackFontAssetTable != null)
189+
return SearchFallbacksForCharacter(unicode, sourceFontAsset, fontStyle, fontWeight, out isAlternativeTypeface);
190+
191+
return null;
192+
}
179193

180-
if (fallbackCount == 0)
181-
return null;
194+
private static TMP_Character SearchFallbacksForCharacter(uint unicode, TMP_FontAsset sourceFontAsset, FontStyles fontStyle, FontWeight fontWeight, out bool isAlternativeTypeface)
195+
{
196+
isAlternativeTypeface = false;
182197

183-
for (int i = 0; i < fallbackCount; i++)
184-
{
185-
TMP_FontAsset temp = fallbackFontAssets[i];
198+
// Get reference to the list of fallback font assets.
199+
List<TMP_FontAsset> fallbackFontAssets = sourceFontAsset.fallbackFontAssetTable;
200+
int fallbackCount = fallbackFontAssets.Count;
186201

187-
if (temp == null)
188-
continue;
202+
if (fallbackCount == 0)
203+
return null;
189204

190-
int id = temp.instanceID;
205+
for (int i = 0; i < fallbackCount; i++)
206+
{
207+
TMP_FontAsset temp = fallbackFontAssets[i];
191208

192-
// Try adding font asset to search list. If already present skip to the next one otherwise check if it contains the requested character.
193-
if (k_SearchedAssets.Add(id) == false)
194-
continue;
209+
if (temp == null)
210+
continue;
195211

196-
// Add reference to this search query
197-
//sourceFontAsset.FallbackSearchQueryLookup.Add(id);
212+
int id = temp.instanceID;
198213

199-
character = GetCharacterFromFontAsset_Internal(unicode, temp, true, fontStyle, fontWeight, out isAlternativeTypeface);
214+
// Try adding font asset to search list. If already present skip to the next one otherwise check if it contains the requested character.
215+
if (k_SearchedAssets.Add(id) == false)
216+
continue;
200217

201-
if (character != null)
202-
return character;
203-
}
218+
TMP_Character character = GetCharacterFromFontAsset_Internal(unicode, temp, true, fontStyle, fontWeight, out isAlternativeTypeface);
219+
220+
if (character != null)
221+
return character;
204222
}
205223

206224
return null;

0 commit comments

Comments
 (0)