Example #1
0
    public void OnPointerClick(PointerEventData eventData)
    {
        Vector2 localPos;

        RectTransformUtility.ScreenPointToLocalPointInRectangle(rectTransform, eventData.position, eventData.pressEventCamera, out localPos);
        for (int i = eventList.Count - 1; i >= 0; i--)
        {
            RichTextEvent e = eventList[i];
            if (e.rect.Contains(localPos))
            {
                clickAction.Invoke(e.name, e.parameter);
                break;
            }
        }
    }
Example #2
0
    private void ApplyUnderlineEffect(RichTextUnderlineTag tag, IList <UIVertex> verts)
    {
        float fontSize2     = fontSize * 0.5f;
        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对应“线”下一个字符的左上角顶点
        //Debug.Log(tag.start);
        //Debug.Log(tag.end);
        int      start = tag.start * 4;
        int      end   = Mathf.Min(tag.end * 4 + 4, verts.Count);
        UIVertex vt1   = verts[start + 3];
        UIVertex vt2;
        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)
        {
            vt2 = verts[i];
            bool newline = Mathf.Abs(vt2.position.y - vt1.position.y) > fontSize2;
            if (newline || i == end - 2)
            {
                RichTextImageInfo imageInfo = new RichTextImageInfo();

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

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

                imageInfo.color = tag.color;
                imageInfoList.Add(imageInfo);

                if (!string.IsNullOrEmpty(tag.eventName))
                {
                    //下划线pos:
                    //x:vt1.x + 图片宽度的一半
                    //y:minY - tag.height * 0.5f
                    RichTextEvent e = new RichTextEvent();
                    e.name      = tag.eventName;
                    e.parameter = tag.eventParameter;
                    e.rect      = new Rect(
                        vt1.position.x * unitsPerPixel,
                        minY * unitsPerPixel,
                        imageInfo.size.x,
                        (maxY - minY) * unitsPerPixel
                        );
                    eventList.Add(e);
                }

                vt1  = verts[i + 1];
                minY = vt1.position.y;
                if (newline && i == end - 2)
                {
                    i -= 4;
                }
            }
            else
            {
                minY = Mathf.Min(minY, verts[i].position.y);
                maxY = Mathf.Max(maxY, verts[i - 1].position.y);
            }
        }
    }
