public void CreateSubLink(ref Vector2 cursorPos, string content, float contentLength, float contentHeight)
    {
        GameObject go = new GameObject("line");

        go.transform.SetParent(transform);
        RectTransform rt = go.AddComponent <RectTransform>();

        rt.pivot = new Vector2(0, 1);
        rt.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, contentLength);
        rt.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, contentHeight);
        rt.localPosition = cursorPos;
        go.AddComponent <EventTriggerListener>();
        Text line = go.AddComponent <Text>();

        line.font               = mTextSetting.font;
        line.fontSize           = mTextSetting.fontSize;
        line.text               = content;
        line.color              = mTextSetting.hyperDefaultColor;
        line.horizontalOverflow = UnityEngine.HorizontalWrapMode.Overflow;
        line.verticalOverflow   = UnityEngine.VerticalWrapMode.Overflow;
        AssignPointerActions(line);
        textLinks.Add(line);


        GameObject goUnderline = new GameObject("underline");

        goUnderline.transform.SetParent(transform);
        RectTransform rtUnderline = goUnderline.AddComponent <RectTransform>();

        rtUnderline.pivot = new Vector2(0, 1);
        rtUnderline.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, contentLength);
        rtUnderline.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, contentHeight);
        rtUnderline.localPosition = cursorPos;
        Text Underline = goUnderline.AddComponent <Text>();

        Underline.raycastTarget = false;
        Underline.font          = mTextSetting.font;
        Underline.fontSize      = mTextSetting.fontSize;
        int fontSize = Underline.fontSize;
        int charWidth;

        MixedLabelUtil.GetCharacterSize('_', Underline.font, ref fontSize, out charWidth);
        Underline.text  = new string('_', (int)Mathf.Round(contentLength / charWidth));
        Underline.color = mTextSetting.hyperDefaultColor;
        Underline.horizontalOverflow = UnityEngine.HorizontalWrapMode.Overflow;
        Underline.verticalOverflow   = UnityEngine.VerticalWrapMode.Overflow;
        textLinks.Add(Underline);
    }
    /// <summary>
    /// Reset all parameter before reuse and initialization
    /// </summary>
    void Reset(TextSettings textSettings)
    {
        mEscapeBuilder = new StringBuilder();
        mStringBuilder = new StringBuilder();
        cursorPos      = Vector2.zero;
        font           = mText.font;
        lineSpace      = mText.lineSpacing;
        lineCount      = 1;
        GetLineHeight();
        MixedLabelUtil.GetCharacterSize(' ', font, ref fontSize, out spaceCharWidth);
        emojiSpaceCount = (int)Mathf.Round(MixedLabelUtil.s_emojiSize / spaceCharWidth);
        totalWidth      = 0;
        totalHeight     = 0;
        hyperCount      = 0;

        mText.color = textSettings.textColor;
        if (textSettings.font == null)
        {
            textSettings.font = mText.font;
        }
        font = textSettings.font;

        if (textSettings.fontSize == 0)
        {
            textSettings.fontSize = mText.fontSize;
        }
        fontSize = textSettings.fontSize;

        if (textSettings.fontStyle == 0)
        {
            textSettings.fontStyle = mText.fontStyle;
        }
        fontStyle = textSettings.fontStyle;


        //if (textSettings.hoverColor == null)
        //    textSettings.hoverColor = Color.red;
        //if (textSettings.defaultColor == null)
        //    mTextSettings.defaultColor = Color.blue;// *0.5f;
        //if (textSettings.pressColor == null)
        //    mTextSettings.pressColor = Color.green;// *1.3f;
        mEmojiCreateList = new List <EmojiInfo>();
    }
    /// <summary>
    /// init a mixed label;
    /// </summary>
    /// <param name="str">content should follow the rules : [e-xxx] represents emojis where xxx are the sprite name of the emoji;[h-xxx-11] represents a hyperlink where xxx are the content and 11 is reference number for callback</param>
    /// <param name="maxWidth">max width of the label, which is also the width of the label</param>
    /// <param name="hyperLinkActions">hyper link click callbacks, the number of params should be less or equal to the number of hyperlinks</param>
    public void Init(string str, int maxWidth, TextSettings _textSettings, params Action <int>[] hyperLinkActions)
    {
        mTextSettings = _textSettings;
        Reset(mTextSettings);
        int tmpCharWidth = 0;

        for (int i = 0; i < str.Length; i++)
        {
            if (str[i] == '[')
            {
                mEscapeBuilder = new StringBuilder();
                i++;
                while (i < str.Length)
                {
                    if (str[i] != ']')
                    {
                        mEscapeBuilder.Append(str[i]);
                    }
                    else
                    {
                        break;
                    }
                    i++;
                }

                string escapeWord = mEscapeBuilder.ToString();
                if (StringUtil.StartsWith(escapeWord, MixedLabelUtil.eChunk))
                {
                    if (cursorPos.x + emojiSpaceCount * spaceCharWidth > maxWidth)
                    {
                        ChangeLine(mStringBuilder, ref cursorPos);
                    }

                    mStringBuilder.Append(' ', emojiSpaceCount);
                    int emojiId = int.Parse(escapeWord.Substring(2, escapeWord.Length - 2));
                    CreateEmoji(ref emojiId, ref cursorPos);
                    cursorPos.x += emojiSpaceCount * spaceCharWidth;
                }
                else if (StringUtil.StartsWith(escapeWord, MixedLabelUtil.iChunk))
                {
                    //TO-DO
                }
                else if (StringUtil.StartsWith(escapeWord, MixedLabelUtil.hChunk))
                {
                    string linkText;
                    int    linkNumber;
                    MixedLabelUtil.GetHtmlInfo(escapeWord, out linkText, out linkNumber);
                    HyperLink hyperLink;
                    if (hyperLinkActions != null && hyperLinkActions.Length > hyperCount)
                    {
                        hyperLink = CreateLink(hyperLinkActions[hyperCount], mTextSettings, linkNumber);
                    }
                    else
                    {
                        hyperLink = CreateLink(null, mTextSettings, linkNumber);
                    }
                    hyperCount++;

                    float  linkTextWidth   = 0;
                    string currentLinkText = "";
                    for (int j = 0; j < linkText.Length; j++)
                    {
                        MixedLabelUtil.GetCharacterSize(linkText[j], mText.font, ref fontSize, out tmpCharWidth);

                        if (cursorPos.x + linkTextWidth + tmpCharWidth > maxWidth)
                        {
                            mStringBuilder.Append(' ', (int)Mathf.Round(linkTextWidth / spaceCharWidth));
                            hyperLink.CreateSubLink(ref cursorPos, currentLinkText, linkTextWidth, lineHeight * lineSpace);
                            ChangeLine(mStringBuilder, ref cursorPos);
                            currentLinkText = linkText[j].ToString();
                            linkTextWidth   = tmpCharWidth;
                        }
                        else
                        {
                            linkTextWidth   += tmpCharWidth;
                            currentLinkText += linkText[j];
                        }
                    }

                    mStringBuilder.Append(' ', (int)Mathf.Round(linkTextWidth / spaceCharWidth));
                    hyperLink.CreateSubLink(ref cursorPos, currentLinkText, linkTextWidth, lineHeight * lineSpace);
                    cursorPos.x += linkTextWidth;
                }
            }
            else
            {
                MixedLabelUtil.GetCharacterSize(str[i], font, ref fontSize, out tmpCharWidth);
                if (cursorPos.x + tmpCharWidth > maxWidth)
                {
                    ChangeLine(mStringBuilder, ref cursorPos);
                }
                cursorPos.x += tmpCharWidth;
                mStringBuilder.Append(str[i]);
            }
        }
        mText.text = mStringBuilder.ToString();
        if (lineCount > 1)
        {
            totalWidth = maxWidth;
        }
        else
        {
            totalWidth = (int)cursorPos.x;
        }
        totalHeight = (int)Math.Round(lineHeight + (lineCount - 1) * lineSpace * lineHeight);

        mRectTransform.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, totalWidth);
        mRectTransform.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, totalHeight);
        CreateAllEmoji();
    }