Пример #1
0
 int Render_Character(byte[] buffer_fill, byte[] buffer_edge, int buffer_width, int buffer_height, int offset, int asc, FaceStyles style, float thickness, RenderModes rasterMode, ref FT_GlyphInfo glyphInfo);
Пример #2
0
        // PRAGMA MARK - Public Interface
        public static void Bake(Font font, bool useAutoSizing, int fontSize, int characterPadding, TMPFontPackingModes fontPackingMode, int atlasWidth, int atlasHeight, FaceStyles fontStyle, int fontStyleMod, RenderModes fontRenderMode, string charactersToBake, string outputFilePath)
        {
            int errorCode = TMPro_FontPlugin.Initialize_FontEngine();

            if (errorCode != 0 && errorCode != 99)               // 99 means that engine was already initialized
            {
                Debug.LogWarning("Error Code: " + errorCode + "  occurred while initializing TMPro_FontPlugin.");
                return;
            }

            string fontPath = AssetDatabase.GetAssetPath(font);

            errorCode = TMPro_FontPlugin.Load_TrueType_Font(fontPath);
            if (errorCode != 0 && errorCode != 99)               // 99 means that font was already loaded
            {
                Debug.LogWarning("Error Code: " + errorCode + "  occurred while loading font: " + font + ".");
                return;
            }

            if (useAutoSizing)
            {
                fontSize = 72;
            }
            errorCode = TMPro_FontPlugin.FT_Size_Font(fontSize);
            if (errorCode != 0)
            {
                Debug.LogWarning("Error Code: " + errorCode + "  occurred while sizing font: " + font + " to size: " + fontSize + ".");
                return;
            }

            byte[] textureBuffer = new byte[atlasWidth * atlasHeight];

            int[] characterArray = charactersToBake.Select(c => (int)c).ToArray();
            int   characterCount = charactersToBake.Length;

            var fontFaceInfo  = new FT_FaceInfo();
            var fontGlyphInfo = new FT_GlyphInfo[characterCount];

            float strokeSize = fontStyleMod;

            if (fontRenderMode == RenderModes.DistanceField16)
            {
                strokeSize *= 16;
            }
            else if (fontRenderMode == RenderModes.DistanceField32)
            {
                strokeSize *= 32;
            }

            errorCode = TMPro_FontPlugin.Render_Characters(textureBuffer, atlasWidth, atlasHeight, characterPadding, characterArray, characterCount, fontStyle, strokeSize, useAutoSizing, fontRenderMode, (int)fontPackingMode, ref fontFaceInfo, fontGlyphInfo);
            if (errorCode != 0)
            {
                Debug.LogWarning("Error Code: " + errorCode + "  occurred while rendering font characters!");
                return;
            }

            string outputFilename = Path.GetFileNameWithoutExtension(outputFilePath);

            // check if font asset already exists
            TMP_FontAsset fontAsset = AssetDatabase.LoadAssetAtPath(outputFilePath, typeof(TMP_FontAsset)) as TMP_FontAsset;

            if (fontAsset == null)
            {
                fontAsset = ScriptableObject.CreateInstance <TMP_FontAsset>();                // Create new TextMeshPro Font Asset.
                AssetDatabase.CreateAsset(fontAsset, outputFilePath);
            }

            // Destroy Assets that will be replaced.
            UnityEngine.Object.DestroyImmediate(fontAsset.atlas, allowDestroyingAssets: true);

            fontAsset.fontAssetType = (fontRenderMode >= RenderModes.DistanceField16) ? TMP_FontAsset.FontAssetTypes.SDF : TMP_FontAsset.FontAssetTypes.Bitmap;

            fontAsset.AddFaceInfo(ConvertToFaceInfo(fontFaceInfo));
            fontAsset.AddGlyphInfo(ConvertToGlyphs(fontGlyphInfo));

            var fontTexture = CreateFontTexture(atlasWidth, atlasHeight, textureBuffer, fontRenderMode);

            fontTexture.name      = outputFilename + " Atlas";
            fontTexture.hideFlags = HideFlags.HideInHierarchy;

            fontAsset.atlas = fontTexture;
            AssetDatabase.AddObjectToAsset(fontTexture, fontAsset);

            // Find all Materials referencing this font atlas.
            Material[] materialReferences = TMP_EditorUtility.FindMaterialReferences(fontAsset).Where(m => m != null).ToArray();
            if (materialReferences == null || materialReferences.Length <= 0)
            {
                // Create new Material and add it as Sub-Asset
                Shader   shader       = Shader.Find("TMPro/Distance Field");
                Material fontMaterial = new Material(shader);
                fontMaterial.name = outputFilename + " Material";

                fontAsset.material     = fontMaterial;
                fontMaterial.hideFlags = HideFlags.HideInHierarchy;
                AssetDatabase.AddObjectToAsset(fontMaterial, fontAsset);

                materialReferences = new Material[] { fontMaterial };
            }

            foreach (var m in materialReferences)
            {
                m.SetTexture(ShaderUtilities.ID_MainTex, fontTexture);
                m.SetFloat(ShaderUtilities.ID_TextureWidth, fontTexture.width);
                m.SetFloat(ShaderUtilities.ID_TextureHeight, fontTexture.height);


                m.SetFloat(ShaderUtilities.ID_WeightNormal, fontAsset.normalStyle);
                m.SetFloat(ShaderUtilities.ID_WeightBold, fontAsset.boldStyle);

                m.SetFloat(ShaderUtilities.ID_GradientScale, characterPadding + 1);
            }

            AssetDatabase.SaveAssets();
            // Re-import font asset to get the new updated version.
            AssetDatabase.ImportAsset(AssetDatabase.GetAssetPath(fontAsset));
            fontAsset.ReadFontDefinition();
            AssetDatabase.Refresh();

            // NEED TO GENERATE AN EVENT TO FORCE A REDRAW OF ANY TEXTMESHPRO INSTANCES THAT MIGHT BE USING THIS FONT ASSET
            TMPro_EventManager.ON_FONT_PROPERTY_CHANGED(true, fontAsset);
        }