Example #3
0
    protected string CalculateLayoutWithImage(string richText, out IList <UIVertex> verts)
    {
        Vector2 extents  = rectTransform.rect.size;
        var     settings = GetGenerationSettings(extents);

        float unitsPerPixel = 1 / pixelsPerUnit;

        float spaceWidth = cachedTextGenerator.GetPreferredWidth(replaceStr, settings) * unitsPerPixel;

        float fontSize2 = fontSize * 0.5f;

        //解析图片标签,并将标签替换为空格
        imageInfoList.Clear();
        Match         match   = null;
        StringBuilder builder = new StringBuilder();

        while ((match = imageTagRegex.Match(richText)).Success)
        {
            RichTextImageInfo imageInfo = new RichTextImageInfo();
            imageInfo.name = match.Groups[1].Value;
            string paras = match.Groups[2].Value;
            if (!string.IsNullOrEmpty(paras))
            {
                var keyValueCollection = imageParaRegex.Matches(paras);
                for (int i = 0; i < keyValueCollection.Count; i++)
                {
                    string key   = keyValueCollection[i].Groups[1].Value;
                    string value = keyValueCollection[i].Groups[2].Value;
                    imageInfo.SetValue(key, value);
                }
            }
            imageInfo.size        = new Vector2(fontSize2 * imageInfo.widthScale, fontSize2 * imageInfo.heightScale);
            imageInfo.startVertex = match.Index * 4;
            int num = Mathf.CeilToInt(imageInfo.size.x / spaceWidth);//占据几个空格
            imageInfo.vertexLength = num * 4;
            imageInfoList.Add(imageInfo);

            builder.Length = 0;
            builder.Append(richText, 0, match.Index);
            for (int i = 0; i < num; i++)
            {
                builder.Append(replaceStr);
            }
            builder.Append(richText, match.Index + match.Length, richText.Length - match.Index - match.Length);
            richText = builder.ToString();
        }

        // Populate charaters
        cachedTextGenerator.Populate(richText, settings);
        verts = cachedTextGenerator.verts;
        // Last 4 verts are always a new line...
        int vertCount = verts.Count - 4;

        //换行处理
        //0 1|4 5|8  9
        //3 2|7 6|11 10
        //例如前两个字为图片标签,第三字为普通文字;那么startVertex为0,vertexLength为8
        for (int i = 0; i < imageInfoList.Count; i++)
        {
            RichTextImageInfo imageInfo = imageInfoList[i];
            int startVertex             = imageInfo.startVertex;
            int vertexLength            = imageInfo.vertexLength;
            int maxVertex = Mathf.Min(startVertex + vertexLength, vertCount);
            //如果最边缘顶点超过了显示范围,则将图片移到下一行
            //之后的图片信息中的起始顶点都往后移
            if (verts[maxVertex - 2].position.x * unitsPerPixel > rectTransform.rect.xMax) //所有空格在同一行
            {
                richText = richText.Insert(startVertex / 4, "\r\n");
                for (int j = i; j < imageInfoList.Count; j++)
                {
                    imageInfoList[j].startVertex += 8;
                }
                cachedTextGenerator.Populate(richText, settings);
                verts     = cachedTextGenerator.verts;
                vertCount = verts.Count - 4;
            }
            else //空格不在同一行
            {
                float lastX = verts[startVertex].position.x;

                for (int j = startVertex + 4; j < startVertex + vertexLength; j += 4)
                {
                    if (verts[j].position.x < lastX)
                    {
                        richText = richText.Insert(startVertex / 4, "\r\n");
                        for (int k = i; k < imageInfoList.Count; k++)
                        {
                            imageInfoList[k].startVertex += 8;
                        }
                        cachedTextGenerator.Populate(richText, settings);
                        verts     = cachedTextGenerator.verts;
                        vertCount = verts.Count - 4;
                        break;
                    }
                    else
                    {
                        lastX = verts[j].position.x;
                    }
                }
            }
        }

        //计算位置
        for (int i = imageInfoList.Count - 1; i >= 0; i--)
        {
            RichTextImageInfo imageInfo = imageInfoList[i];
            int startVertex             = imageInfo.startVertex;
            if (startVertex < vertCount)
            {
                UIVertex uiVertex = verts[startVertex];
                Vector2  pos      = uiVertex.position;
                pos *= unitsPerPixel;
                pos += new Vector2(imageInfo.size.x * 0.5f, fontSize2 * 0.5f);
                pos += new Vector2(rectTransform.sizeDelta.x * (rectTransform.pivot.x - 0.5f), rectTransform.sizeDelta.y * (rectTransform.pivot.y - 0.5f));
                imageInfo.position = pos;
                imageInfo.color    = Color.white;

                if (!string.IsNullOrEmpty(imageInfo.eventName))
                {
                    //图片pos:
                    //x:起点x + 图片宽度的一半
                    //y:起点y + fontSize2 * 0.5f
                    RichTextEvent e = new RichTextEvent();
                    e.name      = imageInfo.eventName;
                    e.parameter = imageInfo.eventParameter;
                    e.rect      = new Rect(
                        verts[startVertex].position.x * unitsPerPixel,
                        verts[startVertex].position.y * unitsPerPixel + fontSize2 * 0.5f - imageInfo.size.y * 0.5f,
                        imageInfo.size.x,
                        imageInfo.size.y
                        );
                    eventList.Add(e);
                }
            }
            else
            {
                imageInfoList.RemoveAt(i);
            }
        }

        isImageDirty = true;

        return(richText);
    }