/// <summary>
 /// Constructor for new Material Reference.
 /// </summary>
 /// <param name="index"></param>
 /// <param name="fontAsset"></param>
 /// <param name="spriteAsset"></param>
 /// <param name="material"></param>
 /// <param name="padding"></param>
 public MaterialReference(int index, TMP_FontAsset fontAsset, TMP_SpriteAsset spriteAsset, Material material, float padding)
 {
     this.index = index;
     this.fontAsset = fontAsset;
     this.spriteAsset = spriteAsset;
     this.material = material;
     this.isDefaultMaterial = material.GetInstanceID() == fontAsset.material.GetInstanceID() ? true : false;
     this.padding = padding;
     this.referenceCount = 0;
 }
    static int set_spriteAsset(IntPtr L)
    {
        object o = null;

        try
        {
            o = ToLua.ToObject(L, 1);
            TMPro.TMP_SubMeshUI   obj  = (TMPro.TMP_SubMeshUI)o;
            TMPro.TMP_SpriteAsset arg0 = (TMPro.TMP_SpriteAsset)ToLua.CheckObject <TMPro.TMP_SpriteAsset>(L, 2);
            obj.spriteAsset = arg0;
            return(0);
        }
        catch (Exception e)
        {
            return(LuaDLL.toluaL_exception(L, e, o, "attempt to index spriteAsset on a nil value"));
        }
    }
    static int get_spriteAsset(IntPtr L)
    {
        object o = null;

        try
        {
            o = ToLua.ToObject(L, 1);
            TMPro.TMP_SubMeshUI   obj = (TMPro.TMP_SubMeshUI)o;
            TMPro.TMP_SpriteAsset ret = obj.spriteAsset;
            ToLua.Push(L, ret);
            return(1);
        }
        catch (Exception e)
        {
            return(LuaDLL.toluaL_exception(L, e, o, "attempt to index spriteAsset on a nil value"));
        }
    }
Example #4
0
        /// <summary>
        /// Search the given sprite asset and fallbacks for a sprite whose hash code value of its name matches the target hash code.
        /// </summary>
        /// <param name="spriteAsset">The Sprite Asset to search for the given sprite whose name matches the hashcode value</param>
        /// <param name="hashCode">The hash code value matching the name of the sprite</param>
        /// <param name="includeFallbacks">Include fallback sprite assets in the search</param>
        /// <param name="spriteIndex">The index of the sprite matching the provided hash code</param>
        /// <returns>The Sprite Asset that contains the sprite</returns>
        public static TMP_SpriteAsset SearchForSpriteByHashCode(TMP_SpriteAsset spriteAsset, int hashCode, bool includeFallbacks, out int spriteIndex)
        {
            // Make sure sprite asset is not null
            if (spriteAsset == null)
            {
                spriteIndex = -1; return(null);
            }

            spriteIndex = spriteAsset.GetSpriteIndexFromHashcode(hashCode);
            if (spriteIndex != -1)
            {
                return(spriteAsset);
            }

            // Initialize list to track instance of Sprite Assets that have already been searched.
            if (k_searchedSpriteAssets == null)
            {
                k_searchedSpriteAssets = new List <int>();
            }

            k_searchedSpriteAssets.Clear();

            int id = spriteAsset.GetInstanceID();

            // Add to list of font assets already searched.
            k_searchedSpriteAssets.Add(id);

            if (includeFallbacks && spriteAsset.fallbackSpriteAssets != null && spriteAsset.fallbackSpriteAssets.Count > 0)
            {
                return(SearchForSpriteByHashCodeInternal(spriteAsset.fallbackSpriteAssets, hashCode, includeFallbacks, out spriteIndex));
            }

            // Search default sprite asset potentially assigned in the TMP Settings.
            if (includeFallbacks && TMP_Settings.defaultSpriteAsset != null)
            {
                return(SearchForSpriteByHashCodeInternal(TMP_Settings.defaultSpriteAsset, hashCode, includeFallbacks, out spriteIndex));
            }

            spriteIndex = -1;
            return(null);
        }
Example #5
0
        /// <summary>

        /// Constructor for new Material Reference.

        /// </summary>

        /// <param name="index"></param>

        /// <param name="fontAsset"></param>

        /// <param name="spriteAsset"></param>

        /// <param name="material"></param>

        /// <param name="padding"></param>

        public MaterialReference(int index, TMP_FontAsset fontAsset, TMP_SpriteAsset spriteAsset, Material material, float padding)

        {
            this.index = index;

            this.fontAsset = fontAsset;

            this.spriteAsset = spriteAsset;

            this.material = material;

            this.isDefaultMaterial = material.GetInstanceID() == fontAsset.material.GetInstanceID() ? true : false;

            this.isFallbackMaterial = false;

            this.fallbackMaterial = null;

            this.padding = padding;

            this.referenceCount = 0;
        }
        private void SaveSpriteAsset(string filePath)
        {
            filePath = filePath.Substring(0, filePath.Length - 6);
            string dataPath = Application.dataPath;

            if (filePath.IndexOf(dataPath, StringComparison.InvariantCultureIgnoreCase) == -1)
            {
                Debug.LogError("You're saving the font asset in a directory outside of this project folder. This is not supported. Please select a directory under \"" + dataPath + "\"");
                return;
            }
            string path                     = filePath.Substring(dataPath.Length - 6);
            string directoryName            = Path.GetDirectoryName(path);
            string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(path);
            string str = directoryName + "/" + fileNameWithoutExtension;

            m_SpriteAsset = ScriptableObject.CreateInstance <TMP_SpriteAsset>();
            AssetDatabase.CreateAsset(m_SpriteAsset, str + ".asset");
            m_SpriteAsset.hashCode       = TMP_TextUtilities.GetSimpleHashCode(m_SpriteAsset.name);
            m_SpriteAsset.spriteSheet    = m_SpriteAtlas;
            m_SpriteAsset.spriteInfoList = m_SpriteInfoList;
            AddDefaultMaterial(m_SpriteAsset);
        }
        private void LoadSpriteAsset(TMP_SpriteAsset spriteAsset)
        {
            if (spriteAsset == null)
            {
                // Load Default SpriteAsset
                if (TMP_Settings.defaultSpriteAsset != null)
                {
                    spriteAsset = TMP_Settings.defaultSpriteAsset;
                }
                else
                {
                    spriteAsset = Resources.Load("Sprite Assets/Default Sprite Asset") as TMP_SpriteAsset;
                }
            }

            m_spriteAsset           = spriteAsset;
            m_inlineGraphic.texture = m_spriteAsset.spriteSheet;

            if (m_textComponent != null && m_isInitialized)
            {
                m_textComponent.havePropertiesChanged = true;
                m_textComponent.SetVerticesDirty();
            }
        }
Example #8
0
        /// <summary>
        /// Cache all sequences in a lookuptable (and in a fastpath) found in SpriteAsset
        /// This Lookuptable will return the Sprite Index of the Emoji in SpriteAsset (the key will be the char sequence that will be used as replacement of old unicode format)
        ///
        /// The sequence will be the name of the TMP_Sprite in UTF32 or UTF16 HEX format separeted by '-' for each character (see below the example)
        /// Ex: 0023-fe0f-20e3.png
        /// </summary>
        /// <param name="p_spriteAsset"> The sprite asset used to cache the sequences</param>
        /// <param name="p_forceUpdate"> force update the lookup table of this SpriteAsset</param>
        /// <returns>true if lookup table changed</returns>
        public static bool TryUpdateSequenceLookupTable(TMP_SpriteAsset p_spriteAsset, bool p_forceUpdate = false)
        {
            var v_mainSpriteAsset = p_spriteAsset == null ? TMPro.TMP_Settings.defaultSpriteAsset : p_spriteAsset;

            if (v_mainSpriteAsset != null && (!s_lookupTableSequences.ContainsKey(v_mainSpriteAsset) || s_lookupTableSequences[v_mainSpriteAsset] == null || p_forceUpdate))
            {
                //Init FastlookupPath
                if (v_mainSpriteAsset != null && (!s_fastLookupPath.ContainsKey(v_mainSpriteAsset) || s_fastLookupPath[v_mainSpriteAsset] == null))
                {
                    s_fastLookupPath[v_mainSpriteAsset] = new HashSet <string>();
                }
                var v_fastLookupPath = v_mainSpriteAsset != null && s_fastLookupPath.ContainsKey(v_mainSpriteAsset) ? s_fastLookupPath[v_mainSpriteAsset] : new HashSet <string>();
                v_fastLookupPath.Clear();

                //Init Lookup Table
                if (v_mainSpriteAsset != null && (!s_lookupTableSequences.ContainsKey(v_mainSpriteAsset) || s_lookupTableSequences[v_mainSpriteAsset] == null))
                {
                    s_lookupTableSequences[v_mainSpriteAsset] = new Dictionary <string, string>();
                }
                var v_lookupTableSequences = v_mainSpriteAsset != null && s_lookupTableSequences.ContainsKey(v_mainSpriteAsset) ? s_lookupTableSequences[v_mainSpriteAsset] : new Dictionary <string, string>();
                v_lookupTableSequences.Clear();

                List <TMPro.TMP_SpriteAsset> v_spriteAssetsChecked = new List <TMPro.TMP_SpriteAsset>();
                v_spriteAssetsChecked.Add(v_mainSpriteAsset);
                //Add the main sprite asset
                if (TMPro.TMP_Settings.defaultSpriteAsset != null && !v_spriteAssetsChecked.Contains(TMPro.TMP_Settings.defaultSpriteAsset))
                {
                    v_spriteAssetsChecked.Add(TMPro.TMP_Settings.defaultSpriteAsset);
                }

                //Check in all spriteassets (and fallbacks)
                for (int i = 0; i < v_spriteAssetsChecked.Count; i++)
                {
                    var v_spriteAsset = v_spriteAssetsChecked[i];
                    if (v_spriteAsset != null)
                    {
                        //Check all sprites in this sprite asset
                        for (int j = 0; j < v_spriteAsset.spriteInfoList.Count; j++)
                        {
                            var v_element = v_spriteAsset.spriteInfoList[j];

                            if (v_element == null || string.IsNullOrEmpty(v_element.name) || !v_element.name.Contains("-"))
                            {
                                continue;
                            }

                            var v_elementName = BuildNameInEmojiSurrogateFormat(v_element.name);
                            var v_unicodeX8   = v_element.unicode.ToString("X8");

                            //Check for elements that Unicode is different from Name
                            if (!string.IsNullOrEmpty(v_elementName) &&
                                !string.Equals(v_elementName, v_unicodeX8, System.StringComparison.InvariantCultureIgnoreCase))
                            {
                                var v_tableStringBuilder = new System.Text.StringBuilder();
                                for (int k = 0; k < v_elementName.Length; k += 8)
                                {
                                    var v_hexUTF32 = v_elementName.Substring(k, Mathf.Min(v_elementName.Length - k, 8));
#if UNITY_2018_3_OR_NEWER
                                    var v_intValue = TMPro.TMP_TextUtilities.StringHexToInt(v_hexUTF32);
#else
                                    var v_intValue = TMPro.TMP_TextUtilities.StringToInt(v_hexUTF32);
#endif

                                    //Not a surrogate and is valid UTF32 (conditions to use char.ConvertFromUtf32 function)
                                    if (v_intValue > 0x000000 && v_intValue < 0x10ffff &&
                                        (v_intValue < 0x00d800 || v_intValue > 0x00dfff))
                                    {
                                        var v_UTF16Surrogate = char.ConvertFromUtf32(v_intValue);
                                        if (!string.IsNullOrEmpty(v_UTF16Surrogate))
                                        {
                                            //Add chars into cache (we must include the both char paths in fastLookupPath)
                                            foreach (var v_surrogateChar in v_UTF16Surrogate)
                                            {
                                                v_tableStringBuilder.Append(v_surrogateChar);
                                                //Add current path to lookup fast path
                                                v_fastLookupPath.Add(v_tableStringBuilder.ToString());
                                            }
                                        }
                                    }
                                    //Split into two chars (we failed to match conditions of char.ConvertFromUtf32 so we must split into two UTF16 chars)
                                    else
                                    {
                                        for (int l = 0; l < v_hexUTF32.Length; l += 4)
                                        {
                                            var v_hexUTF16 = v_hexUTF32.Substring(l, Mathf.Min(v_hexUTF32.Length - l, 4));
#if UNITY_2018_3_OR_NEWER
                                            var v_charValue = (char)TMPro.TMP_TextUtilities.StringHexToInt(v_hexUTF16);
#else
                                            var v_charValue = (char)TMPro.TMP_TextUtilities.StringToInt(v_hexUTF16);
#endif
                                            v_tableStringBuilder.Append(v_charValue);

                                            //Add current path to lookup fast path
                                            v_fastLookupPath.Add(v_tableStringBuilder.ToString());
                                        }
                                    }
                                }
                                var v_tableKey = v_tableStringBuilder.ToString();
                                //Add key as sequence in lookupTable
                                if (!string.IsNullOrEmpty(v_tableKey) && !v_lookupTableSequences.ContainsKey(v_tableKey))
                                {
                                    v_lookupTableSequences[v_tableKey] = v_element.name; //j;
                                }
                            }
                        }

                        //Add Fallbacks (before the next sprite asset and after this sprite asset)
                        for (int k = v_spriteAsset.fallbackSpriteAssets.Count - 1; k >= 0; k--)
                        {
                            var v_fallback = v_spriteAsset.fallbackSpriteAssets[k];
                            if (v_fallback != null && !v_spriteAssetsChecked.Contains(v_fallback))
                            {
                                v_spriteAssetsChecked.Insert(i + 1, v_fallback);
                            }
                        }
                    }
                }
                return(true);
            }

            return(false);
        }
