| using System; | 
| using System.Collections; | 
| using System.Collections.Generic; | 
| using System.Text.RegularExpressions; | 
|   | 
| using UnityEngine; | 
| public class ImgAnalysis : TRichAnalysis<ImgAnalysis> | 
| { | 
|     public static Regex Img_Regex = new Regex(@"<Img (.*?)/>", RegexOptions.Singleline); | 
|     public static Regex Unity_Img_Regex = new Regex(@"<color=#00000000><quad (.*?) index=([0-9]+)/>", RegexOptions.Singleline); | 
|     public static readonly Regex s_VertexFilter = new Regex(@"(<(.+?)>|[ \n\r\t]+)", RegexOptions.Singleline); | 
|   | 
|     private RichTextMgr.ImgInfo presentImgInfo = null; | 
|   | 
|     public override string Analysis(string val, bool IsRich) | 
|     { | 
|         if (!Img_Regex.IsMatch(val)) | 
|         { | 
|             return val; | 
|         } | 
|         m_StringBuilder.Length = 0; | 
|         int index = 0; | 
|         int imgCnt = 0; | 
|         foreach (Match match in Img_Regex.Matches(val)) | 
|         { | 
|             RichTextMgr.ImgInfo imgInfo = new RichTextMgr.ImgInfo(); | 
|             imgInfo.width = 30; | 
|             imgInfo.height = 30; | 
|             imgInfo.scale = 1; | 
|   | 
|             presentImgInfo = imgInfo; | 
|             m_StringBuilder.Append(val.Substring(index, match.Index - index)); | 
|             AnalysisSplitEvent(match.Groups[1].Value); | 
|   | 
|             if (IsRich) | 
|             { | 
|                 presentImgInfo.index = imgCnt; | 
|                 InverseToRichText(); | 
|                 if (RichTextMgr.Inst.GetImgList() != null) RichTextMgr.Inst.GetImgList().Add(presentImgInfo); | 
|                 else imgInfo = null; | 
|                 imgCnt++; | 
|             } | 
|   | 
|             index = match.Index + match.Length; | 
|         } | 
|         m_StringBuilder.Append(val.Substring(index, val.Length - index)); | 
|         presentImgInfo = null; | 
|         return m_StringBuilder.ToString(); | 
|     } | 
|   | 
|       | 
|     // 原逻辑为外部for图片传index,但是会造成函数内反复正则匹配,不使用index | 
|     public override string CalculateTextIndex(string val, int index) | 
|     { | 
|         if (!Unity_Img_Regex.IsMatch(val)) | 
|         { | 
|             return val; | 
|         } | 
|         MatchCollection matchArray = Unity_Img_Regex.Matches(val); | 
|         var filters = s_VertexFilter.Matches(val); | 
|         var imgCnt = RichTextMgr.Inst.GetImgList().Count; | 
|         for (int i = 0; i < imgCnt; i++) | 
|         { | 
|             if (i >= matchArray.Count) | 
|             { | 
|                 break; | 
|             } | 
|             Match match = matchArray[i]; | 
|             var picIndex = match.Index; | 
|   | 
|             //!!!unity 2019之后 建议使用TMP 参考 http://mot.ttthyy.com/374.html | 
|   | 
|             for (int idx = 0; idx < filters.Count; idx++) | 
|             { | 
|                 var filter = filters[idx]; | 
|                 if (filter.Index >= match.Index) | 
|                     break; | 
|                 picIndex -= filter.Length; | 
|             } | 
|             //因为\<quad>标签对应的纹理还是会渲染的,并且仍然占4个顶点,而每个\<quad>会对应一张图片 | 
|             //所以这里加回前面的图片数量,就是加回\<quad>对应的纹理占的顶点 | 
|             picIndex += i; | 
|             if (RichTextMgr.Inst.GetImgList() != null) | 
|             { | 
|                 RichTextMgr.ImgInfo imgInfo = RichTextMgr.Inst.GetImgList()[i]; | 
|                 imgInfo.end = picIndex * 4 + 3; | 
|             } | 
|              | 
|   | 
|         } | 
|          | 
|         return val; | 
|     } | 
|   | 
|     private void AnalysisSplitEvent(string val) | 
|     { | 
|         string[] array = GetSplitEvent(val); | 
|         if (array.Length > 0) | 
|         { | 
|             foreach (var split_event in array) | 
|             { | 
|                 AnalysisSplitData(split_event); | 
|             } | 
|         } | 
|         LoadSprite(); | 
|     } | 
|   | 
|     private void AnalysisSplitData(string val) | 
|     { | 
|         string[] array = GetSplitData(val); | 
|         if (array.Length > 0) | 
|         { | 
|             foreach (var split_data in array) | 
|             { | 
|                 AnalysisSplitValue(split_data); | 
|             } | 
|         } | 
|     } | 
|   | 
|     private void AnalysisSplitValue(string val) | 
|     { | 
|         string[] array = GetSplitValue(val); | 
|         if (array.Length == 2) | 
|         { | 
|             string split_value = array[0].ToLower(); | 
|             switch (split_value) | 
|             { | 
|                 case "img": | 
|                 case "chat": | 
|                     { | 
|                         presentImgInfo.spriteName = array[1]; | 
|                     } | 
|                     break; | 
|                 case "face": | 
|                     { | 
|                         presentImgInfo.spriteName = array[1]; | 
|                         presentImgInfo.IsFace = true; | 
|                         if (RichTextMgr.Inst.presentRichText != null) | 
|                         { | 
|                             int height = 0; | 
|                             if (RichTextMgr.Inst.presentRichText.FaceSize != 0) | 
|                             { | 
|                                 height = (int)RichTextMgr.Inst.presentRichText.FaceSize; | 
|                             } | 
|                             else | 
|                             {  | 
|                                 if (UIFrameMgr.Inst.ContainsDynamicImage(presentImgInfo.spriteName)) | 
|                                 { | 
|                                     var list = UIFrameMgr.Inst.GetDynamicImage(presentImgInfo.spriteName); | 
|                                     height = (int)list[0].rect.height; | 
|                                 } | 
|                                 else | 
|                                 { | 
|                                     height = 40; | 
|                                 } | 
|                             } | 
|                             presentImgInfo.height = height; | 
|                             presentImgInfo.width = presentImgInfo.height; | 
|                         } | 
|                     } | 
|                     break; | 
|                 case "size": | 
|                     { | 
|                         presentImgInfo.height = float.Parse(array[1]); | 
|                         presentImgInfo.width = float.Parse(array[1]); | 
|                     } | 
|                     break; | 
|                 case "scale": | 
|                     { | 
|                         presentImgInfo.scale = float.Parse(array[1]); | 
|                     } | 
|                     break; | 
|             } | 
|         } | 
|     } | 
|   | 
|     private void InverseToRichText() | 
|     { | 
|         m_StringBuilder.Append("<color=#00000000><quad "); | 
|         m_StringBuilder.Append(string.Format("size={0} ", presentImgInfo.height* presentImgInfo.scale)); | 
|         float ratio = (float)Math.Round((float)presentImgInfo.width / presentImgInfo.height * presentImgInfo.scale, 1); | 
|         m_StringBuilder.Append(string.Format("width={0} ", ratio)); | 
|         m_StringBuilder.Append(string.Format("index={0}", presentImgInfo.index)); | 
|         m_StringBuilder.Append("/></color>"); | 
|     } | 
|   | 
|     private void LoadSprite() | 
|     { | 
|         if (presentImgInfo.IsFace) return; | 
|         if (IconConfig.isInit) | 
|         { | 
|             presentImgInfo.sprite = UILoader.LoadSprite(presentImgInfo.spriteName); | 
|         } | 
|   | 
|         if (presentImgInfo.sprite != null) | 
|         { | 
|             RichText text = RichTextMgr.Inst.presentRichText; | 
|             if (text != null) | 
|             { | 
|                 if (text.LockImgSize) | 
|                 { | 
|                     presentImgInfo.width = presentImgInfo.height = text.fontSize; | 
|                     return; | 
|                 } | 
|                 else if (text.ModifyImgSiez) | 
|                 { | 
|                     presentImgInfo.width = text.ModifyImgWidth; | 
|                     presentImgInfo.height = text.ModifyImgHeight; | 
|                     return; | 
|                 } | 
|             } | 
|             presentImgInfo.width = presentImgInfo.sprite.rect.width * presentImgInfo.scale; | 
|             presentImgInfo.height = presentImgInfo.sprite.rect.height * presentImgInfo.scale; | 
|         } | 
|     } | 
|   | 
|     private const string FACE_REPLACE = @"#~([0-9a-zA-Z][0-9a-zA-Z][0-9a-zA-Z])"; | 
|     public static Regex FaceRegex = new Regex(FACE_REPLACE, RegexOptions.Singleline); | 
|     public static string ReplaceFace(string msg) | 
|     { | 
|         if (!FaceRegex.IsMatch(msg)) | 
|         { | 
|             return msg; | 
|         } | 
|         else | 
|         { | 
|             m_StringBuilder.Length = 0; | 
|             int index = 0; | 
|             foreach (Match match in FaceRegex.Matches(msg)) | 
|             { | 
|                 string result = match.Groups[1].Value.Replace("0", ""); | 
|                 m_StringBuilder.Append(msg.Substring(index, match.Index - index)); | 
|                 if (UIFrameMgr.Inst.ContainsDynamicImage(result)) | 
|                 { | 
|                     m_StringBuilder.Append(string.Format("<Img face={0}/>", result)); | 
|                 } | 
|                 else | 
|                 { | 
|                     m_StringBuilder.Append(match.Groups[0].Value); | 
|                 } | 
|                 index = match.Index + match.Length; | 
|             } | 
|             m_StringBuilder.Append(msg.Substring(index, msg.Length - index)); | 
|             return m_StringBuilder.ToString(); | 
|         } | 
|     } | 
|     public static string ReplaceFace(string msg, out int cnt) | 
|     { | 
|         cnt = 0; | 
|         if (!FaceRegex.IsMatch(msg)) | 
|         { | 
|             return msg; | 
|         } | 
|         else | 
|         { | 
|             m_StringBuilder.Length = 0; | 
|             int index = 0; | 
|             foreach (Match match in FaceRegex.Matches(msg)) | 
|             { | 
|                 cnt++; | 
|                 m_StringBuilder.Append(msg.Substring(index, match.Index - index)); | 
|                 index = match.Index + match.Length; | 
|             } | 
|             m_StringBuilder.Append(msg.Substring(index, msg.Length - index)); | 
|             return m_StringBuilder.ToString(); | 
|         } | 
|     } | 
| } |