Exemplo n.º 1
0
        public void SetExternalUnderlining(UnderlineInfo underlineInfo, bool setSelection)
        {
            ExternalUnderliningLoop.SendRewind( );

            lock (this)
            {
                LastExternalUnderlineInfo         = underlineInfo;
                LastExternalUnderlineSetSelection = setSelection;
            }

            ExternalUnderliningLoop.SendWaitAndExecute( );
        }
Exemplo n.º 2
0
    private Stack <UnderlineInfo> tagHeadStack = new Stack <UnderlineInfo>();               //存储标签头,因为嵌套

    private void DealUnderlineTag(string richText, IList <UIVertex> verts)
    {
        if (richText.Length * 4 > verts.Count)
        {
            return;                                    //在标签输入的过程中,会出现
        }
        tagHeadStack.Clear();
        Match match = regex.Match(richText);

        while (match.Success)
        {
            if (match.Value == endStr) //匹配到标签尾
            {
                if (tagHeadStack.Count == 0)
                {
                    match = match.NextMatch();
                    continue;
                }
                UnderlineInfo tagParser  = tagHeadStack.Pop();
                int           startIndex = tagParser.startIndex;
                int           endIndex   = match.Index;
                if (endIndex <= startIndex) //没有囊括内容
                {
                    match = match.NextMatch();
                    continue;
                }
                //标签类型
                Match headMatch = tagRegex.Match(tagParser.content);
                if (!headMatch.Success)
                {
                    match = match.NextMatch();
                    continue;
                }
                string tagName = headMatch.Groups[1].Value;
                if (tagName != "underline")
                {
                    match = match.NextMatch();
                    continue;
                }

                //解析标签参数
                Color  color              = Color.white; //颜色
                float  height             = 1f;          //线段高度
                int    controlID          = -99999;
                string parameter          = "";          //参数
                var    keyValueCollection = _PairRegex.Matches(headMatch.Groups[2].Value);
                for (int i = 0; i < keyValueCollection.Count; i++)
                {
                    string key   = keyValueCollection[i].Groups[1].Value;
                    string value = keyValueCollection[i].Groups[2].Value;
                    switch (key)
                    {
                    case "c":
                    {
                        ColorUtility.TryParseHtmlString(value, out color);
                        break;
                    }

                    case "h":
                    {
                        float.TryParse(value, out height);
                        break;
                    }

                    case "f":
                    {
                        int.TryParse(value, out controlID);
                        break;
                    }

                    case "p":
                    {
                        parameter = value;
                        break;
                    }

                    default:
                        break;
                    }
                }

                float unitsPerPixel = 1 / pixelsPerUnit;

                //0 1|4 5|8  9 |12 13
                //3 2|7 6|11 10|14 15
                //<material=underline c=#ffffff h=1 n=1 p=2>下划线</material>
                //以上面为例:
                //tag.start为42,对应“>” | start对应“下”的左上角顶点
                //tag.end为44,对应“划”  | end对应“线”下一个字符的左上角顶点
                int      start = startIndex * 4;
                int      end   = Mathf.Min(endIndex * 4, verts.Count);
                UIVertex vt1   = verts[start + 3];
                float    minY  = vt1.position.y;
                float    maxY  = verts[start].position.y;
                //换行处理,如需换行,则将一条下划线分割成几条
                //顶点取样分布,如上图的2,6,10,其中end - 2表示最后一个取样点,即10
                //对应例子中的下、划、线的右下角顶点
                for (int i = start + 2; i <= end - 2; i += 4)
                {
                    UIVertex vt2     = verts[i];
                    bool     newline = Mathf.Abs(vt2.position.y - vt1.position.y) > fontSize;
                    if (newline || i == end - 2)
                    {
                        ImageInfo imageInfo = new ImageInfo();

                        //计算宽高
                        int tailIndex = !newline && i == end - 2 ? i : i - 4;
                        vt2            = verts[tailIndex];
                        minY           = vt2.position.y;
                        imageInfo.size = new Vector2((vt2.position.x - vt1.position.x) * unitsPerPixel, height);

                        //计算位置
                        Vector2 vertex = new Vector2(vt1.position.x, minY);
                        vertex            *= unitsPerPixel;
                        vertex            += new Vector2(imageInfo.size.x * 0.5f, -height * 0.5f);
                        vertex            += new Vector2(rectTransform.rect.size.x * (rectTransform.pivot.x - 0.5f), rectTransform.rect.size.y * (rectTransform.pivot.y - 0.5f));
                        imageInfo.position = vertex;

                        imageInfo.color = color;
                        _imgInfoList.Add(imageInfo);

                        if (controlID != -99999)
                        {
                            EventInfo e = new EventInfo();
                            e.controlID = controlID;
                            e.parameter = parameter;
                            Vector2 pos = new Vector2(vt1.position.x, minY);
                            pos   *= unitsPerPixel;
                            pos   += new Vector2(rectTransform.rect.size.x * (rectTransform.pivot.x - 0.5f), rectTransform.rect.size.y * (rectTransform.pivot.y - 0.5f));
                            e.rect = new Rect(pos, new Vector2(imageInfo.size.x, (maxY - minY) * unitsPerPixel));
                            _eventList.Add(e);
                        }
                        maxY = minY;
                        vt1  = verts[i + 1];
                        minY = vt1.position.y;
                        if (newline && i == end - 2)
                        {
                            i -= 4;
                        }
                    }
                }
            }
            else //匹配到标签头
            {
                UnderlineInfo tagParser = new UnderlineInfo();
                tagParser.content    = match.Value;
                tagParser.startIndex = match.Index + match.Length; //匹配位置+标签内容到长度
                tagHeadStack.Push(tagParser);
            }
            match = match.NextMatch();
        }
    }
