Beispiel #1
0
        /// <summary>
        /// Function used to evaluate the length of a text string.
        /// </summary>
        /// <param name="text"></param>
        /// <returns></returns>
        public TextInfo GetTextInfo(string text)
        {
            TextInfo temp_textInfo = new TextInfo();           

            // Early exit if no font asset was assigned. This should not be needed since Arial SDF will be assigned by default.
            if (m_fontAsset.characterDictionary == null)
            {
                Debug.Log("Can't Generate Mesh! No Font Asset has been assigned to Object ID: " + this.GetInstanceID());
                return null;
            }

            // Early exit if string is empty.          
            if (text == null || text.Length == 0)
            {
                return null;
            }
                 
            // Convert String to Char[]
            StringToCharArray(text, ref m_text_buffer);

            int size = GetArraySizes(m_text_buffer);
            temp_textInfo.characterInfo = new TMPro_CharacterInfo[size];          

              
            m_fontIndex = 0;
            m_fontAssetArray[m_fontIndex] = m_fontAsset;
            // Scale the font to approximately match the point size           
            m_fontScale = (m_fontSize / m_fontAssetArray[m_fontIndex].fontInfo.PointSize * (m_isOrthographic ? 1 : 0.1f));
            float baseScale = m_fontScale; // BaseScale keeps the character aligned vertically since <size=+000> results in font of different scale.

            int charCode = 0; // Holds the character code of the currently being processed character.  
            int prev_charCode = 0;
            //bool isMissingCharacter; // Used to handle missing characters in the Font Atlas / Definition.

            m_style = FontStyles.Normal; // Set defaul style as normal.

            // GetPadding to adjust the size of the mesh due to border thickness, softness, glow, etc...
            if (checkPaddingRequired)
            {
                checkPaddingRequired = false;
                m_padding = ShaderUtilities.GetPadding(m_renderer.sharedMaterials, m_enableExtraPadding, m_isUsingBold);
                m_alignmentPadding = ShaderUtilities.GetFontExtent(m_sharedMaterial);
            }

            float style_padding = 0; // Extra padding required to accomodate Bold style.
            float xadvance_multiplier = 1; // Used to increase spacing between character when style is bold.

            m_baselineOffset = 0; // Used by subscript characters.
        
            float lineOffset = 0; // Amount of space between lines (font line spacing + m_linespacing).
            m_xAdvance = 0; // Used to track the position of each character.         

            int lineNumber = 0;
            int wordCount = 0;
            int character_Count = 0; // Total characters in the char[]
            int visibleCharacter_Count = 0; // # of visible characters.

            // Limit Line Length to whatever size fits all characters on a single line.
            m_lineLength = m_lineLength > max_LineWrapLength ? max_LineWrapLength : m_lineLength;

            // Initialize struct to track states of word wrapping
            m_SaveWordWrapState = new WordWrapState();
            int wrappingIndex = 0;


            if (temp_textInfo.lineInfo == null) temp_textInfo.lineInfo = new LineInfo[8];
            for (int i = 0; i < temp_textInfo.lineInfo.Length; i++)
            {              
                temp_textInfo.lineInfo[i] = new LineInfo();
                //m_textInfo.lineInfo[i].lineExtents = new Extents(k_InfinityVector, -k_InfinityVector);
            }

           
            // Tracking of the highest Ascender
            float maxAscender = 0;
            float maxDescender = 0;
           
            int lastLineNumber = 0;

            int endTagIndex = 0;
            // Parse through Character buffer to read html tags and begin creating mesh.
            for (int i = 0; m_text_buffer[i] != 0; i++)
            {
                m_tabSpacing = -999;
                m_spacing = -999;
                charCode = m_text_buffer[i];
            
                if (m_isRichText && charCode == 60)  // '<'
                {
                    // Check if Tag is valid. If valid, skip to the end of the validated tag.
                    if (ValidateHtmlTag(m_text_buffer, i + 1, out endTagIndex))
                    {
                        i = endTagIndex;
                        if (m_tabSpacing != -999)
                        {
                            // Move character to a fix position. Position expresses in characters (approximation).
                            m_xAdvance = m_tabSpacing * m_cached_Underline_GlyphInfo.width * m_fontScale;
                        }

                        if (m_spacing != -999)
                        {
                            m_xAdvance += m_spacing * m_fontScale * m_cached_Underline_GlyphInfo.width;
                        }

                        continue;
                    }
                }

                //isMissingCharacter = false;

                // Look up Character Data from Dictionary and cache it.
                m_fontAssetArray[m_fontIndex].characterDictionary.TryGetValue(charCode, out m_cached_GlyphInfo);
                if (m_cached_GlyphInfo == null)
                {
                    // Character wasn't found in the Dictionary.
                    m_fontAssetArray[m_fontIndex].characterDictionary.TryGetValue(88, out m_cached_GlyphInfo);
                    if (m_cached_GlyphInfo != null)
                    {
                        Debug.LogWarning("Character with ASCII value of " + charCode + " was not found in the Font Asset Glyph Table.");
                        // Replace the missing character by X (if it is found)
                        charCode = 88;
                        //isMissingCharacter = true;
                    }
                    else
                    {  // At this point the character isn't in the Dictionary, the replacement X isn't either so ... 
                        //continue;
                    }
                }


                // Store some of the text object's information
                temp_textInfo.characterInfo[character_Count].character = (char)charCode;
                //temp_textInfo.characterInfo[character_Count].color = m_htmlColor;
                //temp_textInfo.characterInfo[character_Count].style = m_style;
                temp_textInfo.characterInfo[character_Count].index = (short)i;


                // Handle Kerning if Enabled.                 
                if (m_enableKerning && character_Count >= 1)
                {
                    KerningPairKey keyValue = new KerningPairKey(prev_charCode, charCode);

                    KerningPair pair;

                    m_fontAsset.kerningDictionary.TryGetValue(keyValue.key, out pair);
                    if (pair != null)
                    {
                        m_xAdvance += pair.XadvanceOffset * m_fontScale;
                    }
                }



                // Set Padding based on selected font style
                if ((m_style & FontStyles.Bold) == FontStyles.Bold) // Checks for any combination of Bold Style.
                {
                    style_padding = m_fontAsset.BoldStyle * 2;
                    xadvance_multiplier = 1.07f; // Increase xAdvance for bold characters.         
                }
                else
                {
                    style_padding = m_fontAsset.NormalStyle * 2;
                    xadvance_multiplier = 1.0f;
                }


                // Setup Vertices for each character.
                Vector3 top_left = new Vector3(0 + m_xAdvance + ((m_cached_GlyphInfo.xOffset - m_padding - style_padding) * m_fontScale), (m_cached_GlyphInfo.yOffset + m_baselineOffset + m_padding) * m_fontScale - lineOffset * baseScale, 0);
                Vector3 bottom_left = new Vector3(top_left.x, top_left.y - ((m_cached_GlyphInfo.height + m_padding * 2) * m_fontScale), 0);
                Vector3 top_right = new Vector3(bottom_left.x + ((m_cached_GlyphInfo.width + m_padding * 2 + style_padding * 2) * m_fontScale), top_left.y, 0);
                Vector3 bottom_right = new Vector3(top_right.x, bottom_left.y, 0);


                // Check if we need to Shear the rectangles for Italic styles
                if ((m_style & FontStyles.Italic) == FontStyles.Italic)
                {
                    // Shift Top vertices forward by half (Shear Value * height of character) and Bottom vertices back by same amount. 
                    float shear_value = m_fontAsset.ItalicStyle * 0.01f;
                    Vector3 topShear = new Vector3(shear_value * ((m_cached_GlyphInfo.yOffset + m_padding + style_padding) * m_fontScale), 0, 0);
                    Vector3 bottomShear = new Vector3(shear_value * (((m_cached_GlyphInfo.yOffset - m_cached_GlyphInfo.height - m_padding - style_padding)) * m_fontScale), 0, 0);

                    top_left = top_left + topShear;
                    bottom_left = bottom_left + bottomShear;
                    top_right = top_right + topShear;
                    bottom_right = bottom_right + bottomShear;
                }


                // Track Word Count per line and for the object
                if (character_Count > 0 && (char.IsWhiteSpace((char)charCode) || char.IsPunctuation((char)charCode)))
                {
                    if (char.IsLetterOrDigit(temp_textInfo.characterInfo[character_Count - 1].character))
                    {
                        wordCount += 1;
                        temp_textInfo.lineInfo[lineNumber].wordCount += 1;
                    }
                }


                // Setup Mesh for visible characters. ie. not a SPACE / LINEFEED / CARRIAGE RETURN.
                if (charCode != 32 && charCode != 9 && charCode != 10 && charCode != 13)
                {
                    // Determine the bounds of the Mesh.             
                    //meshExtents.min = new Vector2(Mathf.Min(meshExtents.min.x, bottom_left.x), Mathf.Min(meshExtents.min.y, bottom_left.y));
                    //meshExtents.max = new Vector2(Mathf.Max(meshExtents.max.x, top_right.x), Mathf.Max(meshExtents.max.y, top_left.y));

                    // Determine the extend of each line
                    LineInfo lineInfo = temp_textInfo.lineInfo[lineNumber];
                    Extents lineExtents = lineInfo.lineExtents;
                    temp_textInfo.lineInfo[lineNumber].lineExtents.min = new Vector2(Mathf.Min(lineExtents.min.x, bottom_left.x), Mathf.Min(lineExtents.min.y, bottom_left.y));
                    temp_textInfo.lineInfo[lineNumber].lineExtents.max = new Vector2(Mathf.Max(lineExtents.max.x, top_right.x), Mathf.Max(lineExtents.max.y, top_left.y));


                    if (m_enableWordWrapping && top_right.x > m_lineLength)
                    {


                        // Check if further wrapping is possible or if we need to increase the line length
                        if (wrappingIndex == m_SaveWordWrapState.previous_WordBreak)
                        {
                            if (isAffectingWordWrapping)
                            {
                                m_lineLength = Mathf.Round(top_right.x * 100 + 0.5f) / 100f;//m_lineLength = top_right.x;
                                GenerateTextMesh();
                                isAffectingWordWrapping = false;
                            }

                            Debug.Log("Line " + lineNumber + " Cannot wrap lines anymore.");
                            return null;
                        }

                        // Restore to previously stored state
                        character_Count = m_SaveWordWrapState.total_CharacterCount + 1;
                        visibleCharacter_Count = m_SaveWordWrapState.visible_CharacterCount;
                        m_textInfo.lineInfo[lineNumber] = m_SaveWordWrapState.lineInfo;

                        m_htmlColor = m_SaveWordWrapState.vertexColor;
                        m_style = m_SaveWordWrapState.fontStyle;
                        m_baselineOffset = m_SaveWordWrapState.baselineOffset;
                        m_fontScale = m_SaveWordWrapState.fontScale;
                        i = m_SaveWordWrapState.previous_WordBreak;
                        wrappingIndex = i;  // Used to dectect when line length can no longer be reduced.

                        lineNumber += 1;
                        // Check to make sure Array is large enough to hold a new line.
                        if (lineNumber >= temp_textInfo.lineInfo.Length)
                            Array.Resize(ref temp_textInfo.lineInfo, Mathf.NextPowerOfTwo(lineNumber));


                        lineOffset += (m_fontAssetArray[m_fontIndex].fontInfo.LineHeight + m_lineSpacing);
                        m_xAdvance = 0;
                        continue;
                    }

                    //visibleCharacter_Count += 1;
                }
                else
                {   // This is a Space, Tab, LineFeed or Carriage Return              
                    
                    // Track # of spaces per line which is used for line justification.
                    if (charCode == 9 || charCode == 32)
                    {
                        //m_lineExtents[lineNumber].spaceCount += 1;
                        temp_textInfo.lineInfo[lineNumber].spaceCount += 1;
                        temp_textInfo.spaceCount += 1;
                    }

                    // We store the state of numerous variables for the most recent Space, LineFeed or Carriage Return to enable them to be restored 
                    // for Word Wrapping.
                    m_SaveWordWrapState.previous_WordBreak = i;
                    m_SaveWordWrapState.total_CharacterCount = character_Count;
                    m_SaveWordWrapState.visible_CharacterCount = visibleCharacter_Count;
                    m_SaveWordWrapState.maxLineLength = m_xAdvance;
                    m_SaveWordWrapState.fontScale = m_fontScale;
                    m_SaveWordWrapState.baselineOffset = m_baselineOffset;
                    m_SaveWordWrapState.fontStyle = m_style;
                    m_SaveWordWrapState.vertexColor = m_htmlColor;                                 
                    m_SaveWordWrapState.lineInfo = temp_textInfo.lineInfo[lineNumber];                    
                }


                // Store Rectangle positions for each Character.
                temp_textInfo.characterInfo[character_Count].bottomLeft = bottom_left;
                temp_textInfo.characterInfo[character_Count].topRight = top_right;
                temp_textInfo.characterInfo[character_Count].lineNumber = (short)lineNumber;

                //temp_textInfo.characterInfo[character_Count].baseLine = top_right.y - (m_cached_GlyphInfo.yOffset + m_padding) * m_fontScale;
                //temp_textInfo.characterInfo[character_Count].topLine = temp_textInfo.characterInfo[character_Count].baseLine + (m_fontAssetArray[m_fontIndex].fontInfo.Ascender + m_alignmentPadding.y) * m_fontScale; // Ascender              
                //temp_textInfo.characterInfo[character_Count].bottomLine = temp_textInfo.characterInfo[character_Count].baseLine + (m_fontAssetArray[m_fontIndex].fontInfo.Descender - m_alignmentPadding.w) * m_fontScale; // Descender          

                maxAscender = temp_textInfo.characterInfo[character_Count].topLine > maxAscender ? temp_textInfo.characterInfo[character_Count].topLine : maxAscender;
                maxDescender = temp_textInfo.characterInfo[character_Count].bottomLine < maxDescender ? temp_textInfo.characterInfo[character_Count].bottomLine : maxDescender;

                //temp_textInfo.characterInfo[character_Count].aspectRatio = m_cached_GlyphInfo.width / m_cached_GlyphInfo.height;
                //temp_textInfo.characterInfo[character_Count].scale = m_fontScale;
                temp_textInfo.lineInfo[lineNumber].characterCount += 1;

                //Debug.Log("Character #" + i + " is [" + (char)charCode + "] ASCII (" + charCode + ")");

                // Store LineInfo 
                if (lineNumber != lastLineNumber)
                {
                    temp_textInfo.lineInfo[lineNumber].firstCharacterIndex = character_Count;
                    temp_textInfo.lineInfo[lineNumber - 1].lastCharacterIndex = character_Count - 1;
                    temp_textInfo.lineInfo[lineNumber - 1].characterCount = temp_textInfo.lineInfo[lineNumber - 1].lastCharacterIndex - temp_textInfo.lineInfo[lineNumber - 1].firstCharacterIndex + 1;
                    temp_textInfo.lineInfo[lineNumber - 1].lineLength = temp_textInfo.characterInfo[character_Count - 1].topRight.x - m_padding * m_fontScale;
                }

              
                           
                lastLineNumber = lineNumber;

                // Handle Tabulation Stops. Tab stops at every 25% of Font Size.
                if (charCode == 9)
                {
                    m_xAdvance = (int)(m_xAdvance / (m_fontSize * 0.25f) + 1) * (m_fontSize * 0.25f);
                }
                else
                    m_xAdvance += (m_cached_GlyphInfo.xAdvance * xadvance_multiplier * m_fontScale) + m_characterSpacing;


                // Handle Line Feed as well as Word Wrapping
                if (charCode == 10 || charCode == 13)
                {
                    lineNumber += 1;

                    // Check to make sure Array is large enough to hold a new line.
                    if (lineNumber >= temp_textInfo.lineInfo.Length)                    
                        Array.Resize(ref temp_textInfo.lineInfo, Mathf.NextPowerOfTwo(lineNumber));                     
                    
                    
                    lineOffset += (m_fontAssetArray[m_fontIndex].fontInfo.LineHeight + m_lineSpacing);
                    m_xAdvance = 0;
                }

                character_Count += 1;
                prev_charCode = charCode;
            }


            temp_textInfo.lineInfo[lineNumber].lastCharacterIndex = character_Count - 1;
            temp_textInfo.lineInfo[lineNumber].characterCount = temp_textInfo.lineInfo[lineNumber].lastCharacterIndex - temp_textInfo.lineInfo[lineNumber].firstCharacterIndex + 1;
            temp_textInfo.lineInfo[lineNumber].lineLength = temp_textInfo.characterInfo[character_Count - 1].topRight.x - m_padding * m_fontScale;
     
            //m_textMetrics = new TMPro_TextMetrics();
            temp_textInfo.characterCount = character_Count;
            temp_textInfo.lineCount = lineNumber + 1;
            temp_textInfo.wordCount = wordCount;

            //for (int i = 0; i < lineNumber + 1; i++)
            //{
            //    Debug.Log("Line: " + (i + 1) + "  # Char: " + temp_textInfo.lineInfo[i].characterCount
            //                                 + "  Word Count: " + temp_textInfo.lineInfo[i].wordCount
            //                                 + "  Space: " + temp_textInfo.lineInfo[i].spaceCount
            //                                 + "  First:" + temp_textInfo.lineInfo[i].firstCharacterIndex + "  Last [" + temp_textInfo.characterInfo[temp_textInfo.lineInfo[i].lastCharacterIndex].character
            //                                 + "] at Index: " + temp_textInfo.lineInfo[i].lastCharacterIndex + "  Length: " + temp_textInfo.lineInfo[i].lineLength 
            //                                 + " Line Extents: " + temp_textInfo.lineInfo[i].lineExtents);

            //    //Debug.Log("line: " + (i + 1) + "  m_lineExtents Count: " + m_lineExtents[i].characterCount + "  lineInfo: " + m_textInfo.lineInfo[i].characterCount);
            //    //Debug.DrawLine(new Vector3(m_textInfo.lineInfo[i].lineLength, 2, 0), new Vector3(m_textInfo.lineInfo[i].lineLength, -2, 0), Color.red, 30f);
            //}

            return temp_textInfo;
        }
        // ** Still needs to be implemented **
        //private Camera managerCamera;
        //private TMPro_UpdateManager m_updateManager;
        //private bool isAlreadyScheduled;
        // DEBUG Variables
        //private System.Diagnostics.Stopwatch m_StopWatch;
        //private int frame = 0;
        //private int loopCountA = 0;
        //private int loopCountB = 0;
        //private int loopCountC = 0;
        //private int loopCountD = 0;
        //private int loopCountE = 0;
        protected override void Awake()
        {
            //base.Awake();
            //Debug.Log("***** Awake() *****"); // on Object ID:" + GetInstanceID());

            m_isAwake = true;
            // Cache Reference to the Canvas
            //m_canvas = GetComponentInParent<Canvas>();
            //if (m_canvas == null)
            //    m_canvas = gameObject.AddComponent<Canvas>();

            // Cache Reference to RectTransform.
            m_rectTransform = gameObject.GetComponent<RectTransform>();
            if (m_rectTransform == null)
                m_rectTransform = gameObject.AddComponent<RectTransform>();

            // Cache a reference to the UIRenderer.
            m_uiRenderer = GetComponent<CanvasRenderer>();
            if (m_uiRenderer == null)
                m_uiRenderer = gameObject.AddComponent<CanvasRenderer> ();

            m_uiRenderer.hideFlags = HideFlags.HideInInspector;

            // Determine if the RectTransform is Driven
            m_layoutController = GetComponent(typeof(ILayoutController)) as ILayoutController ?? (transform.parent != null ? transform.parent.GetComponent(typeof(ILayoutController)) as ILayoutController : null);
            if (m_layoutController != null) IsRectTransformDriven = true;

            // Cache reference to Mask Component if one is present
            m_mask = GetComponentInParent<Mask>();

            // Load the font asset and assign material to renderer.
            LoadFontAsset();

            // Allocate our initial buffers.
            m_char_buffer = new int[m_max_characters];
            m_cached_GlyphInfo = new GlyphInfo();
            m_uiVertices = new UIVertex[0]; //
            m_isFirstAllocation = true;

            m_textInfo = new TextInfo();
            m_textInfo.wordInfo = new List<WordInfo>();
            m_textInfo.lineInfo = new LineInfo[m_max_numberOfLines];
            m_textInfo.meshInfo = new TMPro_MeshInfo();

            m_fontAssetArray = new TextMeshProFont[16];

            // Check if we have a font asset assigned. Return if we don't because no one likes to see purple squares on screen.
            if (m_fontAsset == null)
            {
                Debug.LogWarning("Please assign a Font Asset to this " + transform.name + " gameobject.");
                return;
            }

            // Set Defaults for Font Auto-sizing
            if (m_fontSizeMin == 0) m_fontSizeMin = m_fontSize / 2;
            if (m_fontSizeMax == 0) m_fontSizeMax = m_fontSize * 2;

            //// Set flags to cause ensure our text is parsed and text redrawn.
            isInputParsingRequired = true;
            havePropertiesChanged = true;
            m_rectTransformDimensionsChanged = true;
            m_isCalculateSizeRequired = true;

            //m_isNewTextObject = true;
            //LayoutRebuilder.MarkLayoutForRebuild(m_rectTransform);
            ForceMeshUpdate(); // Added to force OnWillRenderObject() to be called in case object is not visible so we get initial bounds for the mesh.
            ///* ScheduleUpdate();
        }
        // Restore the State of various variables used in the mesh creation loop.
        int RestoreWordWrappingState(ref WordWrapState state)
        {
            m_textInfo.lineInfo[m_lineNumber] = state.lineInfo;
            m_textInfo = state.textInfo;
            m_currentFontSize = state.currentFontSize;
            m_fontScale = state.fontScale;
            m_baselineOffset = state.baselineOffset;
            m_style = state.fontStyle;
            m_htmlColor = state.vertexColor;

            m_characterCount = state.total_CharacterCount + 1;
            m_visibleCharacterCount = state.visible_CharacterCount;
            m_meshExtents = state.meshExtents;
            m_xAdvance = state.xAdvance;
            m_maxAscender = state.maxAscender;
            m_maxDescender = state.maxDescender;
            m_lineOffset = state.lineOffset;
            m_maxFontScale = state.maxFontScale;

            int index = state.previous_WordBreak;

            return index;
        }