Example #9
0
 private bool TryGetSpriteAssetInternal(int hashCode, out TMP_SpriteAsset spriteAsset)
 {
     spriteAsset = null;
     return(this.m_SpriteAssetReferenceLookup.TryGetValue(hashCode, out spriteAsset));
 }
Example #10
0
        IEnumerator DoSpriteAnimationInternal(int currentCharacter, TMP_SpriteAsset spriteAsset, int start, int end, int framerate)
        {
            if (m_TextComponent == null)
            {
                yield break;
            }

            // We yield otherwise this gets called before the sprite has rendered.
            yield return(null);

            int currentFrame = start;

            // Make sure end frame does not exceed the number of sprites in the sprite asset.
            if (end > spriteAsset.spriteCharacterTable.Count)
            {
                end = spriteAsset.spriteCharacterTable.Count - 1;
            }

            // Get a reference to the current character's info
            TMP_CharacterInfo charInfo = m_TextComponent.textInfo.characterInfo[currentCharacter];

            int materialIndex = charInfo.materialReferenceIndex;
            int vertexIndex   = charInfo.vertexIndex;

            TMP_MeshInfo meshInfo = m_TextComponent.textInfo.meshInfo[materialIndex];

            float baseSpriteScale = spriteAsset.spriteCharacterTable[start].scale * spriteAsset.spriteCharacterTable[start].glyph.scale;

            float elapsedTime = 0;
            float targetTime  = 1f / Mathf.Abs(framerate);

            while (true)
            {
                if (elapsedTime > targetTime)
                {
                    elapsedTime = 0;

                    // Return if sprite was truncated or replaced by the Ellipsis character.
                    char character = m_TextComponent.textInfo.characterInfo[currentCharacter].character;
                    if (character == 0x03 || character == 0x2026)
                    {
                        m_animations.Remove(currentCharacter);
                        yield break;
                    }

                    // Get a reference to the current sprite
                    TMP_SpriteCharacter spriteCharacter = spriteAsset.spriteCharacterTable[currentFrame];

                    // Update the vertices for the new sprite
                    Vector3[] vertices = meshInfo.vertices;

                    Vector2 origin = new Vector2(charInfo.origin, charInfo.baseLine);

                    float spriteScale = charInfo.scale / baseSpriteScale * spriteCharacter.scale * spriteCharacter.glyph.scale;

                    Vector3 bl = new Vector3(origin.x + spriteCharacter.glyph.metrics.horizontalBearingX * spriteScale, origin.y + (spriteCharacter.glyph.metrics.horizontalBearingY - spriteCharacter.glyph.metrics.height) * spriteScale);
                    Vector3 tl = new Vector3(bl.x, origin.y + spriteCharacter.glyph.metrics.horizontalBearingY * spriteScale);
                    Vector3 tr = new Vector3(origin.x + (spriteCharacter.glyph.metrics.horizontalBearingX + spriteCharacter.glyph.metrics.width) * spriteScale, tl.y);
                    Vector3 br = new Vector3(tr.x, bl.y);

                    vertices[vertexIndex + 0] = bl;
                    vertices[vertexIndex + 1] = tl;
                    vertices[vertexIndex + 2] = tr;
                    vertices[vertexIndex + 3] = br;

                    // Update the UV to point to the new sprite
                    Vector2[] uvs0 = meshInfo.uvs0;

                    Vector2 uv0 = new Vector2((float)spriteCharacter.glyph.glyphRect.x / spriteAsset.spriteSheet.width, (float)spriteCharacter.glyph.glyphRect.y / spriteAsset.spriteSheet.height);
                    Vector2 uv1 = new Vector2(uv0.x, (float)(spriteCharacter.glyph.glyphRect.y + spriteCharacter.glyph.glyphRect.height) / spriteAsset.spriteSheet.height);
                    Vector2 uv2 = new Vector2((float)(spriteCharacter.glyph.glyphRect.x + spriteCharacter.glyph.glyphRect.width) / spriteAsset.spriteSheet.width, uv1.y);
                    Vector2 uv3 = new Vector2(uv2.x, uv0.y);

                    uvs0[vertexIndex + 0] = uv0;
                    uvs0[vertexIndex + 1] = uv1;
                    uvs0[vertexIndex + 2] = uv2;
                    uvs0[vertexIndex + 3] = uv3;

                    // Update the modified vertex attributes
                    meshInfo.mesh.vertices = vertices;
                    meshInfo.mesh.uv       = uvs0;
                    m_TextComponent.UpdateGeometry(meshInfo.mesh, materialIndex);


                    if (framerate > 0)
                    {
                        if (currentFrame < end)
                        {
                            currentFrame += 1;
                        }
                        else
                        {
                            currentFrame = start;
                        }
                    }
                    else
                    {
                        if (currentFrame > start)
                        {
                            currentFrame -= 1;
                        }
                        else
                        {
                            currentFrame = end;
                        }
                    }
                }

                elapsedTime += Time.deltaTime;

                yield return(null);
            }
        }