Exemplo n.º 3
0
        public void SetMatches(RegexMatches matches, bool showCaptures, string eol)
        {
            if (matches == null)
            {
                throw new ArgumentNullException(nameof(matches));
            }

            string       last_text;
            RegexMatches last_matches;
            bool         last_show_captures;
            string       last_eol;

            lock (this)
            {
                last_text          = LastText;
                last_matches       = LastMatches;
                last_show_captures = LastShowCaptures;
                last_eol           = LastEol;
            }

            string text = GetBaseTextData(eol).Text;

            if (last_matches != null)
            {
                var old_groups = last_matches.Matches.SelectMany(m => m.Groups).Select(g => (g.Index, g.Length, g.Value));
                var new_groups = matches.Matches.SelectMany(m => m.Groups).Select(g => (g.Index, g.Length, g.Value));

                if (string.Equals(text, last_text) &&
                    showCaptures == last_show_captures &&
                    eol == last_eol &&
                    new_groups.SequenceEqual(old_groups))
                {
                    lock (this)
                    {
                        LastMatches = matches;
                        LastExternalUnderlineInfo = null;
                    }

                    MatchesUpdatedEvent.Set( );

                    return;
                }
            }

            RecolouringLoop.SendRewind( );
            LocalUnderliningLoop.SendRewind( );
            ExternalUnderliningLoop.SendRewind( );

            lock (this)
            {
                LastText                  = text;
                LastMatches               = matches;
                LastShowCaptures          = showCaptures;
                LastEol                   = eol;
                LastExternalUnderlineInfo = null;
            }

            MatchesUpdatedEvent.Set( );

            RecolouringLoop.SendWaitAndExecute( );
            LocalUnderliningLoop.SendWaitAndExecute( );
            ExternalUnderliningLoop.SendWaitAndExecute( );
        }
