Exemplo n.º 1
0
    void Convert()
    {
        int length = text.Length;

        Color[] colors = new Color[length];

        rectMap            = new Texture2D(length, 1, TextureFormat.RGBAFloat, false);
        rectMap.filterMode = FilterMode.Point;
        rectMap.wrapMode   = TextureWrapMode.Repeat;

        effect.SetTexture("rectMap", rectMap);
        effect.SetInt("length", length);

        float w = font.atlasWidth, h = font.atlasHeight;

        for (int i = 0; i < length; i++)
        {
            char      c     = text[i];
            uint      id    = font.characterLookupTable[c].glyphIndex;
            GlyphRect glyph = font.glyphLookupTable[id].glyphRect;

            colors[i].r = glyph.x / w;
            colors[i].g = glyph.y / h;
            colors[i].b = glyph.width / w;
            colors[i].a = glyph.height / h;
        }

        rectMap.SetPixels(colors);
        rectMap.Apply();
    }
        internal static BlobAssetReference <FontData> ConvertFontData(TMPro.TMP_FontAsset font, Allocator allocatorType = Allocator.Persistent)
        {
            if (font.glyphLookupTable == null)
            {
                throw new InvalidOperationException("Reading font resulted in null glyph lookup table?");
            }

            using (var allocator = new BlobBuilder(Allocator.Temp))
            {
                ref var root = ref allocator.ConstructRoot <FontData>();

                root.Atlas.AtlasSize = new int2(font.atlasWidth, font.atlasHeight);

                root.Face.Ascent     = font.faceInfo.ascentLine;
                root.Face.Descent    = font.faceInfo.descentLine;
                root.Face.Baseline   = font.faceInfo.baseline;
                root.Face.Scale      = font.faceInfo.scale;
                root.Face.PointSize  = font.faceInfo.pointSize;
                root.Face.LineHeight = font.faceInfo.lineHeight;

                // TODO we are smooshing chars and glyphs; multiple chars can map to
                // the same glyph.  This might not be the best thing.
                int charCount = font.characterTable.Count;

                var glyphs = allocator.Allocate(ref root.Glyphs, charCount);

                // TODO why did I want a separate glyphRects?
                var glyphRects = allocator.Allocate(ref root.GlyphRects, charCount);

                var atlasSize = new float2(font.atlasWidth, font.atlasHeight);

                for (int i = 0; i < charCount; ++i)
                {
                    var c = font.characterTable[i];

                    glyphs[i] = new GlyphInfo
                    {
                        Unicode           = c.unicode,
                        Size              = new float2(c.glyph.metrics.width, c.glyph.metrics.height),
                        HorizontalBearing = new float2(c.glyph.metrics.horizontalBearingX, c.glyph.metrics.horizontalBearingY),
                        HorizontalAdvance = c.glyph.metrics.horizontalAdvance
                    };

                    // UVs in Tiny rendering are flipped from Unity's orientation.
                    // glyphPos is the top-left coord.
                    int2 glyphPos  = new int2(c.glyph.glyphRect.x, font.atlasHeight - (c.glyph.glyphRect.y + c.glyph.glyphRect.height));
                    int2 glyphSize = new int2(c.glyph.glyphRect.width, c.glyph.glyphRect.height);

                    glyphRects[i] = new GlyphRect
                    {
                        Position      = glyphPos,
                        Size          = glyphSize,
                        TopLeftUV     = glyphPos / atlasSize,
                        BottomRightUV = (glyphPos + glyphSize) / atlasSize,
                    };
                }

                return(allocator.CreateBlobAssetReference <FontData>(allocatorType));
            }
Exemplo n.º 3
0
 /// <summary>
 /// Constructor for new sprite glyph.
 /// </summary>
 /// <param name="index">Index of the sprite glyph.</param>
 /// <param name="metrics">Metrics which define the position of the glyph in the context of text layout.</param>
 /// <param name="glyphRect">GlyphRect which defines the coordinates of the glyph in the atlas texture.</param>
 /// <param name="scale">Scale of the glyph.</param>
 /// <param name="atlasIndex">Index of the atlas texture that contains the glyph.</param>
 public TMP_SpriteGlyph(uint index, GlyphMetrics metrics, GlyphRect glyphRect, float scale, int atlasIndex)
 {
     this.index      = index;
     this.metrics    = metrics;
     this.glyphRect  = glyphRect;
     this.scale      = scale;
     this.atlasIndex = atlasIndex;
 }
 public GlyphMarshallingStruct(uint index, GlyphMetrics metrics, GlyphRect glyphRect, float scale, int atlasIndex)
 {
     this.index      = index;
     this.metrics    = metrics;
     this.glyphRect  = glyphRect;
     this.scale      = scale;
     this.atlasIndex = atlasIndex;
 }
 public GlyphMarshallingStruct(Glyph glyph)
 {
     this.index      = glyph.index;
     this.metrics    = glyph.metrics;
     this.glyphRect  = glyph.glyphRect;
     this.scale      = glyph.scale;
     this.atlasIndex = glyph.atlasIndex;
 }
 /// <summary>
 /// Constructor for new glyph
 /// </summary>
 /// <param name="index">The index of the glyph in the font file.</param>
 /// <param name="metrics">The metrics of the glyph.</param>
 /// <param name="glyphRect">A rectangle defining the position of the glyph in the atlas texture.</param>
 /// <param name="scale">The relative scale of the glyph.</param>
 /// <param name="atlasIndex">The index of the atlas texture that contains the glyph.</param>
 /// <param name="classDefinitionType">Class definition type for the glyph.</param>
 public GlyphMarshallingStruct(uint index, GlyphMetrics metrics, GlyphRect glyphRect, float scale, int atlasIndex, GlyphClassDefinitionType classDefinitionType)
 {
     this.index               = index;
     this.metrics             = metrics;
     this.glyphRect           = glyphRect;
     this.scale               = scale;
     this.atlasIndex          = atlasIndex;
     this.classDefinitionType = classDefinitionType;
 }
Exemplo n.º 7
0
        void DrawGlyph(uint glyphIndex, Rect position, SerializedProperty property)
        {
            // Get a reference to the sprite texture
            TMP_FontAsset fontAsset = property.serializedObject.targetObject as TMP_FontAsset;

            if (fontAsset == null)
            {
                return;
            }

            // Check if glyph currently exists in the atlas texture.
            if (!fontAsset.glyphLookupTable.TryGetValue(glyphIndex, out Glyph glyph))
            {
                return;
            }

            // Get reference to atlas texture.
            int       atlasIndex   = fontAsset.m_AtlasTextureIndex;
            Texture2D atlasTexture = fontAsset.atlasTextures.Length > atlasIndex ? fontAsset.atlasTextures[atlasIndex] : null;

            if (atlasTexture == null)
            {
                return;
            }

            Material mat;

            if (((GlyphRasterModes)fontAsset.atlasRenderMode & GlyphRasterModes.RASTER_MODE_BITMAP) == GlyphRasterModes.RASTER_MODE_BITMAP)
            {
                mat = TMP_FontAssetEditor.internalBitmapMaterial;

                if (mat == null)
                {
                    return;
                }

                mat.mainTexture = atlasTexture;
            }
            else
            {
                mat = TMP_FontAssetEditor.internalSDFMaterial;

                if (mat == null)
                {
                    return;
                }

                mat.mainTexture = atlasTexture;
                mat.SetFloat(ShaderUtilities.ID_GradientScale, fontAsset.atlasPadding + 1);
            }

            // Draw glyph from atlas texture.
            Rect glyphDrawPosition = new Rect(position.x, position.y + 2, 64, 60);

            GlyphRect glyphRect = glyph.glyphRect;

            float normalizedHeight = fontAsset.faceInfo.ascentLine - fontAsset.faceInfo.descentLine;
            float scale            = glyphDrawPosition.width / normalizedHeight;

            // Compute the normalized texture coordinates
            Rect texCoords = new Rect((float)glyphRect.x / atlasTexture.width, (float)glyphRect.y / atlasTexture.height, (float)glyphRect.width / atlasTexture.width, (float)glyphRect.height / atlasTexture.height);

            if (Event.current.type == EventType.Repaint)
            {
                glyphDrawPosition.x     += (glyphDrawPosition.width - glyphRect.width * scale) / 2;
                glyphDrawPosition.y     += (glyphDrawPosition.height - glyphRect.height * scale) / 2;
                glyphDrawPosition.width  = glyphRect.width * scale;
                glyphDrawPosition.height = glyphRect.height * scale;

                // Could switch to using the default material of the font asset which would require passing scale to the shader.
                Graphics.DrawTexture(glyphDrawPosition, atlasTexture, texCoords, 0, 0, 0, 0, new Color(1f, 1f, 1f), mat);
            }
        }
Exemplo n.º 8
0
        void DrawGlyph(uint glyphIndex, Rect position, SerializedProperty property)
        {
            // Get a reference to the serialized object which can either be a TMP_FontAsset or FontAsset.
            SerializedObject so = property.serializedObject;

            if (so == null)
            {
                return;
            }

            if (m_GlyphLookupDictionary == null)
            {
                m_GlyphLookupDictionary = new Dictionary <uint, GlyphProxy>();
                FontAssetEditorUtilities.PopulateGlyphProxyLookupDictionary(so, m_GlyphLookupDictionary);
            }

            // Try getting a reference to the glyph for the given glyph index.
            if (!m_GlyphLookupDictionary.TryGetValue(glyphIndex, out GlyphProxy glyph))
            {
                return;
            }

            // Get the atlas index of the glyph and lookup its atlas texture
            SerializedProperty atlasTextureProperty = so.FindProperty("m_AtlasTextures");
            Texture2D          atlasTexture         = atlasTextureProperty.GetArrayElementAtIndex(glyph.atlasIndex).objectReferenceValue as Texture2D;

            if (atlasTexture == null)
            {
                return;
            }

            Material mat;

            GlyphRenderMode atlasRenderMode = (GlyphRenderMode)so.FindProperty("m_AtlasRenderMode").intValue;
            int             padding         = so.FindProperty("m_AtlasPadding").intValue;

            if (((GlyphRasterModes)atlasRenderMode & GlyphRasterModes.RASTER_MODE_BITMAP) == GlyphRasterModes.RASTER_MODE_BITMAP)
            {
                mat = FontAssetEditor.internalBitmapMaterial;

                if (mat == null)
                {
                    return;
                }

                mat.mainTexture = atlasTexture;
            }
            else
            {
                mat = FontAssetEditor.internalSDFMaterial;

                if (mat == null)
                {
                    return;
                }

                mat.mainTexture = atlasTexture;
                mat.SetFloat(TextShaderUtilities.ID_GradientScale, padding + 1);
            }

            // Draw glyph from atlas texture.
            Rect glyphDrawPosition = new Rect(position.x, position.y + 2, position.width, position.height);

            GlyphRect glyphRect    = glyph.glyphRect;
            int       glyphOriginX = glyphRect.x - padding;
            int       glyphOriginY = glyphRect.y - padding;
            int       glyphWidth   = glyphRect.width + padding * 2;
            int       glyphHeight  = glyphRect.height + padding * 2;

            SerializedProperty faceInfoProperty = so.FindProperty("m_FaceInfo");
            float ascentLine  = faceInfoProperty.FindPropertyRelative("m_AscentLine").floatValue;
            float descentLine = faceInfoProperty.FindPropertyRelative("m_DescentLine").floatValue;

            float normalizedHeight = ascentLine - descentLine;
            float scale            = glyphDrawPosition.width / normalizedHeight;

            // Compute the normalized texture coordinates
            Rect texCoords = new Rect((float)glyphOriginX / atlasTexture.width, (float)glyphOriginY / atlasTexture.height, (float)glyphWidth / atlasTexture.width, (float)glyphHeight / atlasTexture.height);

            if (Event.current.type == EventType.Repaint)
            {
                glyphDrawPosition.x     += -(glyphWidth * scale / 2 - padding * scale);
                glyphDrawPosition.y     += glyphDrawPosition.height - glyph.metrics.horizontalBearingY * scale;
                glyphDrawPosition.width  = glyphWidth * scale;
                glyphDrawPosition.height = glyphHeight * scale;

                // Could switch to using the default material of the font asset which would require passing scale to the shader.
                Graphics.DrawTexture(glyphDrawPosition, atlasTexture, texCoords, 0, 0, 0, 0, new Color(1f, 1f, 1f), mat);
            }
        }
Exemplo n.º 9
0
        override public int DrawGlyph(float x, float y,
                                      List <Vector3> vertList, List <Vector2> uvList, List <Vector2> uv2List, List <Color32> colList)
        {
            GlyphMetrics metrics = _char.glyph.metrics;
            GlyphRect    rect    = _char.glyph.glyphRect;

            if (_format.specialStyle == TextFormat.SpecialStyle.Subscript)
            {
                y = y - Mathf.RoundToInt(_ascent * _scale * SupOffset);
            }
            else if (_format.specialStyle == TextFormat.SpecialStyle.Superscript)
            {
                y = y + Mathf.RoundToInt(_ascent * _scale * (1 / SupScale - 1 + SupOffset));
            }

            topLeft.x     = x + (metrics.horizontalBearingX - _padding - _stylePadding) * _scale;
            topLeft.y     = y + (metrics.horizontalBearingY + _padding) * _scale;
            bottomRight.x = topLeft.x + (metrics.width + _padding * 2 + _stylePadding * 2) * _scale;
            bottomRight.y = topLeft.y - (metrics.height + _padding * 2) * _scale;

            topRight.x   = bottomRight.x;
            topRight.y   = topLeft.y;
            bottomLeft.x = topLeft.x;
            bottomLeft.y = bottomRight.y;

            #region Handle Italic & Shearing
            if (((_style & FontStyles.Italic) == FontStyles.Italic))
            {
                // Shift Top vertices forward by half (Shear Value * height of character) and Bottom vertices back by same amount.
                float   shear_value = _fontAsset.italicStyle * 0.01f;
                Vector3 topShear    = new Vector3(shear_value * ((metrics.horizontalBearingY + _padding + _stylePadding) * _scale), 0, 0);
                Vector3 bottomShear = new Vector3(shear_value * (((metrics.horizontalBearingY - metrics.height - _padding - _stylePadding)) * _scale), 0, 0);

                topLeft     += topShear;
                bottomLeft  += bottomShear;
                topRight    += topShear;
                bottomRight += bottomShear;
            }
            #endregion Handle Italics & Shearing

            vertList.Add(bottomLeft);
            vertList.Add(topLeft);
            vertList.Add(topRight);
            vertList.Add(bottomRight);

            float u  = (rect.x - _padding - _stylePadding) / _fontAsset.atlasWidth;
            float v  = (rect.y - _padding - _stylePadding) / _fontAsset.atlasHeight;
            float uw = (rect.width + _padding * 2 + _stylePadding * 2) / _fontAsset.atlasWidth;
            float vw = (rect.height + _padding * 2 + _stylePadding * 2) / _fontAsset.atlasHeight;

            uvBottomLeft  = new Vector2(u, v);
            uvTopLeft     = new Vector2(u, v + vw);
            uvTopRight    = new Vector2(u + uw, v + vw);
            uvBottomRight = new Vector2(u + uw, v);

            float xScale = _scale * 0.01f;
            if (_format.bold)
            {
                xScale *= -1;
            }
            uv2BottomLeft  = new Vector2(0, xScale);
            uv2TopLeft     = new Vector2(511, xScale);
            uv2TopRight    = new Vector2(2093567, xScale);
            uv2BottomRight = new Vector2(2093056, xScale);

            uvList.Add(uvBottomLeft);
            uvList.Add(uvTopLeft);
            uvList.Add(uvTopRight);
            uvList.Add(uvBottomRight);

            uv2List.Add(uv2BottomLeft);
            uv2List.Add(uv2TopLeft);
            uv2List.Add(uv2TopRight);
            uv2List.Add(uv2BottomRight);

            colList.Add(vertexColors[0]);
            colList.Add(vertexColors[1]);
            colList.Add(vertexColors[2]);
            colList.Add(vertexColors[3]);

            return(4);
        }
Exemplo n.º 10
0
    /// <summary>
    /// 更新图集数据
    /// </summary>
    private void ApplySpriteAssetData()
    {
        if (cacheSpriteGlyphs == null || cacheSpriteGlyphs.Count == 0 || cacheSpriteCharacters == null ||
            cacheSpriteCharacters.Count == 0)
        {
            Debug.LogError("无缓存数据");
        }

        //1.解析新的tpsheet
        string str = File.ReadAllText(arrangeIconAtlasTpsheetFilePath);

        string[] strArr = str.Split('\n');

        //以Name为key的GlyphRect数据
        Dictionary <string, GlyphRect> glyphRectDic = new Dictionary <string, GlyphRect>();

        foreach (var item in strArr)
        {
               
            if (item.StartsWith("#") || item.StartsWith(":") || string.IsNullOrEmpty(item) || item.StartsWith("\r"))
            {
                continue;
            }
            string[]  strArr2 = item.Split(';');
            int       x       = int.Parse(strArr2[1]);
            int       y       = int.Parse(strArr2[2]);
            int       w       = int.Parse(strArr2[3]);
            int       h       = int.Parse(strArr2[4]);
            GlyphRect rect    = new GlyphRect(x, y, w, h);
            glyphRectDic.Add(strArr2[0], rect);
        }

        //1.1获取新的数据,主要使用GlyphMetrics
        Texture texture = AssetDatabase.LoadAssetAtPath <Texture>(AtlasPngPath);
        List <TMP_SpriteCharacter> newSpriteCharacters = new List <TMP_SpriteCharacter>();
        List <TMP_SpriteGlyph>     newSpriteGlyphs     = new List <TMP_SpriteGlyph>();

        PopulateSpriteTables(texture, ref newSpriteCharacters, ref newSpriteGlyphs);

        //2.更新Cache
        //2.1 cacheSpriteGlyphs
        //2.2 cacheSpriteCharacters
        if (cacheSpriteGlyphs != null && cacheSpriteGlyphs.Count > 0)
        {
            //更新Cache的SpriteGlyph的Rect

            for (int i = 0; i < cacheSpriteGlyphs.Count; i++)
            {
                TMP_SpriteGlyph glyph      = cacheSpriteGlyphs[i];
                string          spriteName = cacheSpriteCharacters[(int)glyph.index].name;
                if (glyphRectDic.ContainsKey(spriteName))
                {
                    GlyphRect newRect = glyphRectDic[spriteName];
                    glyph.glyphRect = new GlyphRect(newRect.x, newRect.y, newRect.width, newRect.height);
                }
            }
        }

        foreach (KeyValuePair <string, GlyphRect> glyphRect in glyphRectDic)
        {
            TMP_SpriteCharacter findSpriteCharacter = cacheSpriteCharacters.Find(character => character.name == glyphRect.Key);
            TMP_SpriteCharacter newSpriteCharacter  = newSpriteCharacters.Find(character => character.name == glyphRect.Key);
            if (findSpriteCharacter == null)
            {
                //新增的Sprite

                TMP_SpriteGlyph spriteGlyph = new TMP_SpriteGlyph();
                spriteGlyph.sprite     = null;
                spriteGlyph.atlasIndex = 0;
                spriteGlyph.scale      = 1.0f;
                spriteGlyph.index      = (uint)cacheSpriteGlyphs.Count;

                GlyphMetrics metrics = newSpriteCharacter.glyph.metrics;
                spriteGlyph.metrics = new GlyphMetrics(metrics.width, metrics.height, metrics.horizontalBearingX,
                                                       metrics.horizontalBearingY, metrics.horizontalAdvance);

                spriteGlyph.glyphRect = new GlyphRect(glyphRect.Value.x, glyphRect.Value.y,
                                                      glyphRect.Value.width, glyphRect.Value.height);

                cacheSpriteGlyphs.Add(spriteGlyph);

                TMP_SpriteCharacter spriteCharacter = new TMP_SpriteCharacter(0, spriteGlyph);
                spriteCharacter.glyphIndex = (uint)cacheSpriteCharacters.Count;
                spriteCharacter.scale      = 1;
                spriteCharacter.name       = glyphRect.Key;

                cacheSpriteCharacters.Add(spriteCharacter);
            }
        }

        //3.cache写入SpriteAsset
        TMP_SpriteAsset spriteAsset            = AssetDatabase.LoadAssetAtPath <TMP_SpriteAsset>(SpriteAssetPath);
        FieldInfo       spriteCharacterTablePi = spriteAsset.GetType().GetField("m_SpriteCharacterTable", BindingFlags.NonPublic | BindingFlags.Instance);

        if (null != spriteCharacterTablePi)
        {
            spriteCharacterTablePi.SetValue(spriteAsset, cacheSpriteCharacters);
        }
        FieldInfo spriteGlyphTablePi = spriteAsset.GetType().GetField("m_SpriteGlyphTable", BindingFlags.NonPublic | BindingFlags.Instance);

        if (null != spriteGlyphTablePi)
        {
            spriteGlyphTablePi.SetValue(spriteAsset, cacheSpriteGlyphs);
        }

        AssetDatabase.SaveAssets();
        AssetDatabase.Refresh();
    }