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 "folder": 
 | 
                    {  
 | 
                        presentImgInfo.folderName = 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));  // 占位像素 
 | 
        float ratio = 1f; 
 | 
        m_StringBuilder.Append(string.Format("width={0} ", ratio)); //基础size的缩放比率 
 | 
        m_StringBuilder.Append(string.Format("index={0}", presentImgInfo.index)); 
 | 
        m_StringBuilder.Append("/></color>"); 
 | 
    } 
 | 
  
 | 
    private void LoadSprite() 
 | 
    { 
 | 
        if (presentImgInfo.IsFace) return; 
 | 
        if (IconConfig.isInit) 
 | 
        { 
 | 
            if (!string.IsNullOrEmpty(presentImgInfo.folderName)) 
 | 
            { 
 | 
                presentImgInfo.sprite = UILoader.LoadSprite(presentImgInfo.folderName, presentImgInfo.spriteName); 
 | 
            } 
 | 
            else 
 | 
            { 
 | 
                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(); 
 | 
        } 
 | 
    } 
 | 
} 
 |