using System; using System.Collections; using System.Collections.Generic; using System.Text.RegularExpressions; using UnityEngine; public class ImgAnalysis : TRichAnalysis { public static Regex Img_Regex = new Regex(@"", RegexOptions.Singleline); public static Regex Unity_Img_Regex = new Regex(@"", 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; } //因为\标签对应的纹理还是会渲染的,并且仍然占4个顶点,而每个\会对应一张图片 //所以这里加回前面的图片数量,就是加回\对应的纹理占的顶点 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(""); } private void LoadSprite() { if (presentImgInfo.IsFace) return; if (IconConfig.inited) { 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("", 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(); } } }