Beispiel #4
0
        /// <summary>
        /// Function used to evaluate the length of a text string.
        /// </summary>
        /// <param name="text"></param>
        /// <returns></returns>
        public TextInfo GetTextInfo(string text)
        {
            TextInfo temp_textInfo = new TextInfo();

            // Early exit if no font asset was assigned. This should not be needed since Arial SDF will be assigned by default.
            if (m_fontAsset.characterDictionary == null)
            {
                Debug.Log("Can't Generate Mesh! No Font Asset has been assigned to Object ID: " + this.GetInstanceID());
                return(null);
            }

            // Early exit if string is empty.
            if (text == null || text.Length == 0)
            {
                return(null);
            }

            // Convert String to Char[]
            StringToCharArray(text, ref m_text_buffer);

            int size = GetArraySizes(m_text_buffer);

            temp_textInfo.characterInfo = new TMPro_CharacterInfo[size];


            m_fontIndex = 0;
            m_fontAssetArray[m_fontIndex] = m_fontAsset;
            // Scale the font to approximately match the point size
            m_fontScale = (m_fontSize / m_fontAssetArray[m_fontIndex].fontInfo.PointSize * (m_isOrthographic ? 1 : 0.1f));
            float baseScale = m_fontScale; // BaseScale keeps the character aligned vertically since <size=+000> results in font of different scale.

            int charCode      = 0;         // Holds the character code of the currently being processed character.
            int prev_charCode = 0;

            //bool isMissingCharacter; // Used to handle missing characters in the Font Atlas / Definition.

            m_style = FontStyles.Normal; // Set defaul style as normal.

            // GetPadding to adjust the size of the mesh due to border thickness, softness, glow, etc...
            if (checkPaddingRequired)
            {
                checkPaddingRequired = false;
                m_padding            = ShaderUtilities.GetPadding(m_renderer.sharedMaterials, m_enableExtraPadding, m_isUsingBold);
                m_alignmentPadding   = ShaderUtilities.GetFontExtent(m_sharedMaterial);
            }

            float style_padding       = 0; // Extra padding required to accomodate Bold style.
            float xadvance_multiplier = 1; // Used to increase spacing between character when style is bold.

            m_baselineOffset = 0;          // Used by subscript characters.

            float lineOffset = 0;          // Amount of space between lines (font line spacing + m_linespacing).

            m_xAdvance = 0;                // Used to track the position of each character.

            int lineNumber             = 0;
            int wordCount              = 0;
            int character_Count        = 0; // Total characters in the char[]
            int visibleCharacter_Count = 0; // # of visible characters.

            // Limit Line Length to whatever size fits all characters on a single line.
            m_lineLength = m_lineLength > max_LineWrapLength ? max_LineWrapLength : m_lineLength;

            // Initialize struct to track states of word wrapping
            m_SaveWordWrapState = new WordWrapState();
            int wrappingIndex = 0;


            if (temp_textInfo.lineInfo == null)
            {
                temp_textInfo.lineInfo = new LineInfo[8];
            }
            for (int i = 0; i < temp_textInfo.lineInfo.Length; i++)
            {
                temp_textInfo.lineInfo[i] = new LineInfo();
                //m_textInfo.lineInfo[i].lineExtents = new Extents(k_InfinityVector, -k_InfinityVector);
            }


            // Tracking of the highest Ascender
            float maxAscender  = 0;
            float maxDescender = 0;

            int lastLineNumber = 0;

            int endTagIndex = 0;

            // Parse through Character buffer to read html tags and begin creating mesh.
            for (int i = 0; m_text_buffer[i] != 0; i++)
            {
                m_tabSpacing = -999;
                m_spacing    = -999;
                charCode     = m_text_buffer[i];

                if (m_isRichText && charCode == 60)  // '<'
                {
                    // Check if Tag is valid. If valid, skip to the end of the validated tag.
                    if (ValidateHtmlTag(m_text_buffer, i + 1, out endTagIndex))
                    {
                        i = endTagIndex;
                        if (m_tabSpacing != -999)
                        {
                            // Move character to a fix position. Position expresses in characters (approximation).
                            m_xAdvance = m_tabSpacing * m_cached_Underline_GlyphInfo.width * m_fontScale;
                        }

                        if (m_spacing != -999)
                        {
                            m_xAdvance += m_spacing * m_fontScale * m_cached_Underline_GlyphInfo.width;
                        }

                        continue;
                    }
                }

                //isMissingCharacter = false;

                // Look up Character Data from Dictionary and cache it.
                m_fontAssetArray[m_fontIndex].characterDictionary.TryGetValue(charCode, out m_cached_GlyphInfo);
                if (m_cached_GlyphInfo == null)
                {
                    // Character wasn't found in the Dictionary.
                    m_fontAssetArray[m_fontIndex].characterDictionary.TryGetValue(88, out m_cached_GlyphInfo);
                    if (m_cached_GlyphInfo != null)
                    {
                        Debug.LogWarning("Character with ASCII value of " + charCode + " was not found in the Font Asset Glyph Table.");
                        // Replace the missing character by X (if it is found)
                        charCode = 88;
                        //isMissingCharacter = true;
                    }
                    else
                    {  // At this point the character isn't in the Dictionary, the replacement X isn't either so ...
                       //continue;
                    }
                }


                // Store some of the text object's information
                temp_textInfo.characterInfo[character_Count].character = (char)charCode;
                //temp_textInfo.characterInfo[character_Count].color = m_htmlColor;
                //temp_textInfo.characterInfo[character_Count].style = m_style;
                temp_textInfo.characterInfo[character_Count].index = (short)i;


                // Handle Kerning if Enabled.
                if (m_enableKerning && character_Count >= 1)
                {
                    KerningPairKey keyValue = new KerningPairKey(prev_charCode, charCode);

                    KerningPair pair;

                    m_fontAsset.kerningDictionary.TryGetValue(keyValue.key, out pair);
                    if (pair != null)
                    {
                        m_xAdvance += pair.XadvanceOffset * m_fontScale;
                    }
                }



                // Set Padding based on selected font style
                if ((m_style & FontStyles.Bold) == FontStyles.Bold) // Checks for any combination of Bold Style.
                {
                    style_padding       = m_fontAsset.BoldStyle * 2;
                    xadvance_multiplier = 1.07f; // Increase xAdvance for bold characters.
                }
                else
                {
                    style_padding       = m_fontAsset.NormalStyle * 2;
                    xadvance_multiplier = 1.0f;
                }


                // Setup Vertices for each character.
                Vector3 top_left     = new Vector3(0 + m_xAdvance + ((m_cached_GlyphInfo.xOffset - m_padding - style_padding) * m_fontScale), (m_cached_GlyphInfo.yOffset + m_baselineOffset + m_padding) * m_fontScale - lineOffset * baseScale, 0);
                Vector3 bottom_left  = new Vector3(top_left.x, top_left.y - ((m_cached_GlyphInfo.height + m_padding * 2) * m_fontScale), 0);
                Vector3 top_right    = new Vector3(bottom_left.x + ((m_cached_GlyphInfo.width + m_padding * 2 + style_padding * 2) * m_fontScale), top_left.y, 0);
                Vector3 bottom_right = new Vector3(top_right.x, bottom_left.y, 0);


                // Check if we need to Shear the rectangles for Italic styles
                if ((m_style & FontStyles.Italic) == FontStyles.Italic)
                {
                    // Shift Top vertices forward by half (Shear Value * height of character) and Bottom vertices back by same amount.
                    float   shear_value = m_fontAsset.ItalicStyle * 0.01f;
                    Vector3 topShear    = new Vector3(shear_value * ((m_cached_GlyphInfo.yOffset + m_padding + style_padding) * m_fontScale), 0, 0);
                    Vector3 bottomShear = new Vector3(shear_value * (((m_cached_GlyphInfo.yOffset - m_cached_GlyphInfo.height - m_padding - style_padding)) * m_fontScale), 0, 0);

                    top_left     = top_left + topShear;
                    bottom_left  = bottom_left + bottomShear;
                    top_right    = top_right + topShear;
                    bottom_right = bottom_right + bottomShear;
                }


                // Track Word Count per line and for the object
                if (character_Count > 0 && (char.IsWhiteSpace((char)charCode) || char.IsPunctuation((char)charCode)))
                {
                    if (char.IsLetterOrDigit(temp_textInfo.characterInfo[character_Count - 1].character))
                    {
                        wordCount += 1;
                        temp_textInfo.lineInfo[lineNumber].wordCount += 1;
                    }
                }


                // Setup Mesh for visible characters. ie. not a SPACE / LINEFEED / CARRIAGE RETURN.
                if (charCode != 32 && charCode != 9 && charCode != 10 && charCode != 13)
                {
                    // Determine the bounds of the Mesh.
                    //meshExtents.min = new Vector2(Mathf.Min(meshExtents.min.x, bottom_left.x), Mathf.Min(meshExtents.min.y, bottom_left.y));
                    //meshExtents.max = new Vector2(Mathf.Max(meshExtents.max.x, top_right.x), Mathf.Max(meshExtents.max.y, top_left.y));

                    // Determine the extend of each line
                    LineInfo lineInfo    = temp_textInfo.lineInfo[lineNumber];
                    Extents  lineExtents = lineInfo.lineExtents;
                    temp_textInfo.lineInfo[lineNumber].lineExtents.min = new Vector2(Mathf.Min(lineExtents.min.x, bottom_left.x), Mathf.Min(lineExtents.min.y, bottom_left.y));
                    temp_textInfo.lineInfo[lineNumber].lineExtents.max = new Vector2(Mathf.Max(lineExtents.max.x, top_right.x), Mathf.Max(lineExtents.max.y, top_left.y));


                    if (m_enableWordWrapping && top_right.x > m_lineLength)
                    {
                        // Check if further wrapping is possible or if we need to increase the line length
                        if (wrappingIndex == m_SaveWordWrapState.previous_WordBreak)
                        {
                            if (isAffectingWordWrapping)
                            {
                                m_lineLength = Mathf.Round(top_right.x * 100 + 0.5f) / 100f;//m_lineLength = top_right.x;
                                GenerateTextMesh();
                                isAffectingWordWrapping = false;
                            }

                            Debug.Log("Line " + lineNumber + " Cannot wrap lines anymore.");
                            return(null);
                        }

                        // Restore to previously stored state
                        character_Count                 = m_SaveWordWrapState.total_CharacterCount + 1;
                        visibleCharacter_Count          = m_SaveWordWrapState.visible_CharacterCount;
                        m_textInfo.lineInfo[lineNumber] = m_SaveWordWrapState.lineInfo;

                        m_htmlColor      = m_SaveWordWrapState.vertexColor;
                        m_style          = m_SaveWordWrapState.fontStyle;
                        m_baselineOffset = m_SaveWordWrapState.baselineOffset;
                        m_fontScale      = m_SaveWordWrapState.fontScale;
                        i             = m_SaveWordWrapState.previous_WordBreak;
                        wrappingIndex = i;  // Used to dectect when line length can no longer be reduced.

                        lineNumber += 1;
                        // Check to make sure Array is large enough to hold a new line.
                        if (lineNumber >= temp_textInfo.lineInfo.Length)
                        {
                            Array.Resize(ref temp_textInfo.lineInfo, Mathf.NextPowerOfTwo(lineNumber));
                        }


                        lineOffset += (m_fontAssetArray[m_fontIndex].fontInfo.LineHeight + m_lineSpacing);
                        m_xAdvance  = 0;
                        continue;
                    }

                    //visibleCharacter_Count += 1;
                }
                else
                {   // This is a Space, Tab, LineFeed or Carriage Return
                    // Track # of spaces per line which is used for line justification.
                    if (charCode == 9 || charCode == 32)
                    {
                        //m_lineExtents[lineNumber].spaceCount += 1;
                        temp_textInfo.lineInfo[lineNumber].spaceCount += 1;
                        temp_textInfo.spaceCount += 1;
                    }

                    // We store the state of numerous variables for the most recent Space, LineFeed or Carriage Return to enable them to be restored
                    // for Word Wrapping.
                    m_SaveWordWrapState.previous_WordBreak     = i;
                    m_SaveWordWrapState.total_CharacterCount   = character_Count;
                    m_SaveWordWrapState.visible_CharacterCount = visibleCharacter_Count;
                    m_SaveWordWrapState.maxLineLength          = m_xAdvance;
                    m_SaveWordWrapState.fontScale      = m_fontScale;
                    m_SaveWordWrapState.baselineOffset = m_baselineOffset;
                    m_SaveWordWrapState.fontStyle      = m_style;
                    m_SaveWordWrapState.vertexColor    = m_htmlColor;
                    m_SaveWordWrapState.lineInfo       = temp_textInfo.lineInfo[lineNumber];
                }


                // Store Rectangle positions for each Character.
                temp_textInfo.characterInfo[character_Count].bottomLeft = bottom_left;
                temp_textInfo.characterInfo[character_Count].topRight   = top_right;
                temp_textInfo.characterInfo[character_Count].lineNumber = (short)lineNumber;

                //temp_textInfo.characterInfo[character_Count].baseLine = top_right.y - (m_cached_GlyphInfo.yOffset + m_padding) * m_fontScale;
                //temp_textInfo.characterInfo[character_Count].topLine = temp_textInfo.characterInfo[character_Count].baseLine + (m_fontAssetArray[m_fontIndex].fontInfo.Ascender + m_alignmentPadding.y) * m_fontScale; // Ascender
                //temp_textInfo.characterInfo[character_Count].bottomLine = temp_textInfo.characterInfo[character_Count].baseLine + (m_fontAssetArray[m_fontIndex].fontInfo.Descender - m_alignmentPadding.w) * m_fontScale; // Descender

                maxAscender  = temp_textInfo.characterInfo[character_Count].topLine > maxAscender ? temp_textInfo.characterInfo[character_Count].topLine : maxAscender;
                maxDescender = temp_textInfo.characterInfo[character_Count].bottomLine < maxDescender ? temp_textInfo.characterInfo[character_Count].bottomLine : maxDescender;

                //temp_textInfo.characterInfo[character_Count].aspectRatio = m_cached_GlyphInfo.width / m_cached_GlyphInfo.height;
                //temp_textInfo.characterInfo[character_Count].scale = m_fontScale;
                temp_textInfo.lineInfo[lineNumber].characterCount += 1;

                //Debug.Log("Character #" + i + " is [" + (char)charCode + "] ASCII (" + charCode + ")");

                // Store LineInfo
                if (lineNumber != lastLineNumber)
                {
                    temp_textInfo.lineInfo[lineNumber].firstCharacterIndex    = character_Count;
                    temp_textInfo.lineInfo[lineNumber - 1].lastCharacterIndex = character_Count - 1;
                    temp_textInfo.lineInfo[lineNumber - 1].characterCount     = temp_textInfo.lineInfo[lineNumber - 1].lastCharacterIndex - temp_textInfo.lineInfo[lineNumber - 1].firstCharacterIndex + 1;
                    temp_textInfo.lineInfo[lineNumber - 1].lineLength         = temp_textInfo.characterInfo[character_Count - 1].topRight.x - m_padding * m_fontScale;
                }



                lastLineNumber = lineNumber;

                // Handle Tabulation Stops. Tab stops at every 25% of Font Size.
                if (charCode == 9)
                {
                    m_xAdvance = (int)(m_xAdvance / (m_fontSize * 0.25f) + 1) * (m_fontSize * 0.25f);
                }
                else
                {
                    m_xAdvance += (m_cached_GlyphInfo.xAdvance * xadvance_multiplier * m_fontScale) + m_characterSpacing;
                }


                // Handle Line Feed as well as Word Wrapping
                if (charCode == 10 || charCode == 13)
                {
                    lineNumber += 1;

                    // Check to make sure Array is large enough to hold a new line.
                    if (lineNumber >= temp_textInfo.lineInfo.Length)
                    {
                        Array.Resize(ref temp_textInfo.lineInfo, Mathf.NextPowerOfTwo(lineNumber));
                    }


                    lineOffset += (m_fontAssetArray[m_fontIndex].fontInfo.LineHeight + m_lineSpacing);
                    m_xAdvance  = 0;
                }

                character_Count += 1;
                prev_charCode    = charCode;
            }


            temp_textInfo.lineInfo[lineNumber].lastCharacterIndex = character_Count - 1;
            temp_textInfo.lineInfo[lineNumber].characterCount     = temp_textInfo.lineInfo[lineNumber].lastCharacterIndex - temp_textInfo.lineInfo[lineNumber].firstCharacterIndex + 1;
            temp_textInfo.lineInfo[lineNumber].lineLength         = temp_textInfo.characterInfo[character_Count - 1].topRight.x - m_padding * m_fontScale;

            //m_textMetrics = new TMPro_TextMetrics();
            temp_textInfo.characterCount = character_Count;
            temp_textInfo.lineCount      = lineNumber + 1;
            temp_textInfo.wordCount      = wordCount;

            //for (int i = 0; i < lineNumber + 1; i++)
            //{
            //    Debug.Log("Line: " + (i + 1) + "  # Char: " + temp_textInfo.lineInfo[i].characterCount
            //                                 + "  Word Count: " + temp_textInfo.lineInfo[i].wordCount
            //                                 + "  Space: " + temp_textInfo.lineInfo[i].spaceCount
            //                                 + "  First:" + temp_textInfo.lineInfo[i].firstCharacterIndex + "  Last [" + temp_textInfo.characterInfo[temp_textInfo.lineInfo[i].lastCharacterIndex].character
            //                                 + "] at Index: " + temp_textInfo.lineInfo[i].lastCharacterIndex + "  Length: " + temp_textInfo.lineInfo[i].lineLength
            //                                 + " Line Extents: " + temp_textInfo.lineInfo[i].lineExtents);

            //    //Debug.Log("line: " + (i + 1) + "  m_lineExtents Count: " + m_lineExtents[i].characterCount + "  lineInfo: " + m_textInfo.lineInfo[i].characterCount);
            //    //Debug.DrawLine(new Vector3(m_textInfo.lineInfo[i].lineLength, 2, 0), new Vector3(m_textInfo.lineInfo[i].lineLength, -2, 0), Color.red, 30f);
            //}

            return(temp_textInfo);
        }
        //public void RedrawMesh()
        //{
        //    isRedrawRequired = true;
        //}


        public void DrawMesh()
        {
            Matrix4x4 matrix;


            TMPro_MeshInfo meshInfos = m_textMeshProComponent.meshInfo;
            TextInfo       textInfos = m_textMeshProComponent.textInfo;

            TMPro_CharacterInfo[] characters_Info = textInfos.characterInfo;
            int characterCount = textInfos.characterCount;

            Vector3[] vertices     = meshInfos.vertices;
            Vector2[] uv0s         = meshInfos.uv0s;
            Vector2[] uv2s         = meshInfos.uv2s;
            Color32[] vertexColors = meshInfos.vertexColors;
            Vector3[] normals      = meshInfos.normals;
            Vector4[] tangents     = meshInfos.tangents;

            float     curveScale = 1;
            char      charCode;
            float     xScale   = 0;
            float     xAdvance = 0;
            GlyphInfo glyph;

            // Draw Scale Changes First
            for (int i = 0; i < characterCount; i++)
            {
                charCode = characters_Info[i].character;
                glyph    = m_textMeshProComponent.font.characterDictionary[charCode];

                int vertIndex = characters_Info[i].vertexIndex;
                if (characters_Info[i].isVisible)
                {
                    float charMidLine = (characters_Info[i].bottomLeft.x + characters_Info[i].topRight.x) / 2; // Middle X-Axis of character.

                    // Need to translate all 4 vertices of each quad to aligned with middle of character / baseline.
                    Vector3 offset = new Vector3(charMidLine, 0, 0);
                    vertices[vertIndex + 0] += -offset;
                    vertices[vertIndex + 1] += -offset;
                    vertices[vertIndex + 2] += -offset;
                    vertices[vertIndex + 3] += -offset;

                    // Apply Scale Matrix first
                    float x = characterCount > 1 ? (float)i / (characterCount - 1) : 0;
                    xScale = ScaleCurve.Evaluate(x);

                    matrix = Matrix4x4.TRS(new Vector3(0, 0, 0), Quaternion.Euler(0, 0, 0), new Vector3(xScale, xScale, 1));

                    vertices[vertIndex + 0] = matrix.MultiplyPoint3x4(vertices[vertIndex + 0]);
                    vertices[vertIndex + 1] = matrix.MultiplyPoint3x4(vertices[vertIndex + 1]);
                    vertices[vertIndex + 2] = matrix.MultiplyPoint3x4(vertices[vertIndex + 2]);
                    vertices[vertIndex + 3] = matrix.MultiplyPoint3x4(vertices[vertIndex + 3]);

                    // Redo the spacing for each character.
                    float adjusted_pos = glyph.xOffset * characters_Info[i].scale * xScale + (characters_Info[i].topRight.x - characters_Info[i].bottomLeft.x) / 2 * xScale;

                    offset = new Vector3(adjusted_pos + xAdvance, 0, 0);
                    vertices[vertIndex + 0] += offset;
                    vertices[vertIndex + 1] += offset;
                    vertices[vertIndex + 2] += offset;
                    vertices[vertIndex + 3] += offset;

                    // Update Scale packed in UV2 for SDF Shader. // Skip this for surface shader.
                    uv2s[vertIndex + 0].y *= xScale;
                    uv2s[vertIndex + 1].y *= xScale;
                    uv2s[vertIndex + 2].y *= xScale;
                    uv2s[vertIndex + 3].y *= xScale;
                }

                xAdvance += glyph.xAdvance * characters_Info[i].scale * xScale + m_textMeshProComponent.characterSpacing;
            }

            int   lastIndex   = characters_Info[characterCount - 1].vertexIndex;
            float startPos    = vertices[0].x;
            float lastCharPos = vertices[lastIndex + 2].x; // Position of middle of last character.

            for (int i = 0; i < characterCount; i++)
            {
                int vertIndex = characters_Info[i].vertexIndex;

                if (characters_Info[i].isVisible)
                {
                    float charMidLine = (vertices[vertIndex + 0].x + vertices[vertIndex + 2].x) / 2; // Middle X-Axis of character.

                    // Need to translate all 4 vertices of each quad to aligned with middle of character / baseline.
                    Vector3 offset = new Vector3(charMidLine, 0, 0);
                    vertices[vertIndex + 0] += -offset;
                    vertices[vertIndex + 1] += -offset;
                    vertices[vertIndex + 2] += -offset;
                    vertices[vertIndex + 3] += -offset;

                    float x0 = (charMidLine - startPos) / (lastCharPos - startPos); // Character position relative to X-Axis normalized (0 - 1) with curve.
                    float x1 = x0 + 0.0001f;
                    float y0 = TranslationCurve.Evaluate(x0) * curveScale;          // Y position for middle of character.
                    float y1 = TranslationCurve.Evaluate(x1) * curveScale;

                    Vector3 horizontal = new Vector3(1, 0, 0);
                    Vector3 normal     = new Vector3(-(y1 - y0), (x1 * (lastCharPos - startPos) + startPos) - charMidLine, 0);
                    //Vector3 dir = new Vector3(x1 * (lastCharPos - startPos) + startPos, y1) - new Vector3(charMidLine, y0);

                    //Debug.DrawLine(new Vector3(charMidLine, y0, 0), new Vector3(charMidLine, y0, 0) + dir * 1000, Color.green, 60);
                    Debug.DrawLine(new Vector3(charMidLine, y0, 0), normal, Color.green, 60);

                    Vector3 tangent = new Vector3(x1 * (lastCharPos - startPos) + startPos, y1) - new Vector3(charMidLine, y0);

                    //Debug.Log(((x1 * (lastCharPos - startPos) + startPos) - charMidLine));

                    float dot = Mathf.Acos(Vector3.Dot(horizontal, tangent.normalized)) * 57.2957795f;

                    Vector3 cross = Vector3.Cross(horizontal, tangent);
                    float   angle = cross.z > 0 ? dot : 360 - dot;

                    matrix = Matrix4x4.TRS(new Vector3(0, y0, 0), Quaternion.Euler(0, 0, angle), new Vector3(1, 1, 1));

                    vertices[vertIndex + 0] = matrix.MultiplyPoint3x4(vertices[vertIndex + 0]);
                    vertices[vertIndex + 1] = matrix.MultiplyPoint3x4(vertices[vertIndex + 1]);
                    vertices[vertIndex + 2] = matrix.MultiplyPoint3x4(vertices[vertIndex + 2]);
                    vertices[vertIndex + 3] = matrix.MultiplyPoint3x4(vertices[vertIndex + 3]);

                    //offset = new Vector3(adjusted_pos + xAdvance, 0, 0);
                    vertices[vertIndex + 0] += offset;
                    vertices[vertIndex + 1] += offset;
                    vertices[vertIndex + 2] += offset;
                    vertices[vertIndex + 3] += offset;
                }
            }


            // Upload Mesh Data
            Mesh mesh = m_textMeshProComponent.mesh;

            mesh.vertices = vertices;
            mesh.uv       = uv0s;
            mesh.uv2      = uv2s;
            mesh.colors32 = vertexColors;

            // If Surface Shader, upload Normals & Tangents to the mesh.
            if (m_sharedMaterial.HasProperty(ShaderUtilities.ID_Shininess))
            {
                mesh.normals  = normals;
                mesh.tangents = tangents;
            }

            mesh.RecalculateBounds();
            // Setting Mesh Bounds manually is more efficient.
            //m_mesh.bounds = new Bounds(new Vector3((meshExtents.Max.x + meshExtents.Min.x) / 2, (meshExtents.Max.y + meshExtents.Min.y) / 2, 0) + anchorOffset, new Vector3(meshExtents.Max.x - meshExtents.Min.x, meshExtents.Max.y - meshExtents.Min.y, 0));
        }
