From 4a51ed64c51b2eeb67847db23162f4bfeb3d8339 Mon Sep 17 00:00:00 2001
From: hch <305670599@qq.com>
Date: 星期六, 07 二月 2026 16:54:17 +0800
Subject: [PATCH] 0312 优化richtext 可能闪退的情况

---
 Main/System/Message/RichText.cs |  126 ++++++++++++++++++++++++++++++++++++++---
 1 files changed, 115 insertions(+), 11 deletions(-)

diff --git a/Main/System/Message/RichText.cs b/Main/System/Message/RichText.cs
index 360a4da..26b20bd 100644
--- a/Main/System/Message/RichText.cs
+++ b/Main/System/Message/RichText.cs
@@ -504,8 +504,26 @@
             {
                 font = FontUtility.preferred;
             }
+
+            // 娣诲姞 null 妫�鏌�
+            if (font == null || rectTransform == null || cachedTextGeneratorForLayout == null || string.IsNullOrEmpty(m_OutputText))
+            {
+                return 0f;
+            }
+
             var settings = GetGenerationSettings(Vector2.zero);
-            return cachedTextGeneratorForLayout.GetPreferredWidth(m_OutputText, settings) / pixelsPerUnit;
+
+            float width = 0f;
+            try
+            {
+                width = cachedTextGeneratorForLayout.GetPreferredWidth(m_OutputText, settings) / pixelsPerUnit;
+            }
+            catch (Exception ex)
+            {
+                Debug.LogError($"GetPreferredWidth failed: {ex.Message}");
+                width = 0f;
+            }
+            return width;
         }
     }
 
@@ -517,9 +535,26 @@
             {
                 font = FontUtility.preferred;
             }
+
+            // 娣诲姞 null 妫�鏌�
+            if (font == null || rectTransform == null || cachedTextGeneratorForLayout == null || string.IsNullOrEmpty(m_OutputText))
+            {
+                return 0f;
+            }
+
             var settings = GetGenerationSettings(new Vector2(rectTransform.rect.size.x, 0.0f));
-            float _height = cachedTextGeneratorForLayout.GetPreferredHeight(m_OutputText, settings) / pixelsPerUnit;
-            return _height;
+
+            float height = 0f;
+            try
+            {
+                height = cachedTextGeneratorForLayout.GetPreferredHeight(m_OutputText, settings) / pixelsPerUnit;
+            }
+            catch (Exception ex)
+            {
+                Debug.LogError($"GetPreferredHeight failed: {ex.Message}");
+                height = 0f;
+            }
+            return height;
         }
     }
     #endregion
@@ -666,6 +701,9 @@
 
     private Dictionary<int, Match> matchDics = new Dictionary<int, Match>();
 