Example #11
0
        /// <summary>
        /// Search the given sprite asset and fallbacks for a sprite whose hash code value of its name matches the target hash code.
        /// </summary>
        /// <param name="spriteAsset">The Sprite Asset to search for the given sprite whose name matches the hashcode value</param>
        /// <param name="hashCode">The hash code value matching the name of the sprite</param>
        /// <param name="includeFallbacks">Include fallback sprite assets in the search</param>
        /// <param name="spriteIndex">The index of the sprite matching the provided hash code</param>
        /// <returns>The Sprite Asset that contains the sprite</returns>
        public static TMP_SpriteAsset SearchForSpriteByHashCode(TMP_SpriteAsset spriteAsset, int hashCode, bool includeFallbacks, out int spriteIndex)
        {
            // Make sure sprite asset is not null
            if (spriteAsset == null)
            {
                spriteIndex = -1; return(null);
            }

            spriteIndex = spriteAsset.GetSpriteIndexFromHashcode(hashCode);
            if (spriteIndex != -1)
            {
                return(spriteAsset);
            }

            // Initialize or clear list to Sprite Assets that have already been searched.
            if (k_searchedSpriteAssets == null)
            {
                k_searchedSpriteAssets = new HashSet <int>();
            }
            else
            {
                k_searchedSpriteAssets.Clear();
            }

            int id = spriteAsset.instanceID;

            // Add to list of font assets already searched.
            k_searchedSpriteAssets.Add(id);

            TMP_SpriteAsset tempSpriteAsset;

            // Search potential fallbacks assigned to local sprite asset.
            if (includeFallbacks && spriteAsset.fallbackSpriteAssets != null && spriteAsset.fallbackSpriteAssets.Count > 0)
            {
                tempSpriteAsset = SearchForSpriteByHashCodeInternal(spriteAsset.fallbackSpriteAssets, hashCode, true, out spriteIndex);

                if (spriteIndex != -1)
                {
                    return(tempSpriteAsset);
                }
            }

            // Search default sprite asset potentially assigned in the TMP Settings.
            if (includeFallbacks && TMP_Settings.defaultSpriteAsset != null)
            {
                tempSpriteAsset = SearchForSpriteByHashCodeInternal(TMP_Settings.defaultSpriteAsset, hashCode, true, out spriteIndex);

                if (spriteIndex != -1)
                {
                    return(tempSpriteAsset);
                }
            }

            // Clear search list since we are now looking for the missing sprite character.
            k_searchedSpriteAssets.Clear();

            uint missingSpriteCharacterUnicode = TMP_Settings.missingCharacterSpriteUnicode;

            // Get sprite index for the given unicode
            spriteIndex = spriteAsset.GetSpriteIndexFromUnicode(missingSpriteCharacterUnicode);
            if (spriteIndex != -1)
            {
                return(spriteAsset);
            }

            // Add current sprite asset to list of assets already searched.
            k_searchedSpriteAssets.Add(id);

            // Search for the missing sprite character in the local sprite asset and potential fallbacks.
            if (includeFallbacks && spriteAsset.fallbackSpriteAssets != null && spriteAsset.fallbackSpriteAssets.Count > 0)
            {
                tempSpriteAsset = SearchForSpriteByUnicodeInternal(spriteAsset.fallbackSpriteAssets, missingSpriteCharacterUnicode, true, out spriteIndex);

                if (spriteIndex != -1)
                {
                    return(tempSpriteAsset);
                }
            }

            // Search for the missing sprite character in the default sprite asset and potential fallbacks.
            if (includeFallbacks && TMP_Settings.defaultSpriteAsset != null)
            {
                tempSpriteAsset = SearchForSpriteByUnicodeInternal(TMP_Settings.defaultSpriteAsset, missingSpriteCharacterUnicode, true, out spriteIndex);
                if (spriteIndex != -1)
                {
                    return(tempSpriteAsset);
                }
            }

            spriteIndex = -1;
            return(null);
        }
        IEnumerator DoSpriteAnimationInternal(int currentCharacter, TMP_SpriteAsset spriteAsset, int start, int end, int framerate)
        {
            if (m_TextComponent == null)
            {
                yield break;
            }

            // We yield otherwise this gets called before the sprite has rendered.
            yield return(null);

            int currentFrame = start;

            // Make sure end frame does not exceed the number of sprites in the sprite asset.
            if (end > spriteAsset.spriteInfoList.Count)
            {
                end = spriteAsset.spriteInfoList.Count - 1;
            }

            // Get a reference to the geometry of the current character.
            TMP_CharacterInfo charInfo = m_TextComponent.textInfo.characterInfo[currentCharacter];

            int materialIndex = charInfo.materialReferenceIndex;
            int vertexIndex   = charInfo.vertexIndex;

            TMP_MeshInfo meshInfo = m_TextComponent.textInfo.meshInfo[materialIndex];

            float elapsedTime = 0;
            float targetTime  = 1f / Mathf.Abs(framerate);

            while (true)
            {
                if (elapsedTime > targetTime)
                {
                    elapsedTime = 0;

                    // Get a reference to the current sprite
                    TMP_Sprite sprite = spriteAsset.spriteInfoList[currentFrame];

                    // Update the vertices for the new sprite
                    Vector3[] vertices = meshInfo.vertices;

                    Vector2 origin      = new Vector2(charInfo.origin, charInfo.baseLine);
                    float   spriteScale = charInfo.fontAsset.fontInfo.Ascender / sprite.height * sprite.scale * charInfo.scale;

                    Vector3 bl = new Vector3(origin.x + sprite.xOffset * spriteScale, origin.y + (sprite.yOffset - sprite.height) * spriteScale);
                    Vector3 tl = new Vector3(bl.x, origin.y + sprite.yOffset * spriteScale);
                    Vector3 tr = new Vector3(origin.x + (sprite.xOffset + sprite.width) * spriteScale, tl.y);
                    Vector3 br = new Vector3(tr.x, bl.y);

                    vertices[vertexIndex + 0] = bl;
                    vertices[vertexIndex + 1] = tl;
                    vertices[vertexIndex + 2] = tr;
                    vertices[vertexIndex + 3] = br;

                    // Update the UV to point to the new sprite
                    Vector2[] uvs0 = meshInfo.uvs0;

                    Vector2 uv0 = new Vector2(sprite.x / spriteAsset.spriteSheet.width, sprite.y / spriteAsset.spriteSheet.height);
                    Vector2 uv1 = new Vector2(uv0.x, (sprite.y + sprite.height) / spriteAsset.spriteSheet.height);
                    Vector2 uv2 = new Vector2((sprite.x + sprite.width) / spriteAsset.spriteSheet.width, uv1.y);
                    Vector2 uv3 = new Vector2(uv2.x, uv0.y);

                    uvs0[vertexIndex + 0] = uv0;
                    uvs0[vertexIndex + 1] = uv1;
                    uvs0[vertexIndex + 2] = uv2;
                    uvs0[vertexIndex + 3] = uv3;

                    // Update the modified vertex attributes
                    meshInfo.mesh.vertices = vertices;
                    meshInfo.mesh.uv       = uvs0;
                    m_TextComponent.UpdateGeometry(meshInfo.mesh, materialIndex);


                    if (framerate > 0)
                    {
                        if (currentFrame < end)
                        {
                            currentFrame += 1;
                        }
                        else
                        {
                            currentFrame = start;
                        }
                    }
                    else
                    {
                        if (currentFrame > start)
                        {
                            currentFrame -= 1;
                        }
                        else
                        {
                            currentFrame = end;
                        }
                    }
                }

                elapsedTime += Time.deltaTime;

                yield return(null);
            }
        }
        /// <summary>
        /// Internal method to add a new sprite asset to the dictionary.
        /// </summary>
        /// <param name="hashCode"></param>
        /// <param name="spriteAsset"></param>
        private void AddSpriteAssetInternal(int hashCode, TMP_SpriteAsset spriteAsset)
        {
            if (m_SpriteAssetReferenceLookup.ContainsKey(hashCode)) return;

            // Add reference to Sprite Asset.
            m_SpriteAssetReferenceLookup.Add(hashCode, spriteAsset);

            // Add reference to Sprite Asset using the asset hashcode.
            m_FontMaterialReferenceLookup.Add(hashCode, spriteAsset.material);

            // Compatibility check
            if (spriteAsset.hashCode == 0) spriteAsset.hashCode = hashCode;
        }
        /// <summary>
        /// Internal method to add a new sprite asset to the dictionary.
        /// </summary>
        /// <param name="hashCode"></param>
        /// <param name="spriteAsset"></param>
        private void AddSpriteAssetInternal(TMP_SpriteAsset spriteAsset)
        {
            if (m_SpriteAssetReferenceLookup.ContainsKey(spriteAsset.hashCode)) return;

            // Add reference to sprite asset.
            m_SpriteAssetReferenceLookup.Add(spriteAsset.hashCode, spriteAsset);

            // Adding reference to the sprite asset material as well
            m_FontMaterialReferenceLookup.Add(spriteAsset.hashCode, spriteAsset.material);
        }
        /// <summary>
        /// Function to check if the sprite asset is already referenced.
        /// </summary>
        /// <param name="font"></param>
        /// <returns></returns>
        public bool Contains(TMP_SpriteAsset sprite)
        {
            if (m_FontAssetReferenceLookup.ContainsKey(sprite.hashCode))
                return true;

            return false;
        }
 /// <summary>
 /// Function returning the Sprite Asset corresponding to the provided hash code.
 /// </summary>
 /// <param name="hashCode"></param>
 /// <param name="spriteAsset"></param>
 /// <returns></returns>
 public static bool TryGetSpriteAsset(int hashCode, out TMP_SpriteAsset spriteAsset)
 {
     return MaterialReferenceManager.instance.TryGetSpriteAssetInternal(hashCode, out spriteAsset);
 }
 /// <summary>
 /// Add new Sprite Asset to dictionary.
 /// </summary>
 /// <param name="hashCode"></param>
 /// <param name="spriteAsset"></param>
 public static void AddSpriteAsset(int hashCode, TMP_SpriteAsset spriteAsset)
 {
     MaterialReferenceManager.instance.AddSpriteAssetInternal(hashCode, spriteAsset);
 }
 /// <summary>
 /// Add new Sprite Asset to dictionary.
 /// </summary>
 /// <param name="hashCode"></param>
 /// <param name="spriteAsset"></param>
 public static void AddSpriteAsset(TMP_SpriteAsset spriteAsset)
 {
     MaterialReferenceManager.instance.AddSpriteAssetInternal(spriteAsset);
 }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="material"></param>
        /// <param name="spriteAsset"></param>
        /// <param name="materialReferences"></param>
        /// <param name="materialReferenceIndexLookup"></param>
        /// <returns></returns>
        public static int AddMaterialReference(Material material, TMP_SpriteAsset spriteAsset, MaterialReference[] materialReferences, Dictionary<int, int> materialReferenceIndexLookup)
        {
            int materialID = material.GetInstanceID();
            int index = 0;

            if (materialReferenceIndexLookup.TryGetValue(materialID, out index))
            {
                return index;
            }
            else
            {
                index = materialReferenceIndexLookup.Count;

                // Add new reference index
                materialReferenceIndexLookup[materialID] = index;

                materialReferences[index].index = index;
                materialReferences[index].fontAsset = materialReferences[0].fontAsset;
                materialReferences[index].spriteAsset = spriteAsset;
                materialReferences[index].material = material;
                materialReferences[index].isDefaultMaterial = true;
                //materialReferences[index].padding = 0;
                materialReferences[index].referenceCount = 0;

                return index;
            }
        }
Example #20
0
        static Dictionary <TMP_SpriteAsset, HashSet <string> > s_fastLookupPath = new Dictionary <TMP_SpriteAsset, HashSet <string> >(); //this will cache will save the path of each character in sequence, so for every iteration we can check if we need to continue

        #endregion

        #region Emoji Search Engine Functions

        /// <summary>
        /// Try parse text converting to supported EmojiSequence format (all char sequences will be replaced to <sprite=index>)
        /// </summary>
        /// <param name="p_spriteAsset"></param>
        /// <param name="text"></param>
        /// <returns></returns>
        public static bool ParseEmojiCharSequence(TMP_SpriteAsset p_spriteAsset, ref string p_text)
        {
            bool v_changed = false;

            TryUpdateSequenceLookupTable(p_spriteAsset);
            if (!string.IsNullOrEmpty(p_text))
            {
                var v_mainSpriteAsset      = p_spriteAsset == null ? TMPro.TMP_Settings.defaultSpriteAsset : p_spriteAsset;
                var v_fastLookupPath       = v_mainSpriteAsset != null && s_fastLookupPath.ContainsKey(v_mainSpriteAsset) ? s_fastLookupPath[v_mainSpriteAsset] : new HashSet <string>();
                var v_lookupTableSequences = v_mainSpriteAsset != null && s_lookupTableSequences.ContainsKey(v_mainSpriteAsset) ? s_lookupTableSequences[v_mainSpriteAsset] : new Dictionary <string, string>();

                if (v_lookupTableSequences == null || v_lookupTableSequences.Count == 0)
                {
                    return(false);
                }

                System.Text.StringBuilder sb = new System.Text.StringBuilder();

                //Eficient way to check characters
                for (int i = 0; i < p_text.Length; i++)
                {
                    int v_endCounter = i;
                    System.Text.StringBuilder v_auxSequence = new System.Text.StringBuilder();

                    //Look for sequences in fastLookupPath
                    while (p_text.Length > v_endCounter &&
                           (v_endCounter == i ||
                            v_fastLookupPath.Contains(v_auxSequence.ToString()))
                           )
                    {
                        //We must skip variant selectors (if found it)
                        v_auxSequence.Append(p_text[v_endCounter]);
                        v_endCounter++;
                    }

                    //Remove last added guy (the previous one is the correct)
                    if (v_auxSequence.Length > 0 && !v_fastLookupPath.Contains(v_auxSequence.ToString()))
                    {
                        v_auxSequence.Remove(v_auxSequence.Length - 1, 1);
                    }

                    var v_sequence = v_auxSequence.Length > 0 ? v_auxSequence.ToString() : "";
                    //Found a sequence, add it instead add the character
                    if (v_sequence.Length > 0 && v_lookupTableSequences.ContainsKey(v_sequence))
                    {
                        v_changed = true;
                        //Changed Index to Sprite Name to prevent erros when looking at fallbacks
                        sb.Append(string.Format("<sprite name=\"{0}\">", v_lookupTableSequences[v_sequence]));

                        i += (v_sequence.Length - 1); //jump checked characters
                    }
                    //add the char (normal character)
                    else
                    {
                        var c = p_text[i];
                        if (c == '\ufe0f' || c == '\ufe0e')
                        {
                            v_changed = true;
                            continue;
                        }
                        sb.Append(c);
                    }
                }

                if (v_changed)
                {
                    p_text = sb.ToString();
                }
            }

            return(v_changed);
        }