Exemplo n.º 4
0
    void ParseText(string mText)
    {
        if (_emojiData == null || !Application.isPlaying)
        {
            _outputText = mText;
            return;
        }

        _builder.Length = 0;
        _emojis.Clear();
        _hrefs.Clear();
        _underlines.Clear();
        ClearImages();

        MatchCollection matches = Regex.Matches(mText, _regexTag);

        if (matches.Count > 0)
        {
            int textIndex = 0;
            int imgIdx    = 0;
            int rectIdx   = 0;
            for (int i = 0; i < matches.Count; i++)
            {
                var match = matches[i];
                _matchResult.Parse(match, fontSize);

                switch (_matchResult.type)
                {
                case MatchType.Emoji:
                {
                    SpriteInfo info;
                    if (_emojiData.TryGetValue(_matchResult.title, out info))
                    {
                        _builder.Append(mText.Substring(textIndex, match.Index - textIndex));
                        int temIndex = _builder.Length;

                        _builder.Append("<quad size=");
                        _builder.Append(_matchResult.height);
                        _builder.Append(" width=");
                        _builder.Append((_matchResult.width * 1.0f / _matchResult.height).ToString("f2"));
                        _builder.Append(" />");

                        _emojis.Add(temIndex, new EmojiInfo()
                            {
                                type   = MatchType.Emoji,
                                sprite = info,
                                width  = _matchResult.width,
                                height = _matchResult.height
                            });

                        if (_matchResult.hasUrl)
                        {
                            var hrefInfo = new HrefInfo()
                            {
                                show       = false,
                                startIndex = temIndex * 4,
                                endIndex   = temIndex * 4 + 3,
                                url        = _matchResult.url,
                                color      = _matchResult.GetColor(color)
                            };
                            _hrefs.Add(hrefInfo);
                        }

                        textIndex = match.Index + match.Length;
                    }
                    break;
                }

                case MatchType.HyperLink:
                {
                    _builder.Append(mText.Substring(textIndex, match.Index - textIndex));
                    _builder.Append("<color=");
                    _builder.Append(_matchResult.GetHexColor(color));
                    _builder.Append(">");

                    var href = new HrefInfo();
                    href.show       = true;
                    href.startIndex = _builder.Length * 4;
                    _builder.Append(_matchResult.link);
                    href.endIndex = _builder.Length * 4 - 1;
                    href.url      = _matchResult.url;
                    href.color    = _matchResult.GetColor(color);

                    _hrefs.Add(href);
                    _underlines.Add(href);
                    _builder.Append("</color>");

                    textIndex = match.Index + match.Length;
                    break;
                }

                case MatchType.CustomFill:
                case MatchType.Texture:
                {
                    _builder.Append(mText.Substring(textIndex, match.Index - textIndex));

                    int temIndex = _builder.Length;

                    _builder.Append("<quad size=");
                    _builder.Append(_matchResult.height);
                    _builder.Append(" width=");
                    _builder.Append((_matchResult.width * 1.0f / _matchResult.height).ToString("f2"));
                    _builder.Append(" />");

                    _emojis.Add(temIndex, new EmojiInfo()
                        {
                            type    = _matchResult.type,
                            width   = _matchResult.width,
                            height  = _matchResult.height,
                            texture = new TextureInfo()
                            {
                                link = _matchResult.link, index = _matchResult.type == MatchType.Texture? imgIdx++ : rectIdx++
                            }
                        });
                    if (_matchResult.hasUrl)
                    {
                        var hrefInfo = new HrefInfo()
                        {
                            show       = false,
                            startIndex = temIndex * 4,
                            endIndex   = temIndex * 4 + 3,
                            url        = _matchResult.url,
                            color      = _matchResult.GetColor(color)
                        };

                        _hrefs.Add(hrefInfo);
                        //_underlines.Add(hrefInfo);
                    }

                    textIndex = match.Index + match.Length;
                    break;
                }
                }
            }
            _builder.Append(mText.Substring(textIndex, mText.Length - textIndex));
            _outputText = _builder.ToString();
        }
        else
        {
            _outputText = mText;
        }

        matches = Regex.Matches(_outputText, _regexEffect);
        for (int i = 0; i < matches.Count; i++)
        {
            var match = matches[i];
            if (match.Success && match.Groups.Count == 4)
            {
                string v1 = match.Groups[1].Value;
                Color  lineColor;
                if (!string.IsNullOrEmpty(v1) && ColorUtility.TryParseHtmlString(v1, out lineColor))
                {
                }
                else
                {
                    lineColor = color;
                }

                var underline = new UnderlineInfo()
                {
                    show       = true,
                    startIndex = match.Groups[2].Index * 4,
                    endIndex   = match.Groups[2].Index * 4 + match.Groups[2].Length * 4 - 1,
                    color      = lineColor
                };
                _underlines.Add(underline);
            }
        }
    }