+    // 瀛楃瀹藉害缂撳瓨锛岄伩鍏嶉噸澶嶈绠楃浉鍚屽瓧绗�
+    private Dictionary<string, float> charWidthCache = new Dictionary<string, float>();
+
     private bool IsModifySize(int _index,out int _size)
     {
         _size = 0;
@@ -724,6 +762,14 @@
         {
             font = FontUtility.preferred;
         }
+
+        // 娣诲姞 null 妫�鏌�
+        if (font == null || rectTransform == null || cachedTextGeneratorForLayout == null)
+        {
+            Debug.LogWarning("SetFitterSize: font, rectTransform or cachedTextGeneratorForLayout is null");
+            return;
+        }
+
         var settings = GetGenerationSettings(Vector2.zero);
 
         float cache = 0;
@@ -732,6 +778,7 @@
         float ratio = GetResolutionRatio();
 
         matchDics.Clear();
+        charWidthCache.Clear();
 
         foreach (Match match in ImgAnalysis.Unity_Img_Regex.Matches(fitterText))
         {
@@ -802,7 +849,8 @@
                 }
                 else
                 {
-                    cache = cachedTextGeneratorForLayout.GetPreferredWidth(match.Value, settings) * ratio;
+                    cache = GetCharWidthCached(match.Value, settings, ratio);
+
                     if (width + cache > (rectTransform.rect.width - 5))
                     {
                         CacluHrefAndImgIndex(Mathf.Max(0, i - 1));
@@ -820,19 +868,16 @@
             else
             {
                 var _size = 0;
-                var _cacheFontSize = fontSize;
+                // 涓嶅啀淇敼 fontSize锛屼娇鐢ㄤ复鏃� TextGenerator 璁$畻涓嶅悓瀛楀彿鐨勫搴�
                 if (_modifySize && IsModifySize(i, out _size))
                 {
-                    fontSize = _size;
-                    settings = GetGenerationSettings(Vector2.zero);
-                    cache = cachedTextGeneratorForLayout.GetPreferredWidth(fitterText[i].ToString(), settings) * ratio;
-                    fontSize = _cacheFontSize;
-                    settings = GetGenerationSettings(Vector2.zero);
+                    cache = GetCharWidthWithCustomSize(fitterText[i], _size, ratio);
                 }
                 else
                 {
-                    cache = cachedTextGeneratorForLayout.GetPreferredWidth(fitterText[i].ToString(), settings) * ratio;
+                    cache = GetCharWidthCached(fitterText[i].ToString(), settings, ratio);
                 }
+
                 if (width + cache > (rectTransform.rect.width - 5))
                 {
                     CacluHrefAndImgIndex(Mathf.Max(0, i - 1));
@@ -850,6 +895,65 @@
         m_OutputText = textBuilder.ToString();
     }
 
+    /// <summary>
+    /// 鑾峰彇瀛楃瀹藉害锛堝甫缂撳瓨锛�
+    /// </summary>
+    private float GetCharWidthCached(string charStr, TextGenerationSettings settings, float ratio)
+    {
+        string cacheKey = $"{fontSize}_{charStr}";
+
+        if (charWidthCache.ContainsKey(cacheKey))
+        {
+            return charWidthCache[cacheKey];
+        }
+
+        float width = 0;
+        try
+        {
+            width = cachedTextGeneratorForLayout.GetPreferredWidth(charStr, settings) * ratio;
+        }
+        catch (Exception ex)
+        {
+            Debug.LogError($"GetPreferredWidth failed for '{charStr}': {ex.Message}");
+            width = 0;
+        }
+
+        charWidthCache[cacheKey] = width;
+        return width;
+    }
+
+    /// <summary>
+    /// 浣跨敤鑷畾涔夊瓧鍙疯绠楀瓧绗﹀搴︼紙涓嶄慨鏀瑰師濮� Text 缁勪欢鐨� fontSize锛�
+    /// </summary>
+    private float GetCharWidthWithCustomSize(char c, int customFontSize, float ratio)
+    {
+        string charStr = c.ToString();
+        string cacheKey = $"{customFontSize}_{charStr}";
+
+        if (charWidthCache.ContainsKey(cacheKey))
+        {
+            return charWidthCache[cacheKey];
+        }
+
+        float width = 0;
+        try
+        {
+            // 鍒涘缓涓存椂鐨� TextGenerationSettings锛屼娇鐢ㄨ嚜瀹氫箟瀛楀彿
+            TextGenerationSettings tempSettings = GetGenerationSettings(Vector2.zero);
+            tempSettings.fontSize = customFontSize;
+
+            width = cachedTextGeneratorForLayout.GetPreferredWidth(charStr, tempSettings) * ratio;
+        }
+        catch (Exception ex)
+        {
+            Debug.LogError($"GetPreferredWidth failed for '{charStr}' with fontSize {customFontSize}: {ex.Message}");
+            width = 0;
+        }
+
+        charWidthCache[cacheKey] = width;
+        return width;
+    }
+
     private void CacluHrefAndImgIndex(int index)
     {
         for (int i = 0; i < m_ImgList.Count; i++)

--
Gitblit v1.8.0