Example #21
0
        void DrawEditorPanel()
        {
            // label
            GUILayout.Label("Import Settings", EditorStyles.boldLabel);

            EditorGUI.BeginChangeCheck();

            // Sprite Texture Selection
            m_JsonFile = EditorGUILayout.ObjectField("Sprite Data Source", m_JsonFile, typeof(TextAsset), false) as TextAsset;

            m_SpriteDataFormat = (SpriteAssetImportFormats)EditorGUILayout.EnumPopup("Import Format", m_SpriteDataFormat);

            // Sprite Texture Selection
            m_SpriteAtlas = EditorGUILayout.ObjectField("Sprite Texture Atlas", m_SpriteAtlas, typeof(Texture2D), false) as Texture2D;

            if (EditorGUI.EndChangeCheck())
            {
                m_CreationFeedback = string.Empty;
            }

            GUILayout.Space(10);

            GUI.enabled = m_JsonFile != null && m_SpriteAtlas != null && m_SpriteDataFormat != SpriteAssetImportFormats.None;

            // Create Sprite Asset
            if (GUILayout.Button("Create Sprite Asset"))
            {
                m_CreationFeedback = string.Empty;

                // Read json data file
                if (m_JsonFile != null)
                {
                    switch (m_SpriteDataFormat)
                    {
                    case SpriteAssetImportFormats.TexturePackerJsonArray:
                        TexturePacker_JsonArray.SpriteDataObject jsonData = null;
                        try
                        {
                            jsonData = JsonUtility.FromJson <TexturePacker_JsonArray.SpriteDataObject>(m_JsonFile.text);
                        }
                        catch
                        {
                            m_CreationFeedback = "The Sprite Data Source file [" + m_JsonFile.name + "] appears to be invalid or incorrectly formatted.";
                        }

                        if (jsonData != null && jsonData.frames != null && jsonData.frames.Count > 0)
                        {
                            int spriteCount = jsonData.frames.Count;

                            // Update import results
                            m_CreationFeedback  = "<b>Import Results</b>\n--------------------\n";
                            m_CreationFeedback += "<color=#C0ffff><b>" + spriteCount + "</b></color> Sprites were imported from file.";

                            if (m_SpriteAsset != null)
                            {
                                DestroyImmediate(m_SpriteAsset);
                            }

                            // Create new Sprite Asset
                            m_SpriteAsset = CreateInstance <TMP_SpriteAsset>();

                            // Assign sprite sheet / atlas texture to sprite asset
                            m_SpriteAsset.spriteSheet = m_SpriteAtlas;

                            List <TMP_SpriteGlyph>     spriteGlyphTable     = new List <TMP_SpriteGlyph>();
                            List <TMP_SpriteCharacter> spriteCharacterTable = new List <TMP_SpriteCharacter>();

                            PopulateSpriteTables(jsonData, spriteCharacterTable, spriteGlyphTable);

                            m_SpriteAsset.spriteCharacterTable = spriteCharacterTable;
                            m_SpriteAsset.spriteGlyphTable     = spriteGlyphTable;
                        }
                        break;
                    }
                }
            }

            GUI.enabled = true;

            // Creation Feedback
            GUILayout.Space(5);
            GUILayout.BeginVertical(EditorStyles.helpBox, GUILayout.Height(60));
            {
                EditorGUILayout.LabelField(m_CreationFeedback, TMP_UIStyleManager.label);
            }
            GUILayout.EndVertical();

            GUILayout.Space(5);
            GUI.enabled = m_JsonFile != null && m_SpriteAtlas && m_SpriteInfoList != null && m_SpriteAsset != null;
            if (GUILayout.Button("Save Sprite Asset") && m_JsonFile != null)
            {
                string filePath = EditorUtility.SaveFilePanel("Save Sprite Asset File", new FileInfo(AssetDatabase.GetAssetPath(m_JsonFile)).DirectoryName, m_JsonFile.name, "asset");

                if (filePath.Length == 0)
                {
                    return;
                }

                SaveSpriteAsset(filePath);
            }
            GUI.enabled = true;
        }