Beispiel #6
0
        void Awake()
        {
            //Debug.Log("TextMeshPro OnEnable() has been called. HavePropertiesChanged = " + havePropertiesChanged); // has been called on Object ID:" + gameObject.GetInstanceID());      
      
            // Get Reference to AdvancedLayoutComponent if one is attached.
            m_advancedLayoutComponent = GetComponent<TMPro_AdvancedLayout>();
            //isAdvancedLayoutComponentPresent = m_advancedLayoutComponent == null ? false : true;

            // Reset max line lenght
            max_LineWrapLength = 999;

            // Cache Reference to the Mesh Renderer.
            m_renderer = renderer;
            m_renderer.sortingLayerID = m_sortingLayerID;
            m_renderer.sortingOrder = m_sortingOrder; 
        

            // Cache Reference to the transform;
            m_transform = transform;

            // Cache a reference to the Mesh Filter.
            m_meshFilter = GetComponent<MeshFilter>();
            if (m_meshFilter == null)
                m_meshFilter = gameObject.AddComponent<MeshFilter>();

            // Cache a reference to our mesh.
            if (m_mesh == null)
            {
                //Debug.Log("Creating new mesh."); 
                m_mesh = new Mesh();
                m_mesh.hideFlags = HideFlags.HideAndDontSave;

                m_meshFilter.mesh = m_mesh;                
                //m_mesh.bounds = new Bounds(transform.position, new Vector3(1000, 1000, 0));               
            }           
            m_meshFilter.hideFlags = HideFlags.HideInInspector;
                      
            // Load the font asset and assign material to renderer.
            LoadFontAsset();

            // Allocate our initial buffers.          
            m_char_buffer = new int[m_max_characters];
            //m_lineExtents = new Mesh_Extents[m_max_numberOfLines];
            m_cached_GlyphInfo = new GlyphInfo();
            m_vertices = new Vector3[0]; // 
            m_isFirstAllocation = true;          
            m_textInfo = new TextInfo();
            m_fontAssetArray = new TextMeshProFont[16];
            m_textInfo.lineInfo = new LineInfo[m_max_numberOfLines];
            m_textInfo.meshInfo = new TMPro_MeshInfo();      
         

            // Check if we have a font asset assigned. Return if we don't because no one likes to see purple squares on screen.
            if (m_fontAsset == null)
            {
                Debug.LogWarning("Please assign a Font Asset to this " + transform.name + " gameobject.");
                return;
            }

            //// Set flags to cause ensure our text is parsed and text redrawn. 
            isInputParsingRequired = true;
            havePropertiesChanged = true;
            
            ForceMeshUpdate(); // Added to force OnWillRenderObject() to be called in case object is not visible so we get initial bounds for the mesh.
            ///* ScheduleUpdate();         
        }