Пример #3
0
    private void ThreadRenderBackupFont(int backupLevel, int xOffsetDist)
    {
        if (m_FontBackupPaths == null || m_FontBackupPaths.Length <= backupLevel)
        {
            return;
        }

        List <int> list = new List <int>();

        for (int index = 0; index < m_CharacterCount; ++index)
        {
            if (m_FontGlyphInfo[index].x == -1)
            {
                list.Add(m_FontGlyphInfo[index].id);
            }
        }

        // 如果有指定字体,则在这里插入
        if (m_CharacterUseFontBackup != null && m_CharacterUseFontBackup.Length > backupLevel)
        {
            foreach (var character in m_CharacterUseFontBackup[backupLevel])
            {
                if (!string.IsNullOrEmpty(character))
                {
                    for (int i = 0; i < character.Length; i++)
                    {
                        // Check to make sure we don't include duplicates
                        if (list.FindIndex(item => item == character[i]) == -1)
                        {
                            list.Add(character[i]);
                        }
                    }
                }
            }
        }

        if (list.Count == 0)
        {
            return;
        }

        int[]  characterSet = list.ToArray();
        string fontPath     = m_FontBackupPaths[backupLevel];
        int    errorCode    = TMPro_FontPlugin.Load_TrueType_Font(fontPath);

        if (errorCode != 0)
        {
            return;
        }

        var tmpAtlasWidth     = 512;
        var tmpAtlasHeight    = 512;
        var tmpTextureBuffer  = new byte[tmpAtlasWidth * tmpAtlasHeight];
        var tmpCharacterCount = characterSet.Length;
        var tmpFontFaceInfo   = default(FT_FaceInfo);
        var tmpFontGlyphInfo  = new FT_GlyphInfo[tmpCharacterCount];

        bool  autoSizing = m_PointSizeSamplingMode == 0;
        float strokeSize = m_FontStyleValue;

        if (m_RenderMode == RenderModes.DistanceField16)
        {
            strokeSize = m_FontStyleValue * 16;
        }
        if (m_RenderMode == RenderModes.DistanceField32)
        {
            strokeSize = m_FontStyleValue * 32;
        }

        errorCode = TMPro_FontPlugin.Render_Characters(tmpTextureBuffer, tmpAtlasWidth,
                                                       tmpAtlasHeight, m_Padding, characterSet, tmpCharacterCount, m_FontStyle, strokeSize,
                                                       autoSizing, m_RenderMode, (int)m_PackingMode, ref tmpFontFaceInfo, tmpFontGlyphInfo);
        if (errorCode != 0)
        {
            return;
        }

        int wordWidth = m_PointSize;
        int xStart    = xOffsetDist - m_Padding * 2 - wordWidth; // 从padding开始拷贝,否则会出现负偏移丢失的情况
        int yStart    = m_AtlasHeight - m_Padding - 1;
        int numY      = 0;

        for (int index = 0; index < tmpCharacterCount; ++index)
        {
            if (!Mathf.Approximately(tmpFontGlyphInfo[index].x, -1))
            {
                var gi = tmpFontGlyphInfo[index];
                var x  = Mathf.FloorToInt(gi.x) - m_Padding;
                var y  = tmpAtlasHeight - (Mathf.FloorToInt(gi.y) - m_Padding);
                var w  = Mathf.CeilToInt(gi.width) + m_Padding * 2;
                var h  = Mathf.CeilToInt(gi.height) + m_Padding * 2;

                for (int r = 0; r < h; r++)
                {
                    for (int c = 0; c < w; c++)
                    {
                        m_TextureBuffer[(yStart - r) * m_AtlasWidth + c + xStart] =
                            tmpTextureBuffer[(y - r) * tmpAtlasWidth + c + x];
                    }
                }
                var idx = ArrayUtility.FindIndex(m_FontGlyphInfo, info => info.id == gi.id);
                if (idx == -1)
                {
                    // 往数组里面添加
                    ArrayUtility.Add(ref m_FontGlyphInfo, new FT_GlyphInfo()
                    {
                        id = gi.id
                    });
                    idx = m_FontGlyphInfo.Length - 1;
                }

                var gi2 = m_FontGlyphInfo[idx];
                gi2.x                = xStart + m_Padding;
                gi2.y                = m_AtlasHeight - yStart + m_Padding;
                gi2.width            = gi.width;
                gi2.height           = gi.height;
                gi2.xAdvance         = gi.xAdvance;
                gi2.xOffset          = gi.xOffset;
                gi2.yOffset          = gi.yOffset;
                m_FontGlyphInfo[idx] = gi2;

                yStart = yStart - h - m_Padding - 1;
                numY++;

                // 如果超过五个则换一列
                if (numY > 5)
                {
                    numY   = 0;
                    xStart = xStart - m_Padding * 2 - wordWidth;
                    yStart = m_AtlasHeight - m_Padding - 1;
                }
            }
        }

        ThreadRenderBackupFont(++backupLevel, xStart);
    }