Example #22
0
        /// <summary>
        /// Restore the State of various variables used in the mesh creation loop.
        /// </summary>
        /// <param name="state"></param>
        /// <returns></returns>
        protected int RestoreWordWrappingState(ref WordWrapState state)
        {
            int index = state.previous_WordBreak;

            // Multi Font & Material support related
            m_currentFontAsset = state.currentFontAsset;
            m_currentSpriteAsset = state.currentSpriteAsset;
            m_currentMaterial = state.currentMaterial;
            m_currentMaterialIndex = state.currentMaterialIndex;

            m_characterCount = state.total_CharacterCount + 1;
            m_visibleCharacterCount = state.visible_CharacterCount;
            m_visibleSpriteCount = state.visible_SpriteCount;
            m_textInfo.linkCount = state.visible_LinkCount;

            m_firstCharacterOfLine = state.firstCharacterIndex;
            m_firstVisibleCharacterOfLine = state.firstVisibleCharacterIndex;
            m_lastVisibleCharacterOfLine = state.lastVisibleCharIndex;

            m_style = state.fontStyle;
            m_fontScale = state.fontScale;
            m_fontScaleMultiplier = state.fontScaleMultiplier;
            //m_maxFontScale = state.maxFontScale;
            m_currentFontSize = state.currentFontSize;

            m_xAdvance = state.xAdvance;
            m_maxAscender = state.maxAscender;
            m_maxDescender = state.maxDescender;
            m_maxLineAscender = state.maxLineAscender;
            m_maxLineDescender = state.maxLineDescender;
            m_startOfLineAscender = state.previousLineAscender;
            m_preferredWidth = state.preferredWidth;
            m_preferredHeight = state.preferredHeight;
            m_meshExtents = state.meshExtents;

            m_lineNumber = state.lineNumber;
            m_lineOffset = state.lineOffset;
            m_baselineOffset = state.baselineOffset;

            //m_lineJustification = state.alignment;
            m_htmlColor = state.vertexColor;
            tag_NoParsing = state.tagNoParsing;

            // XML Tag Stack
            m_colorStack = state.colorStack;
            m_sizeStack = state.sizeStack;
            m_fontWeightStack = state.fontWeightStack;
            m_styleStack = state.styleStack;
            m_materialReferenceStack = state.materialReferenceStack;

            if (m_lineNumber < m_textInfo.lineInfo.Length)
                m_textInfo.lineInfo[m_lineNumber] = state.lineInfo;

            return index;
        }
        private IEnumerator DoSpriteAnimationInternal(int currentCharacter, TMP_SpriteAsset spriteAsset, int start, int end, int framerate)
        {
            if (this.m_TextComponent == null)
            {
                yield break;
            }
            yield return(null);

            int currentFrame = start;

            if (end > spriteAsset.spriteInfoList.Count)
            {
                end = spriteAsset.spriteInfoList.Count - 1;
            }
            TMP_CharacterInfo charInfo = this.m_TextComponent.textInfo.characterInfo[currentCharacter];
            int          materialIndex = charInfo.materialReferenceIndex;
            int          vertexIndex   = charInfo.vertexIndex;
            TMP_MeshInfo meshInfo      = this.m_TextComponent.textInfo.meshInfo[materialIndex];
            float        elapsedTime   = 0f;
            float        targetTime    = 1f / (float)Mathf.Abs(framerate);

            for (;;)
            {
                if (elapsedTime > targetTime)
                {
                    elapsedTime = 0f;
                    TMP_Sprite tmp_Sprite = spriteAsset.spriteInfoList[currentFrame];
                    Vector3[]  vertices   = meshInfo.vertices;
                    Vector2    vector     = new Vector2(charInfo.origin, charInfo.baseLine);
                    float      num        = charInfo.fontAsset.fontInfo.Ascender / tmp_Sprite.height * tmp_Sprite.scale * charInfo.scale;
                    Vector3    vector2    = new Vector3(vector.x + tmp_Sprite.xOffset * num, vector.y + (tmp_Sprite.yOffset - tmp_Sprite.height) * num);
                    Vector3    vector3    = new Vector3(vector2.x, vector.y + tmp_Sprite.yOffset * num);
                    Vector3    vector4    = new Vector3(vector.x + (tmp_Sprite.xOffset + tmp_Sprite.width) * num, vector3.y);
                    Vector3    vector5    = new Vector3(vector4.x, vector2.y);
                    vertices[vertexIndex]     = vector2;
                    vertices[vertexIndex + 1] = vector3;
                    vertices[vertexIndex + 2] = vector4;
                    vertices[vertexIndex + 3] = vector5;
                    Vector2[] uvs     = meshInfo.uvs0;
                    Vector2   vector6 = new Vector2(tmp_Sprite.x / (float)spriteAsset.spriteSheet.width, tmp_Sprite.y / (float)spriteAsset.spriteSheet.height);
                    Vector2   vector7 = new Vector2(vector6.x, (tmp_Sprite.y + tmp_Sprite.height) / (float)spriteAsset.spriteSheet.height);
                    Vector2   vector8 = new Vector2((tmp_Sprite.x + tmp_Sprite.width) / (float)spriteAsset.spriteSheet.width, vector7.y);
                    Vector2   vector9 = new Vector2(vector8.x, vector6.y);
                    uvs[vertexIndex]       = vector6;
                    uvs[vertexIndex + 1]   = vector7;
                    uvs[vertexIndex + 2]   = vector8;
                    uvs[vertexIndex + 3]   = vector9;
                    meshInfo.mesh.vertices = vertices;
                    meshInfo.mesh.uv       = uvs;
                    this.m_TextComponent.UpdateGeometry(meshInfo.mesh, materialIndex);
                    if (framerate > 0)
                    {
                        if (currentFrame < end)
                        {
                            currentFrame++;
                        }
                        else
                        {
                            currentFrame = start;
                        }
                    }
                    else if (currentFrame > start)
                    {
                        currentFrame--;
                    }
                    else
                    {
                        currentFrame = end;
                    }
                }
                elapsedTime += Time.deltaTime;
                yield return(null);
            }
            yield break;
        }
 /// <summary>
 /// Add new Sprite Asset to dictionary.
 /// </summary>
 /// <param name="hashCode"></param>
 /// <param name="spriteAsset"></param>
 public static void AddSpriteAsset(TMP_SpriteAsset spriteAsset)
 {
     MaterialReferenceManager.instance.AddSpriteAssetInternal(spriteAsset);
 }
        /// <summary>
        /// Internal function returning the Sprite Asset corresponding to the provided hash code.
        /// </summary>
        /// <param name="hashCode"></param>
        /// <param name="fontAsset"></param>
        /// <returns></returns>
        private bool TryGetSpriteAssetInternal(int hashCode, out TMP_SpriteAsset spriteAsset)
        {
            spriteAsset = null;

            if (m_SpriteAssetReferenceLookup.TryGetValue(hashCode, out spriteAsset))
            {
                return true;
            }

            return false;
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="unicode"></param>
        /// <param name="spriteAsset"></param>
        /// <param name="includeFallbacks"></param>
        /// <returns></returns>
        static TMP_SpriteCharacter GetSpriteCharacterFromSpriteAsset_Internal(uint unicode, TMP_SpriteAsset spriteAsset, bool includeFallbacks)
        {
            TMP_SpriteCharacter spriteCharacter;

            // Search sprite asset for potential sprite character for the given unicode value
            if (spriteAsset.spriteCharacterLookupTable.TryGetValue(unicode, out spriteCharacter))
            {
                return(spriteCharacter);
            }

            if (includeFallbacks)
            {
                List <TMP_SpriteAsset> fallbackSpriteAsset = spriteAsset.fallbackSpriteAssets;

                if (fallbackSpriteAsset != null && fallbackSpriteAsset.Count > 0)
                {
                    int fallbackCount = fallbackSpriteAsset.Count;

                    for (int i = 0; i < fallbackCount; i++)
                    {
                        TMP_SpriteAsset temp = fallbackSpriteAsset[i];

                        if (temp == null)
                        {
                            continue;
                        }

                        int id = temp.instanceID;

                        // Try adding asset to search list. If already present skip to the next one otherwise check if it contains the requested character.
                        if (k_SearchedAssets.Add(id) == false)
                        {
                            continue;
                        }

                        spriteCharacter = GetSpriteCharacterFromSpriteAsset_Internal(unicode, temp, true);

                        if (spriteCharacter != null)
                        {
                            return(spriteCharacter);
                        }
                    }
                }
            }

            return(null);
        }
Example #27
0
        /// <summary>
        /// Function to identify and validate the rich tag. Returns the position of the > if the tag was valid.
        /// </summary>
        /// <param name="chars"></param>
        /// <param name="startIndex"></param>
        /// <param name="endIndex"></param>
        /// <returns></returns>
        protected bool ValidateHtmlTag(int[] chars, int startIndex, out int endIndex)
        {
            int tagCharCount = 0;
            byte attributeFlag = 0;

            TagUnits tagUnits = TagUnits.Pixels;
            TagType tagType = TagType.None;

            int attributeIndex = 0;
            m_xmlAttribute[attributeIndex].nameHashCode = 0;
            m_xmlAttribute[attributeIndex].valueType = TagType.None;
            m_xmlAttribute[attributeIndex].valueHashCode = 0;
            m_xmlAttribute[attributeIndex].valueStartIndex = 0;
            m_xmlAttribute[attributeIndex].valueLength = 0;
            m_xmlAttribute[attributeIndex].valueDecimalIndex = 0;

            endIndex = startIndex;
            bool isTagSet = false;
            bool isValidHtmlTag = false;

            for (int i = startIndex; i < chars.Length && chars[i] != 0 && tagCharCount < m_htmlTag.Length && chars[i] != 60; i++)
            {
                if (chars[i] == 62) // ASCII Code of End HTML tag '>'
                {
                    isValidHtmlTag = true;
                    endIndex = i;
                    m_htmlTag[tagCharCount] = (char)0;
                    break;
                }

                m_htmlTag[tagCharCount] = (char)chars[i];
                tagCharCount += 1;

                if (attributeFlag == 1)
                {
                    if (m_xmlAttribute[attributeIndex].valueStartIndex == 0)
                    {
                        // Check for attribute type
                        if (chars[i] == 43 || chars[i] == 45 || char.IsDigit((char)chars[i]))
                        {
                            tagType = TagType.NumericalValue;
                            m_xmlAttribute[attributeIndex].valueType = TagType.NumericalValue;
                            m_xmlAttribute[attributeIndex].valueStartIndex = tagCharCount - 1;
                            m_xmlAttribute[attributeIndex].valueLength += 1;
                        }
                        else if (chars[i] == 35)
                        {
                            tagType = TagType.ColorValue;
                            m_xmlAttribute[attributeIndex].valueType = TagType.ColorValue;
                            m_xmlAttribute[attributeIndex].valueStartIndex = tagCharCount - 1;
                            m_xmlAttribute[attributeIndex].valueLength += 1;
                        }
                        else if (chars[i] != 34)
                        {
                            tagType = TagType.StringValue;
                            m_xmlAttribute[attributeIndex].valueType = TagType.StringValue;
                            m_xmlAttribute[attributeIndex].valueStartIndex = tagCharCount - 1;
                            m_xmlAttribute[attributeIndex].valueHashCode = (m_xmlAttribute[attributeIndex].valueHashCode << 5) + m_xmlAttribute[attributeIndex].valueHashCode ^ chars[i];
                            m_xmlAttribute[attributeIndex].valueLength += 1;
                        }
                    }
                    else
                    {
                        if (tagType == TagType.NumericalValue)
                        {
                            if (chars[i] == 46) // '.' Decimal Point Index
                                m_xmlAttribute[attributeIndex].valueDecimalIndex = tagCharCount - 1;

                            // Check for termination of numerical value.
                            if (chars[i] == 112 || chars[i] == 101 || chars[i] == 37 || chars[i] == 32)
                            {
                                attributeFlag = 2;
                                tagType = TagType.None;
                                attributeIndex += 1;
                                m_xmlAttribute[attributeIndex].nameHashCode = 0;
                                m_xmlAttribute[attributeIndex].valueType = TagType.None;
                                m_xmlAttribute[attributeIndex].valueHashCode = 0;
                                m_xmlAttribute[attributeIndex].valueStartIndex = 0;
                                m_xmlAttribute[attributeIndex].valueLength = 0;
                                m_xmlAttribute[attributeIndex].valueDecimalIndex = 0;

                                if (chars[i] == 101)
                                    tagUnits = TagUnits.FontUnits;
                                else if (chars[i] == 37)
                                    tagUnits = TagUnits.Percentage;
                            }
                            else if (attributeFlag != 2)
                            {
                                m_xmlAttribute[attributeIndex].valueLength += 1;
                            }
                        }
                        else if (tagType == TagType.ColorValue)
                        {
                            if (chars[i] != 32)
                            {
                                m_xmlAttribute[attributeIndex].valueLength += 1;
                            }
                            else
                            {
                                attributeFlag = 2;
                                tagType = TagType.None;
                                attributeIndex += 1;
                                m_xmlAttribute[attributeIndex].nameHashCode = 0;
                                m_xmlAttribute[attributeIndex].valueType = TagType.None;
                                m_xmlAttribute[attributeIndex].valueHashCode = 0;
                                m_xmlAttribute[attributeIndex].valueStartIndex = 0;
                                m_xmlAttribute[attributeIndex].valueLength = 0;
                                m_xmlAttribute[attributeIndex].valueDecimalIndex = 0;
                            }
                        }
                        else if (tagType == TagType.StringValue)
                        {
                            // Compute HashCode value for the named tag.
                            if (chars[i] != 34)
                            {
                                m_xmlAttribute[attributeIndex].valueHashCode = (m_xmlAttribute[attributeIndex].valueHashCode << 5) + m_xmlAttribute[attributeIndex].valueHashCode ^ chars[i];
                                m_xmlAttribute[attributeIndex].valueLength += 1;
                            }
                            else
                            {
                                //m_xmlAttribute[attributeIndex].valueHashCode = -1;
                                attributeFlag = 2;
                                tagType = TagType.None;
                                attributeIndex += 1;
                                m_xmlAttribute[attributeIndex].nameHashCode = 0;
                                m_xmlAttribute[attributeIndex].valueType = TagType.None;
                                m_xmlAttribute[attributeIndex].valueHashCode = 0;
                                m_xmlAttribute[attributeIndex].valueStartIndex = 0;
                                m_xmlAttribute[attributeIndex].valueLength = 0;
                                m_xmlAttribute[attributeIndex].valueDecimalIndex = 0;
                            }
                        }
                    }
                }

                if (chars[i] == 61) // '='
                    attributeFlag = 1;

                // Compute HashCode for the name of the attribute
                if (attributeFlag == 0 && chars[i] == 32)
                {
                    if (isTagSet) return false;

                    isTagSet = true;
                    attributeFlag = 2;

                    tagType = TagType.None;
                    attributeIndex += 1;
                    m_xmlAttribute[attributeIndex].nameHashCode = 0;
                    m_xmlAttribute[attributeIndex].valueType = TagType.None;
                    m_xmlAttribute[attributeIndex].valueHashCode = 0;
                    m_xmlAttribute[attributeIndex].valueStartIndex = 0;
                    m_xmlAttribute[attributeIndex].valueLength = 0;
                    m_xmlAttribute[attributeIndex].valueDecimalIndex = 0;
                }

                if (attributeFlag == 0)
                    m_xmlAttribute[attributeIndex].nameHashCode = (m_xmlAttribute[attributeIndex].nameHashCode << 3) - m_xmlAttribute[attributeIndex].nameHashCode + chars[i];

                if (attributeFlag == 2 && chars[i] == 32)
                    attributeFlag = 0;

            }

            if (!isValidHtmlTag)
            {
                return false;
            }

            //Debug.Log("Tag is [" + m_htmlTag.ArrayToString() + "].  Tag HashCode: " + m_xmlAttribute[0].nameHashCode + "  Tag Value HashCode: " + m_xmlAttribute[0].valueHashCode + "  Attribute 1 HashCode: " + m_xmlAttribute[1].nameHashCode + " Value HashCode: " + m_xmlAttribute[1].valueHashCode);
            //for (int i = 0; i < attributeIndex + 1; i++)
            //    Debug.Log("Tag [" + i + "] with HashCode: " + m_xmlAttribute[i].nameHashCode + " has value of [" + new string(m_htmlTag, m_xmlAttribute[i].valueStartIndex, m_xmlAttribute[i].valueLength) + "] Numerical Value: " + ConvertToFloat(m_htmlTag, m_xmlAttribute[i].valueStartIndex, m_xmlAttribute[i].valueLength, m_xmlAttribute[i].valueDecimalIndex));

            // Special handling of the NoParsing tag
            if (tag_NoParsing && m_xmlAttribute[0].nameHashCode != 53822163)
                return false;
            else if (m_xmlAttribute[0].nameHashCode == 53822163)
            {
                tag_NoParsing = false;
                return true;
            }

            // Color <#FF00FF>
            if (m_htmlTag[0] == 35 && tagCharCount == 7) // if Tag begins with # and contains 7 characters.
            {
                m_htmlColor = HexCharsToColor(m_htmlTag, tagCharCount);
                m_colorStack.Add(m_htmlColor);
                return true;
            }
            // Color <#FF00FF00> with alpha
            else if (m_htmlTag[0] == 35 && tagCharCount == 9) // if Tag begins with # and contains 9 characters.
            {
                m_htmlColor = HexCharsToColor(m_htmlTag, tagCharCount);
                m_colorStack.Add(m_htmlColor);
                return true;
            }
            else
            {
                float value = 0;

                switch (m_xmlAttribute[0].nameHashCode)
                {
                    case 98: // <b>
                        m_style |= FontStyles.Bold;
                        m_fontWeightInternal = 700;
                        m_fontWeightStack.Add(700);
                        return true;
                    case 427: // </b>
                        if ((m_fontStyle & FontStyles.Bold) != FontStyles.Bold)
                        {
                            m_style &= ~FontStyles.Bold;
                            m_fontWeightInternal = m_fontWeightStack.Remove();
                        }
                        return true;
                    case 105: // <i>
                        m_style |= FontStyles.Italic;
                        return true;
                    case 434: // </i>
                        m_style &= ~FontStyles.Italic;
                        return true;
                    case 115: // <s>
                        m_style |= FontStyles.Strikethrough;
                        return true;
                    case 444: // </s>
                        if ((m_fontStyle & FontStyles.Strikethrough) != FontStyles.Strikethrough)
                            m_style &= ~FontStyles.Strikethrough;
                        return true;
                    case 117: // <u>
                        m_style |= FontStyles.Underline;
                        return true;
                    case 446: // </u>
                        if ((m_fontStyle & FontStyles.Underline) != FontStyles.Underline)
                            m_style &= ~FontStyles.Underline;
                        return true;

                    case 6552: // <sub>
                        m_fontScaleMultiplier = m_currentFontAsset.fontInfo.SubSize > 0 ? m_currentFontAsset.fontInfo.SubSize : 1;
                        m_baselineOffset = m_currentFontAsset.fontInfo.SubscriptOffset * m_fontScale * m_fontScaleMultiplier;
                        m_style |= FontStyles.Subscript;
                        return true;
                    case 22673: // </sub>
                        if ((m_style & FontStyles.Subscript) == FontStyles.Subscript)
                        {
                            // Check to make sure we are not also using Superscript
                            if ((m_style & FontStyles.Superscript) == FontStyles.Superscript)
                            {
                                m_fontScaleMultiplier = m_currentFontAsset.fontInfo.SubSize > 0 ? m_currentFontAsset.fontInfo.SubSize : 1;
                                m_baselineOffset = m_currentFontAsset.fontInfo.SuperscriptOffset * m_fontScale * m_fontScaleMultiplier;
                            }
                            else
                            {
                                m_baselineOffset = 0;
                                m_fontScaleMultiplier = 1;
                            }

                            m_style &= ~FontStyles.Subscript;
                        }
                        return true;
                    case 6566: // <sup>
                        m_fontScaleMultiplier = m_currentFontAsset.fontInfo.SubSize > 0 ? m_currentFontAsset.fontInfo.SubSize : 1;
                        m_baselineOffset = m_currentFontAsset.fontInfo.SuperscriptOffset * m_fontScale * m_fontScaleMultiplier;
                        m_style |= FontStyles.Superscript;
                        return true;
                    case 22687: // </sup>
                        if ((m_style & FontStyles.Superscript) == FontStyles.Superscript)
                        {
                            // Check to make sure we are not also using Superscript
                            if ((m_style & FontStyles.Subscript) == FontStyles.Subscript)
                            {
                                m_fontScaleMultiplier = m_currentFontAsset.fontInfo.SubSize > 0 ? m_currentFontAsset.fontInfo.SubSize : 1;
                                m_baselineOffset = m_currentFontAsset.fontInfo.SubscriptOffset * m_fontScale * m_fontScaleMultiplier;
                            }
                            else
                            {
                                m_baselineOffset = 0;
                                m_fontScaleMultiplier = 1;
                            }

                            m_style &= ~FontStyles.Superscript;
                        }
                        return true;
                    case -330774850: // <font-weight>
                        value = ConvertToFloat(m_htmlTag, m_xmlAttribute[0].valueStartIndex, m_xmlAttribute[0].valueLength, m_xmlAttribute[0].valueDecimalIndex);
                        if (value == -9999 || value == 0) return false;

                        if ((m_fontStyle & FontStyles.Bold) == FontStyles.Bold)
                        {
                            // Nothing happens since Bold is forced on the text.
                            //m_fontWeight = 700;
                            return true;
                        }

                        // Remove bold style
                        m_style &= ~FontStyles.Bold;

                        switch ((int)value)
                        {
                            case 100:
                                m_fontWeightInternal = 100;
                                break;
                            case 200:
                                m_fontWeightInternal = 200;
                                break;
                            case 300:
                                m_fontWeightInternal = 300;
                                break;
                            case 400:
                                m_fontWeightInternal = 400;

                                break;
                            case 500:
                                m_fontWeightInternal = 500;
                                break;
                            case 600:
                                m_fontWeightInternal = 600;
                                break;
                            case 700:
                                m_fontWeightInternal = 700;
                                m_style |= FontStyles.Bold;
                                break;
                            case 800:
                                m_fontWeightInternal = 800;
                                break;
                            case 900:
                                m_fontWeightInternal = 900;
                                break;
                        }

                        m_fontWeightStack.Add(m_fontWeightInternal);

                        return true;
                    case -1885698441: // </font-weight>
                        m_fontWeightInternal = m_fontWeightStack.Remove();
                        return true;
                    case 6380: // <pos=000.00px> <pos=0em> <pos=50%>
                        value = ConvertToFloat(m_htmlTag, m_xmlAttribute[0].valueStartIndex, m_xmlAttribute[0].valueLength, m_xmlAttribute[0].valueDecimalIndex);
                        if (value == -9999) return false;

                        switch (tagUnits)
                        {
                            case TagUnits.Pixels:
                                m_xAdvance = value;
                                //m_isIgnoringAlignment = true;
                                return true;
                            case TagUnits.FontUnits:
                                m_xAdvance = value * m_fontScale * m_fontAsset.fontInfo.TabWidth / m_fontAsset.tabSize;
                                //m_isIgnoringAlignment = true;
                                return true;
                            case TagUnits.Percentage:
                                m_xAdvance = m_marginWidth * value / 100;
                                //m_isIgnoringAlignment = true;
                                return true;
                        }
                        return false;
                    case 22501: // </pos>
                        m_isIgnoringAlignment = false;
                        return true;
                    case 16034505: // <voffset>
                        value = ConvertToFloat(m_htmlTag, m_xmlAttribute[0].valueStartIndex, m_xmlAttribute[0].valueLength, m_xmlAttribute[0].valueDecimalIndex);
                        if (value == -9999 || value == 0) return false;

                        switch (tagUnits)
                        {
                            case TagUnits.Pixels:
                                m_baselineOffset = value;
                                return true;
                            case TagUnits.FontUnits:
                                m_baselineOffset = value * m_fontScale * m_fontAsset.fontInfo.Ascender;
                                return true;
                            case TagUnits.Percentage:
                                //m_baselineOffset = m_marginHeight * val / 100;
                                return false;
                        }
                        return false;
                    case 54741026: // </voffset>
                        m_baselineOffset = 0;
                        return true;
                    case 43991: // <page>
                        // This tag only works when Overflow - Page mode is used.
                        if (m_overflowMode == TextOverflowModes.Page)
                        {
                            m_xAdvance = 0 + tag_LineIndent + tag_Indent;
                            //m_textInfo.lineInfo[m_lineNumber].marginLeft = m_xAdvance;
                            m_lineOffset = 0;
                            m_pageNumber += 1;
                            m_isNewPage = true;
                        }
                        return true;

                    case 43969: // <nobr>
                        m_isNonBreakingSpace = true;
                        return true;
                    case 156816: // </nobr>
                        m_isNonBreakingSpace = false;
                        return true;
                    case 45545: // <size=>
                        value = ConvertToFloat(m_htmlTag, m_xmlAttribute[0].valueStartIndex, m_xmlAttribute[0].valueLength, m_xmlAttribute[0].valueDecimalIndex);
                        if (value == -9999 || value == 0) return false;

                        switch (tagUnits)
                        {
                            case TagUnits.Pixels:
                                if (m_htmlTag[5] == 43) // <size=+00>
                                {
                                    m_currentFontSize = m_fontSize + value;
                                    m_sizeStack.Add(m_currentFontSize);
                                    m_fontScale = (m_currentFontSize / m_currentFontAsset.fontInfo.PointSize * m_currentFontAsset.fontInfo.Scale * (m_isOrthographic ? 1 : 0.1f));
                                    return true;
                                }
                                else if (m_htmlTag[5] == 45) // <size=-00>
                                {
                                    m_currentFontSize = m_fontSize + value;
                                    m_sizeStack.Add(m_currentFontSize);
                                    m_fontScale = (m_currentFontSize / m_currentFontAsset.fontInfo.PointSize * m_currentFontAsset.fontInfo.Scale * (m_isOrthographic ? 1 : 0.1f));
                                    return true;
                                }
                                else // <size=00.0>
                                {
                                    m_currentFontSize = value;
                                    m_sizeStack.Add(m_currentFontSize);
                                    m_fontScale = (m_currentFontSize / m_currentFontAsset.fontInfo.PointSize * m_currentFontAsset.fontInfo.Scale * (m_isOrthographic ? 1 : 0.1f));
                                    return true;
                                }
                            case TagUnits.FontUnits:
                                m_currentFontSize = m_fontSize * value;
                                m_sizeStack.Add(m_currentFontSize);
                                m_fontScale = (m_currentFontSize / m_currentFontAsset.fontInfo.PointSize * m_currentFontAsset.fontInfo.Scale * (m_isOrthographic ? 1 : 0.1f));
                                return true;
                            case TagUnits.Percentage:
                                m_currentFontSize = m_fontSize * value / 100;
                                m_sizeStack.Add(m_currentFontSize);
                                m_fontScale = (m_currentFontSize / m_currentFontAsset.fontInfo.PointSize * m_currentFontAsset.fontInfo.Scale * (m_isOrthographic ? 1 : 0.1f));
                                return true;
                        }
                        return false;
                    case 158392: // </size>
                        m_currentFontSize = m_sizeStack.Remove();
                        m_fontScale = (m_currentFontSize / m_currentFontAsset.fontInfo.PointSize * m_currentFontAsset.fontInfo.Scale * (m_isOrthographic ? 1 : 0.1f));
                        return true;
                    case 41311: // <font=xx>
                        //Debug.Log("Font name: \"" + new string(m_htmlTag, m_xmlAttribute[0].valueStartIndex, m_xmlAttribute[0].valueLength) + "\"   HashCode: " + m_xmlAttribute[0].valueHashCode + "   Material Name: \"" + new string(m_htmlTag, m_xmlAttribute[1].valueStartIndex, m_xmlAttribute[1].valueLength) + "\"   Hashcode: " + m_xmlAttribute[1].valueHashCode);

                        int fontHashCode = m_xmlAttribute[0].valueHashCode;
                        int materialAttributeHashCode = m_xmlAttribute[1].nameHashCode;
                        int materialHashCode = m_xmlAttribute[1].valueHashCode;

                        // Special handling for <font=default> or <font=Default>
                        if (fontHashCode == 764638571 || fontHashCode == 523367755)
                        {
                            m_currentFontAsset = m_materialReferences[0].fontAsset;
                            m_currentMaterial = m_materialReferences[0].material;
                            m_currentMaterialIndex = 0;
                            //Debug.Log("<font=Default> assigning Font Asset [" + m_currentFontAsset.name + "] with Material [" + m_currentMaterial.name + "].");

                            m_fontScale = (m_currentFontSize / m_currentFontAsset.fontInfo.PointSize * m_currentFontAsset.fontInfo.Scale * (m_isOrthographic ? 1 : 0.1f));

                            m_materialReferenceStack.Add(m_materialReferences[0]);

                            return true;
                        }

                        TMP_FontAsset tempFont;
                        Material tempMaterial;

                        // HANDLE NEW FONT ASSET
                        if (MaterialReferenceManager.TryGetFontAsset(fontHashCode, out tempFont))
                        {
                            //if (tempFont != m_currentFontAsset)
                            //{
                            //    //Debug.Log("Assigning Font Asset: " + tempFont.name);
                            //    m_currentFontAsset = tempFont;
                            //    m_fontScale = (m_currentFontSize / m_currentFontAsset.fontInfo.PointSize * m_currentFontAsset.fontInfo.Scale * (m_isOrthographic ? 1 : 0.1f));
                            //}
                        }
                        else
                        {
                            // Load Font Asset
                            tempFont = Resources.Load<TMP_FontAsset>("Fonts & Materials/" + new string(m_htmlTag, m_xmlAttribute[0].valueStartIndex, m_xmlAttribute[0].valueLength));

                            if (tempFont == null)
                                return false;

                            // Add new reference to the font asset as well as default material to the MaterialReferenceManager
                            MaterialReferenceManager.AddFontAsset(tempFont);
                        }

                        // HANDLE NEW MATERIAL
                        if (materialAttributeHashCode == 0 && materialHashCode == 0)
                        {
                            // No material specified then use default font asset material.
                            m_currentMaterial = tempFont.material;

                            m_currentMaterialIndex = MaterialReference.AddMaterialReference(m_currentMaterial, tempFont, m_materialReferences, m_materialReferenceIndexLookup);

                            m_materialReferenceStack.Add(m_materialReferences[m_currentMaterialIndex]);
                        }
                        else if (materialAttributeHashCode == 103415287) // using material attribute
                        {
                            if (MaterialReferenceManager.TryGetMaterial(materialHashCode, out tempMaterial))
                            {
                                m_currentMaterial = tempMaterial;

                                m_currentMaterialIndex = MaterialReference.AddMaterialReference(m_currentMaterial, tempFont, m_materialReferences, m_materialReferenceIndexLookup);

                                m_materialReferenceStack.Add(m_materialReferences[m_currentMaterialIndex]);
                            }
                            else
                            {
                                // Load new material
                                tempMaterial = Resources.Load<Material>("Fonts & Materials/" + new string(m_htmlTag, m_xmlAttribute[1].valueStartIndex, m_xmlAttribute[1].valueLength));

                                if (tempMaterial == null)
                                    return false;

                                // Add new reference to this material in the MaterialReferenceManager
                                MaterialReferenceManager.AddFontMaterial(materialHashCode, tempMaterial);

                                m_currentMaterial = tempMaterial;

                                m_currentMaterialIndex = MaterialReference.AddMaterialReference(m_currentMaterial, tempFont, m_materialReferences, m_materialReferenceIndexLookup);

                                m_materialReferenceStack.Add(m_materialReferences[m_currentMaterialIndex]);
                            }
                        }
                        else
                            return false;

                        m_currentFontAsset = tempFont;
                        m_fontScale = (m_currentFontSize / m_currentFontAsset.fontInfo.PointSize * m_currentFontAsset.fontInfo.Scale * (m_isOrthographic ? 1 : 0.1f));

                        return true;
                    case 154158: // </font>
                        MaterialReference materialReference = m_materialReferenceStack.Remove();

                        m_currentFontAsset = materialReference.fontAsset;
                        m_currentMaterial = materialReference.material;
                        m_currentMaterialIndex = materialReference.index;

                        m_fontScale = (m_currentFontSize / m_currentFontAsset.fontInfo.PointSize * m_currentFontAsset.fontInfo.Scale * (m_isOrthographic ? 1 : 0.1f));

                        return true;
                    case 320078: // <space=000.00>
                        value = ConvertToFloat(m_htmlTag, m_xmlAttribute[0].valueStartIndex, m_xmlAttribute[0].valueLength, m_xmlAttribute[0].valueDecimalIndex);
                        if (value == -9999 || value == 0) return false;

                        switch (tagUnits)
                        {
                            case TagUnits.Pixels:
                                m_xAdvance += value;
                                return true;
                            case TagUnits.FontUnits:
                                m_xAdvance += value * m_fontScale * m_fontAsset.fontInfo.TabWidth / m_fontAsset.tabSize;
                                return true;
                            case TagUnits.Percentage:
                                // Not applicable
                                return false;
                        }
                        return false;
                    case 276254: // <alpha=#FF>
                        if (m_xmlAttribute[0].valueLength != 3) return false;

                        m_htmlColor.a = (byte)(HexToInt(m_htmlTag[7]) * 16 + HexToInt(m_htmlTag[8]));
                        return true;

                    case 1750458: // <a name=" ">
                        return false;
                    case 426: // </a>
                        return true;
                    case 43066: // <link="name">
                        if (m_isParsingText)
                        {
                            tag_LinkInfo.textComponent = this;
                            tag_LinkInfo.hashCode = m_xmlAttribute[0].valueHashCode;
                            tag_LinkInfo.linkTextfirstCharacterIndex = m_characterCount;

                            tag_LinkInfo.linkIdFirstCharacterIndex = startIndex + m_xmlAttribute[0].valueStartIndex;
                            tag_LinkInfo.linkIdLength = m_xmlAttribute[0].valueLength;

                        }
                        return true;
                    case 155913: // </link>
                        if (m_isParsingText)
                        {
                            tag_LinkInfo.linkTextLength = m_characterCount - tag_LinkInfo.linkTextfirstCharacterIndex;

                            int size = m_textInfo.linkInfo.Length;

                            if (m_textInfo.linkCount + 1 > size)
                                TMP_TextInfo.Resize(ref m_textInfo.linkInfo, size + 1);

                            m_textInfo.linkInfo[m_textInfo.linkCount] = tag_LinkInfo;

                            m_textInfo.linkCount += 1;

                        }
                        return true;
                    case 275917: // <align=>
                        switch (m_xmlAttribute[0].valueHashCode)
                        {
                            case 3774683: // <align=left>
                                m_lineJustification = TextAlignmentOptions.Left;
                                return true;
                            case 136703040: // <align=right>
                                m_lineJustification = TextAlignmentOptions.Right;
                                return true;
                            case -458210101: // <align=center>
                                m_lineJustification = TextAlignmentOptions.Center;
                                return true;
                            case -523808257: // <align=justified>
                                m_lineJustification = TextAlignmentOptions.Justified;
                                return true;
                        }
                        return false;
                    case 1065846: // </align>
                        m_lineJustification = m_textAlignment;
                        return true;
                    case 327550: // <width=xx>
                        value = ConvertToFloat(m_htmlTag, m_xmlAttribute[0].valueStartIndex, m_xmlAttribute[0].valueLength, m_xmlAttribute[0].valueDecimalIndex);
                        if (value == -9999 || value == 0) return false;

                        switch (tagUnits)
                        {
                            case TagUnits.Pixels:
                                m_width = value;
                                break;
                            case TagUnits.FontUnits:
                                return false;
                            //break;
                            case TagUnits.Percentage:
                                m_width = m_marginWidth * value / 100;
                                break;
                        }
                        return true;
                    case 1117479: // </width>
                        m_width = -1;
                        return true;
                    case 322689: // <style="name">
                        TMP_Style style = TMP_StyleSheet.Instance.GetStyle(m_xmlAttribute[0].valueHashCode);

                        if (style == null) return false;

                        m_styleStack.Add(style.hashCode);

                        //// Parse Style Macro
                        for (int i = 0; i < style.styleOpeningTagArray.Length; i++)
                        {
                            if (style.styleOpeningTagArray[i] == 60)
                                ValidateHtmlTag(style.styleOpeningTagArray, i + 1, out i);
                        }
                        return true;
                    case 1112618: // </style>
                        style = TMP_StyleSheet.Instance.GetStyle(m_xmlAttribute[0].valueHashCode);

                        if (style == null)
                        {
                            // Get style from the Style Stack
                            int styleHashCode = m_styleStack.Remove();
                            style = TMP_StyleSheet.Instance.GetStyle(styleHashCode);
                        }

                        if (style == null) return false;
                        //// Parse Style Macro
                        for (int i = 0; i < style.styleClosingTagArray.Length; i++)
                        {
                            if (style.styleClosingTagArray[i] == 60)
                                ValidateHtmlTag(style.styleClosingTagArray, i + 1, out i);
                        }
                        return true;
                    case 281955: // <color=#FF00FF> or <color=#FF00FF00>
                        // <color=#FF00FF> 3 Hex pairs
                        if (m_htmlTag[6] == 35 && tagCharCount == 13)
                        {
                            m_htmlColor = HexCharsToColor(m_htmlTag, tagCharCount);
                            m_colorStack.Add(m_htmlColor);
                            return true;
                        }
                        // <color=#FF00FF00> 4 Hex pairs
                        else if (m_htmlTag[6] == 35 && tagCharCount == 15)
                        {
                            m_htmlColor = HexCharsToColor(m_htmlTag, tagCharCount);
                            m_colorStack.Add(m_htmlColor);
                            return true;
                        }

                        // <color=name>
                        switch (m_xmlAttribute[0].valueHashCode)
                        {
                            case 125395: // <color=red>
                                m_htmlColor = Color.red;
                                m_colorStack.Add(m_htmlColor);
                                return true;
                            case 3573310: // <color=blue>
                                m_htmlColor = Color.blue;
                                m_colorStack.Add(m_htmlColor);
                                return true;
                            case 117905991: // <color=black>
                                m_htmlColor = Color.black;
                                m_colorStack.Add(m_htmlColor);
                                return true;
                            case 121463835: // <color=green>
                                m_htmlColor = Color.green;
                                m_colorStack.Add(m_htmlColor);
                                return true;
                            case 140357351: // <color=white>
                                m_htmlColor = Color.white;
                                m_colorStack.Add(m_htmlColor);
                                return true;
                            case 26556144: // <color=orange>
                                m_htmlColor = new Color32(255, 128, 0, 255);
                                m_colorStack.Add(m_htmlColor);
                                return true;
                            case -36881330: // <color=purple>
                                m_htmlColor = new Color32(160, 32, 240, 255);
                                m_colorStack.Add(m_htmlColor);
                                return true;
                            case 554054276: // <color=yellow>
                                m_htmlColor = Color.yellow;
                                m_colorStack.Add(m_htmlColor);
                                return true;
                        }
                        return false;
                    case 1983971: // <cspace=xx.x>
                        value = ConvertToFloat(m_htmlTag, m_xmlAttribute[0].valueStartIndex, m_xmlAttribute[0].valueLength, m_xmlAttribute[0].valueDecimalIndex);
                        if (value == -9999 || value == 0) return false;

                        switch (tagUnits)
                        {
                            case TagUnits.Pixels:
                                m_cSpacing = value;
                                break;
                            case TagUnits.FontUnits:
                                m_cSpacing = value;
                                m_cSpacing *= m_fontScale * m_fontAsset.fontInfo.TabWidth / m_fontAsset.tabSize;
                                break;
                            case TagUnits.Percentage:
                                return false;
                        }
                        return true;
                    case 7513474: // </cspace>
                        m_cSpacing = 0;
                        return true;
                    case 2152041: // <mspace=xx.x>
                        value = ConvertToFloat(m_htmlTag, m_xmlAttribute[0].valueStartIndex, m_xmlAttribute[0].valueLength, m_xmlAttribute[0].valueDecimalIndex);
                        if (value == -9999 || value == 0) return false;

                        switch (tagUnits)
                        {
                            case TagUnits.Pixels:
                                m_monoSpacing = value;
                                break;
                            case TagUnits.FontUnits:
                                m_monoSpacing = value;
                                m_monoSpacing *= m_fontScale * m_fontAsset.fontInfo.TabWidth / m_fontAsset.tabSize;
                                break;
                            case TagUnits.Percentage:
                                return false;
                        }
                        return true;
                    case 7681544: // </mspace>
                        m_monoSpacing = 0;
                        return true;
                    case 280416: // <class="name">
                        return false;
                    case 1071884: // </color>
                        m_htmlColor = m_colorStack.Remove();
                        return true;
                    case 2068980: // <indent=10px> <indent=10em> <indent=50%>
                        value = ConvertToFloat(m_htmlTag, m_xmlAttribute[0].valueStartIndex, m_xmlAttribute[0].valueLength, m_xmlAttribute[0].valueDecimalIndex);
                        if (value == -9999 || value == 0) return false;

                        switch (tagUnits)
                        {
                            case TagUnits.Pixels:
                                tag_Indent = value;
                                break;
                            case TagUnits.FontUnits:
                                tag_Indent = value;
                                tag_Indent *= m_fontScale * m_fontAsset.fontInfo.TabWidth / m_fontAsset.tabSize;
                                break;
                            case TagUnits.Percentage:
                                tag_Indent = m_marginWidth * value / 100;
                                break;
                        }
                        m_indentStack.Add(tag_Indent);

                        m_xAdvance = tag_Indent;
                        return true;
                    case 7598483: // </indent>
                        tag_Indent = m_indentStack.Remove();
                        //m_xAdvance = tag_Indent;
                        return true;
                    case 1109386397: // <line-indent>
                        value = ConvertToFloat(m_htmlTag, m_xmlAttribute[0].valueStartIndex, m_xmlAttribute[0].valueLength, m_xmlAttribute[0].valueDecimalIndex);
                        if (value == -9999 || value == 0) return false;

                        switch (tagUnits)
                        {
                            case TagUnits.Pixels:
                                tag_LineIndent = value;
                                break;
                            case TagUnits.FontUnits:
                                tag_LineIndent = value;
                                tag_LineIndent *= m_fontScale * m_fontAsset.fontInfo.TabWidth / m_fontAsset.tabSize;
                                break;
                            case TagUnits.Percentage:
                                tag_LineIndent = m_marginWidth * value / 100;
                                break;
                        }

                        m_xAdvance += tag_LineIndent;
                        return true;
                    case -445537194: // </line-indent>
                        tag_LineIndent = 0;
                        return true;
                    case 2246877: // <sprite=x>
                        int spriteAssetHashCode = m_xmlAttribute[0].valueHashCode;
                        TMP_SpriteAsset tempSpriteAsset;

                        // CHECK TAG FORMAT
                        if (m_xmlAttribute[0].valueType == TagType.None || m_xmlAttribute[0].valueType == TagType.NumericalValue)
                        {
                            // No Sprite Asset specified
                            if (m_defaultSpriteAsset == null)
                            {
                                // Load TMP Settings
                                if (m_settings == null) m_settings = TMP_Settings.LoadDefaultSettings();

                                if (m_settings != null && m_settings.spriteAsset != null)
                                    m_defaultSpriteAsset = m_settings.spriteAsset;
                                else
                                    m_defaultSpriteAsset = Resources.Load<TMP_SpriteAsset>("Sprite Assets/Default Sprite Asset");

                            }

                            m_currentSpriteAsset = m_defaultSpriteAsset;

                            // No valid sprite asset available
                            if (m_currentSpriteAsset == null)
                                return false;
                        }
                        else
                        {
                            // A Sprite Asset has been specified
                            if (MaterialReferenceManager.TryGetSpriteAsset(spriteAssetHashCode, out tempSpriteAsset))
                            {
                                m_currentSpriteAsset = tempSpriteAsset;
                            }
                            else
                            {
                                // Load Sprite Asset
                                if (tempSpriteAsset == null)
                                {
                                    tempSpriteAsset = Resources.Load<TMP_SpriteAsset>("Sprites/" + new string(m_htmlTag, m_xmlAttribute[0].valueStartIndex, m_xmlAttribute[0].valueLength));
                                }

                                if (tempSpriteAsset == null)
                                    return false;

                                //Debug.Log("Loading & assigning new Sprite Asset: " + tempSpriteAsset.name);
                                MaterialReferenceManager.AddSpriteAsset(spriteAssetHashCode, tempSpriteAsset);
                                m_currentSpriteAsset = tempSpriteAsset;
                            }
                        }

                        if (m_xmlAttribute[0].valueType == TagType.NumericalValue)
                        {
                            int index = (int)ConvertToFloat(m_htmlTag, m_xmlAttribute[0].valueStartIndex, m_xmlAttribute[0].valueLength, m_xmlAttribute[0].valueDecimalIndex);
                            if (index == -9999) return false;

                            m_spriteIndex = index;
                        }
                        else if (m_xmlAttribute[1].nameHashCode == 43347) // <sprite name="">
                        {
                            //Debug.Log("Name attribute [" + new string(m_htmlTag, m_xmlAttribute[1].valueStartIndex, m_xmlAttribute[1].valueLength) + "].");

                            int index = m_currentSpriteAsset.GetSpriteIndex(m_xmlAttribute[1].valueHashCode);
                            if (index == -1) return false;

                            m_spriteIndex = index;

                        }
                        else if (m_xmlAttribute[1].nameHashCode == 295562) // <sprite index=xx>
                        {
                            int index = (int)ConvertToFloat(m_htmlTag, m_xmlAttribute[1].valueStartIndex, m_xmlAttribute[1].valueLength, m_xmlAttribute[1].valueDecimalIndex);
                            if (index == -9999) return false;

                            m_spriteIndex = index;

                            // Check to make sure sprite index is valid
                            if (m_spriteIndex > m_currentSpriteAsset.spriteInfoList.Count - 1) return false;
                        }
                        else
                        {
                            return false;
                        }

                        // Material HashCode for the Sprite Asset is the Sprite Asset Hash Code
                        m_currentMaterialIndex = MaterialReference.AddMaterialReference(m_currentSpriteAsset.material, m_currentSpriteAsset, m_materialReferences, m_materialReferenceIndexLookup);

                        //m_materialReferenceStack.Add(m_materialReferenceManager.materialReferences[m_currentMaterialIndex]);

                        m_spriteColor = s_colorWhite;
                        m_tintSprite = false;

                        // Handle Tint Attribute
                        if (m_xmlAttribute[1].nameHashCode == 45819)
                            m_tintSprite = ConvertToFloat(m_htmlTag, m_xmlAttribute[1].valueStartIndex, m_xmlAttribute[1].valueLength, m_xmlAttribute[1].valueDecimalIndex) != 0;
                        else if (m_xmlAttribute[2].nameHashCode == 45819)
                            m_tintSprite = ConvertToFloat(m_htmlTag, m_xmlAttribute[2].valueStartIndex, m_xmlAttribute[2].valueLength, m_xmlAttribute[2].valueDecimalIndex) != 0;

                        // Handle Color Attribute
                        if (m_xmlAttribute[1].nameHashCode == 281955)
                            m_spriteColor = HexCharsToColor(m_htmlTag, m_xmlAttribute[1].valueStartIndex, m_xmlAttribute[1].valueLength);
                        else if (m_xmlAttribute[2].nameHashCode == 281955)
                            m_spriteColor = HexCharsToColor(m_htmlTag, m_xmlAttribute[2].valueStartIndex, m_xmlAttribute[2].valueLength);

                        m_xmlAttribute[1].nameHashCode = 0;
                        m_xmlAttribute[2].nameHashCode = 0;

                        m_textElementType = TMP_TextElementType.Sprite;
                        return true;
                    case 730022849: // <lowercase>
                        m_style |= FontStyles.LowerCase;
                        return true;
                    case -1668324918: // </lowercase>
                        m_style &= ~FontStyles.LowerCase;
                        return true;
                    case 13526026: // <allcaps>
                    case 781906058: // <uppercase>
                        m_style |= FontStyles.UpperCase;
                        return true;
                    case 52232547: // </allcaps>
                    case -1616441709: // </uppercase>
                        m_style &= ~FontStyles.UpperCase;
                        return true;
                    case 766244328: // <smallcaps>
                        m_style |= FontStyles.SmallCaps;
                        return true;
                    case -1632103439: // </smallcaps>
                        m_style &= ~FontStyles.SmallCaps;
                        return true;
                    case 2109854: // <margin=00.0> <margin=00em> <margin=50%>
                        value = ConvertToFloat(m_htmlTag, m_xmlAttribute[0].valueStartIndex, m_xmlAttribute[0].valueLength, m_xmlAttribute[0].valueDecimalIndex); // px
                        if (value == -9999 || value == 0) return false;

                        m_marginLeft = value;
                        switch (tagUnits)
                        {
                            case TagUnits.Pixels:
                                // Default behavior
                                break;
                            case TagUnits.FontUnits:
                                m_marginLeft *= m_fontScale * m_fontAsset.fontInfo.TabWidth / m_fontAsset.tabSize;
                                break;
                            case TagUnits.Percentage:
                                m_marginLeft = (m_marginWidth - (m_width != -1 ? m_width : 0)) * m_marginLeft / 100;
                                break;
                        }
                        m_marginLeft = m_marginLeft >= 0 ? m_marginLeft : 0;
                        m_marginRight = m_marginLeft;
                        return true;
                    case 7639357: // </margin>
                        m_marginLeft = 0;
                        m_marginRight = 0;
                        return true;
                    case 1100728678: // <margin-left=xx.x>
                        value = ConvertToFloat(m_htmlTag, m_xmlAttribute[0].valueStartIndex, m_xmlAttribute[0].valueLength, m_xmlAttribute[0].valueDecimalIndex); // px
                        if (value == -9999 || value == 0) return false;

                        m_marginLeft = value;
                        switch (tagUnits)
                        {
                            case TagUnits.Pixels:
                                // Default behavior
                                break;
                            case TagUnits.FontUnits:
                                m_marginLeft *= m_fontScale * m_fontAsset.fontInfo.TabWidth / m_fontAsset.tabSize;
                                break;
                            case TagUnits.Percentage:
                                m_marginLeft = (m_marginWidth - (m_width != -1 ? m_width : 0)) * m_marginLeft / 100;
                                break;
                        }
                        m_marginLeft = m_marginLeft >= 0 ? m_marginLeft : 0;
                        return true;
                    case -884817987: // <margin-right=xx.x>
                        value = ConvertToFloat(m_htmlTag, m_xmlAttribute[0].valueStartIndex, m_xmlAttribute[0].valueLength, m_xmlAttribute[0].valueDecimalIndex); // px
                        if (value == -9999 || value == 0) return false;

                        m_marginRight = value;
                        switch (tagUnits)
                        {
                            case TagUnits.Pixels:
                                // Default behavior
                                break;
                            case TagUnits.FontUnits:
                                m_marginRight *= m_fontScale * m_fontAsset.fontInfo.TabWidth / m_fontAsset.tabSize;
                                break;
                            case TagUnits.Percentage:
                                m_marginRight = (m_marginWidth - (m_width != -1 ? m_width : 0)) * m_marginRight / 100;
                                break;
                        }
                        m_marginRight = m_marginRight >= 0 ? m_marginRight : 0;
                        return true;
                    case 1109349752: // <line-height=xx.x>
                        value = ConvertToFloat(m_htmlTag, m_xmlAttribute[0].valueStartIndex, m_xmlAttribute[0].valueLength, m_xmlAttribute[0].valueDecimalIndex);
                        if (value == -9999 || value == 0) return false;

                        m_lineHeight = value;
                        switch (tagUnits)
                        {
                            case TagUnits.Pixels:
                                //m_lineHeight *= m_isOrthographic ? 1 : 0.1f;
                                break;
                            case TagUnits.FontUnits:
                                m_lineHeight *= m_fontAsset.fontInfo.LineHeight * m_fontScale;
                                break;
                            case TagUnits.Percentage:
                                m_lineHeight = m_fontAsset.fontInfo.LineHeight * m_lineHeight / 100 * m_fontScale;
                                break;
                        }
                        return true;
                    case -445573839: // </line-height>
                        m_lineHeight = 0;
                        return true;
                    case 15115642: // <noparse>
                        tag_NoParsing = true;
                        return true;
                    case 1913798: // <action>
                        // TODO
                        return false;
                    case 7443301: // </action>
                        // TODO
                        return false;
                }
            }
            return false;
        }
Example #28
0
 public static bool TryGetSpriteAsset(int hashCode, out TMP_SpriteAsset spriteAsset)
 {
     return(instance.TryGetSpriteAssetInternal(hashCode, out spriteAsset));
 }
 /// <summary>
 /// Function returning the Sprite Asset corresponding to the provided hash code.
 /// </summary>
 /// <param name="hashCode"></param>
 /// <param name="spriteAsset"></param>
 /// <returns></returns>
 public static bool TryGetSpriteAsset(int hashCode, out TMP_SpriteAsset spriteAsset)
 {
     return(MaterialReferenceManager.instance.TryGetSpriteAssetInternal(hashCode, out spriteAsset));
 }
Example #30
0
 public static void AddSpriteAsset(TMP_SpriteAsset spriteAsset)
 {
     instance.AddSpriteAssetInternal(spriteAsset);
 }
 /// <summary>
 /// Add new Sprite Asset to dictionary.
 /// </summary>
 /// <param name="hashCode"></param>
 /// <param name="spriteAsset"></param>
 public static void AddSpriteAsset(int hashCode, TMP_SpriteAsset spriteAsset)
 {
     MaterialReferenceManager.instance.AddSpriteAssetInternal(hashCode, spriteAsset);
 }
Example #32
0
 public static void AddSpriteAsset(int hashCode, TMP_SpriteAsset spriteAsset)
 {
     instance.AddSpriteAssetInternal(hashCode, spriteAsset);
 }
Example #33
0
        private void LoadSpriteAsset(TMP_SpriteAsset spriteAsset)
        {

            if (spriteAsset == null)
            {
                // Load Default SpriteAsset
                TMP_Settings settings = Resources.Load("TMP Settings") as TMP_Settings;
                if (settings != null && settings.spriteAsset != null)
                    spriteAsset = settings.spriteAsset;
                else
                    spriteAsset = Resources.Load("Sprite Assets/Default Sprite Asset") as TMP_SpriteAsset;


            }

            m_spriteAsset = spriteAsset;
            m_inlineGraphic.texture = m_spriteAsset.spriteSheet;

            if (m_textComponent != null && m_isInitialized)
            {
                m_textComponent.havePropertiesChanged = true;
                m_textComponent.SetVerticesDirty();
            }

        }
Example #34
0
 public bool Contains(TMP_SpriteAsset sprite)
 {
     return(this.m_FontAssetReferenceLookup.ContainsKey(sprite.hashCode));
 }