Esempio n. 1
0
        static KerningTable GetKerningTable(string fontFilePath, int pointSize)
        {
            KerningTable kerningInfo = new KerningTable();

            kerningInfo.kerningPairs = new List <KerningPair>();

            // Temporary Array to hold the kerning pairs from the Native Plug-in.
            FT_KerningPair[] kerningPairs = new FT_KerningPair[7500];

            int kpCount = TMPro_FontPlugin.FT_GetKerningPairs(fontFilePath, m_kerningSet, m_kerningSet.Length, kerningPairs);

            for (int i = 0; i < kpCount; i++)
            {
                // Proceed to add each kerning pairs.
                KerningPair kp = new KerningPair((uint)kerningPairs[i].ascII_Left, (uint)kerningPairs[i].ascII_Right, kerningPairs[i].xAdvanceOffset * pointSize);

                // Filter kerning pairs to avoid duplicates
                int index = kerningInfo.kerningPairs.FindIndex(item => item.firstGlyph == kp.firstGlyph && item.secondGlyph == kp.secondGlyph);

                if (index == -1)
                {
                    kerningInfo.kerningPairs.Add(kp);
                }
                else
                if (!TMP_Settings.warningsDisabled)
                {
                    Debug.LogWarning("Kerning Key for [" + kp.firstGlyph + "] and [" + kp.secondGlyph + "] is a duplicate.");
                }
            }

            return(kerningInfo);
        }
Esempio n. 2
0
        private void OnDone()
        {
            EditorUtility.ClearProgressBar();

            EditorApplication.update -= OnUpdate;

            UpdateRenderFeedbackWindow();
            CreateFontTexture();

            foreach (var asset in m_assets)
            {
                Save_SDF_FontAsset(asset);
            }

            m_fontAtlas = null;

            TMPro_FontPlugin.Destroy_FontEngine();

            if (m_fontAtlas != null && EditorUtility.IsPersistent(m_fontAtlas) == false)
            {
                GameObject.DestroyImmediate(m_fontAtlas);
            }

            Resources.UnloadUnusedAssets();
        }
Esempio n. 3
0
        private void OnUpdate()
        {
            var info     = m_fontAssetPath;
            var progress = TMPro_FontPlugin.Check_RenderProgress();

            EditorUtility.DisplayProgressBar("TMP_FontAssetUpdater", info, progress);
        }
Esempio n. 4
0
    private void MyUpdate()
    {
        if (m_IsRepaintNeeded)
        {
            //Debug.Log("Repainting...");
            m_IsRepaintNeeded = false;
            Repaint();
        }

        // 第一步创建字体渲染数组
        // Update Progress bar is we are Rendering a Font.
        if (m_IsProcessing)
        {
            m_RenderingProgress = TMPro_FontPlugin.Check_RenderProgress();
            m_FontAssetInfos[m_CurGenerateIndex].genPercent = m_RenderingProgress * 100;

            m_IsRepaintNeeded = true;
        }

        // Update Feedback Window & Create Font Texture once Rendering is done.
        if (m_IsRenderingDone)
        {
            // Stop StopWatch
            m_StopWatch.Stop();
            Debug.Log("Font Atlas generation completed in: " + m_StopWatch.Elapsed.TotalMilliseconds.ToString("0.000 ms."));
            m_StopWatch.Reset();

            m_IsProcessing    = false;
            m_IsRenderingDone = false;

            if (m_IsGenerationCancelled == false)
            {
                // 第二步输出渲染结果
                UpdateRenderFeedbackWindow();
                // 第三步将渲染数组填充到纹理贴图(注意,贴图共享不删除)
                CreateFontTexture();
                foreach (var asset in m_FontAssetInfos[m_CurGenerateIndex].assets)
                {
                    // 最后保存信息到字体资产
                    Save_SDF_FontAsset(asset);
                }
                // 最后置空
                m_FontAtlas = null;
            }
            Repaint();
        }
    }
Esempio n. 5
0
    public void OnDisable()
    {
        //Debug.Log("TextMeshPro Editor Window has been disabled.");

        // Destroy Engine only if it has been initialized already
        TMPro_FontPlugin.Destroy_FontEngine();

        if (m_FontAtlas != null && EditorUtility.IsPersistent(m_FontAtlas) == false)
        {
            //Debug.Log("Destroying font_Atlas!");
            DestroyImmediate(m_FontAtlas);
        }

        if (File.Exists("Assets/TextMesh Pro/Glyph Report.txt"))
        {
            File.Delete("Assets/TextMesh Pro/Glyph Report.txt");
            File.Delete("Assets/TextMesh Pro/Glyph Report.txt.meta");

            AssetDatabase.Refresh();
        }

        Resources.UnloadUnusedAssets();
    }
Esempio n. 6
0
    static void CreateTexture(int channel)
    {
        renderCompleted = false;
        textureChannel  = channel;
        int charStartIndex = 0;

        for (int i = 0; i < channel; i++)
        {
            charStartIndex += charCounts[i];
        }
        charCount = charCounts[channel];
        charCodes = new int[charCount];
        for (int i = 0; i < charCount; i++)
        {
            charCodes[i] = gbkChars[charStartIndex + i];
        }
        faceInfo      = new FT_FaceInfo();
        glyphInfo     = new FT_GlyphInfo[charCount];
        textureBuffer = new byte[textureSize * textureSize];
        ThreadPool.QueueUserWorkItem(SomeTask => {
            TMPro_FontPlugin.Render_Characters(textureBuffer, textureSize, textureSize, charPadding, charCodes, charCount, FaceStyles.Normal, 32, false, RenderModes.DistanceField16, 0, ref faceInfo, glyphInfo);
            renderCompleted = true;
        });
    }
Esempio n. 7
0
    static void CreateFont()
    {
        InitGBK();
        string path = AssetDatabase.GetAssetPath(Selection.activeObject);

        fontName = Path.GetFileNameWithoutExtension(path);
        int errorCode = TMPro_FontPlugin.Initialize_FontEngine();

        if (errorCode == 0 || errorCode == 99)
        {
            errorCode = TMPro_FontPlugin.Load_TrueType_Font(path);
            if (errorCode == 0 || errorCode == 99)
            {
                errorCode = TMPro_FontPlugin.FT_Size_Font(fontSize);
                if (errorCode == 0 || errorCode == 99)
                {
                    EditorApplication.update += RenderUpdate;
                    textureColors             = new Color32[textureSize * textureSize];
                    charInfoList              = new List <CharacterInfo>();
                    CreateTexture(0);
                }
            }
        }
    }
Esempio n. 8
0
        public static void SetupGUI(TexAsset asset)
        {
            EditorGUI.BeginDisabledGroup(onRendering);
            GUILayout.BeginHorizontal();
            GUI.changed = false;

            GUILayout.Label("Atlas Resolution", GUILayout.Width(EditorGUIUtility.labelWidth));
            _bufferWidth  = EditorGUILayout.IntPopup(_bufferWidth, FontResolutionLabels, FontAtlasResolutions);  //, GUILayout.Width(80));
            _bufferHeight = EditorGUILayout.IntPopup(_bufferHeight, FontResolutionLabels, FontAtlasResolutions); //, GUILayout.Width(80));

            GUILayout.EndHorizontal();

            GUILayout.BeginHorizontal();
            GUILayout.Label("Padding", GUILayout.Width(EditorGUIUtility.labelWidth));
            _padding = EditorGUILayout.IntSlider(_padding, 1, 10);
            GUILayout.EndHorizontal();

            _render = (RenderModes)EditorGUILayout.EnumPopup(_render);
            if (GUILayout.Button("Render"))
            {
                CreateSDFAsset(asset);
            }
            EditorGUI.BeginDisabledGroup(onRendering || asset.type != TexAssetType.FontSigned);
            GUI.backgroundColor = Color.red;

            if (GUILayout.Button("Delete SDF Asset"))
            {
                AssetDatabase.DeleteAsset(AssetDatabase.GetAssetPath(((TexFontSigned)asset).asset));
                asset = Deconvert((TexFontSigned)asset);
            }

            GUI.backgroundColor = Color.white;
            EditorGUI.EndDisabledGroup();
            {
                EditorGUILayout.Space();
                if (GUILayout.Button("Render All Fonts"))
                {
                    onRenderingBatch = (EditorUtility.DisplayDialogComplex("Confirm Action", "Are you sure? This will take few moments.\nAnd what will you do with existing SDF Asset?",
                                                                           "Overwrite", "Cancel", "Skip (Faster)"));
                    onRenderingBatch = onRenderingBatch == 1 ? 0 : (onRenderingBatch == 0 ? 1 : 2);
                    if (onRenderingBatch > 0)
                    {
                        DoBatchRendering();
                    }
                }
                EditorGUI.BeginDisabledGroup(onRendering);
                GUI.backgroundColor = new Color(0.5f, 0, 0.5f);
                if (GUILayout.Button("Delete All SDF Asset"))
                {
                    if (EditorUtility.DisplayDialog("Confirm Deletion", "Are you sure you want to delete ALL SDF Font Asset?", "Yes", "No"))
                    {
                        var fonts = TEXPreference.main.fonts;
                        for (int i = 0; i < fonts.Length; i++)
                        {
                            EditorUtility.DisplayProgressBar("Please wait", "Reimporting Fonts...", i / (float)fonts.Length);
                            if (fonts[i].type == TexAssetType.FontSigned)
                            {
                                AssetDatabase.DeleteAsset(AssetDatabase.GetAssetPath(((TexFontSigned)fonts[i]).asset));
                                Deconvert((TexFontSigned)fonts[i]);
                            }
                        }
                        TEXPreference.main.RebuildMaterial();
                        EditorUtility.ClearProgressBar();
                    }
                }
                GUI.backgroundColor = Color.white;
                EditorGUI.EndDisabledGroup();
            }

            EditorGUI.EndDisabledGroup();
            if (onRendering)
            {
                var prog = TMPro_FontPlugin.Check_RenderProgress();
                EditorGUI.ProgressBar(EditorGUILayout.GetControlRect(), prog, prog.ToString("P"));
                if (onRenderingBatch > 0)
                {
                    if (onRenderingBatch == 3)
                    {
                        EditorGUILayout.HelpBox("Will be stopped after current rendering is done", MessageType.Info);
                    }
                    else
                    {
                        GUI.backgroundColor = Color.yellow;
                        if (GUILayout.Button("Cancel"))
                        {
                            onRenderingBatch = 3;
                        }
                        GUI.backgroundColor = Color.white;
                    }
                }
            }
        }
Esempio n. 9
0
        public static void CreateSDFAsset(TexAsset asset, Font font, string fontPath)
        {
            // initialize
            CheckErr(TMPro_FontPlugin.Initialize_FontEngine());
            CheckErr(TMPro_FontPlugin.Load_TrueType_Font(fontPath));
            CheckErr(TMPro_FontPlugin.FT_Size_Font(72));

            _buffers = new byte[_bufferWidth * _bufferHeight];
            var charSet = new int[asset.chars.Length];

            _glyphsInfo = new FT_GlyphInfo[asset.chars.Length];
            _atlasInfo  = null;

            for (int i = 0; i < asset.chars.Length; i++)
            {
                charSet[i] = asset.chars[i].characterIndex;
            }

            float strokeSize = _styleStrokeSize;

            if (_render == RenderModes.DistanceField16)
            {
                strokeSize = _styleStrokeSize * 16;
            }
            if (_render == RenderModes.DistanceField32)
            {
                strokeSize = _styleStrokeSize * 32;
            }

            ThreadPool.QueueUserWorkItem(SomeTask =>
            {
                try
                {
                    onRendering = true;

                    CheckErr(TMPro_FontPlugin.Render_Characters(_buffers, _bufferWidth, _bufferHeight, _padding,
                                                                charSet, charSet.Length, _style, strokeSize, true, _render, _optimized ? 4 : 0,
                                                                ref _faceInfo, _glyphsInfo));

                    EditorApplication.delayCall += delegate()
                    {
                        try
                        {
                            OnFinished(Convert(asset));
                        }
                        catch (Exception ex)
                        {
                            Debug.LogException(ex);
                            Debug.LogWarningFormat("Failed to create SDF File for {0}.ttf. Consider delete and rerender again", asset.id);
                        }
                        finally
                        {
                            hasRendered = false;

                            if (onRendering)
                            {
                                //CheckErr(TMPro_FontPlugin.Destroy_FontEngine());
                                onRendering = false;
                            }

                            if (onRenderingBatch > 0)
                            {
                                isRenderingBatchFinished = true;
                            }
                        }
                    };
                    Debug.LogFormat("Font Rendering of {0}.ttf has completed.", asset.id);
                }
                catch (Exception ex)
                {
                    Debug.LogException(ex);
                    Debug.LogWarningFormat("Failed to create Render {0}.ttf. Consider rerender again", asset.id);
                }
                finally
                {
                    if (onRendering)
                    {
                        //CheckErr(TMPro_FontPlugin.Destroy_FontEngine());
                        onRendering = false;
                    }
                }
            });
        }
Esempio n. 10
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);
        }
Esempio n. 11
0
        //==============================================================================
        // 関数
        //==============================================================================
        public void Start(TMP_FontAssetUpdaterSettings settings, Action onComplete = null)
        {
            ShaderUtilities.GetShaderPropertyIDs();

            m_settings      = settings;
            m_font          = settings.SourceFontFile;
            m_fontAssetPath = AssetDatabase.GetAssetPath(settings.FontAsset);

            var fontPath = AssetDatabase.GetAssetPath(m_font);
            var fontName = Path.GetFileNameWithoutExtension(fontPath);
            var filter   = "t:TMP_FontAsset " + fontName + " SDF";

            m_assets = AssetDatabase
                       .FindAssets(filter, new [] { "Assets" })
                       .Select(c => AssetDatabase.GUIDToAssetPath(c))
                       .ToArray()
            ;

            m_characterSequence = m_settings.CustomCharacterList.text;

            if (m_font == null)
            {
                return;
            }

            GameObject.DestroyImmediate(m_fontAtlas);
            m_fontAtlas = null;

            var initResult = TMPro_FontPlugin.Initialize_FontEngine();

            if (initResult != 0 && initResult != 0xF0)
            {
                Debug.Log("Error Code: " + initResult + "  occurred while Initializing the FreeType Library.");
                return;
            }

            var loadResult = TMPro_FontPlugin.Load_TrueType_Font(fontPath);

            if (loadResult != 0 && loadResult != 0xF1)
            {
                Debug.Log("Error Code: " + loadResult + "  occurred while Loading the [" + m_font.name + "] font file. This typically results from the use of an incompatible or corrupted font file.");
                return;
            }

            var sizeResult = TMPro_FontPlugin.FT_Size_Font(SamplingPointSize);

            if (sizeResult != 0)
            {
                Debug.Log("Error Code: " + sizeResult + "  occurred while Sizing the font.");
                return;
            }

            int[] characterSet;
            var   charList = new List <int>();

            for (int i = 0; i < m_characterSequence.Length; i++)
            {
                if (charList.FindIndex(item => item == m_characterSequence[i]) == -1)
                {
                    charList.Add(m_characterSequence[i]);
                }
                else
                {
                    //Debug.Log("Character [" + characterSequence[i] + "] is a duplicate.");
                }
            }

            characterSet = charList.ToArray();

            m_characterCount = characterSet.Length;
            m_textureBuffer  = new byte[AtlasWidth * AtlasHeight];
            m_fontFaceInfo   = new FT_FaceInfo();
            m_fontGlyphInfo  = new FT_GlyphInfo[m_characterCount];

            int padding = Padding;

            var autoSizing = SamplingPointSizeMode == SamplingPointSizes.AutoSizing;
            var strokeSize = FontStyleModifier;

            if (RenderMode == RenderModes.DistanceField16)
            {
                strokeSize = FontStyleModifier * 16;
            }
            if (RenderMode == RenderModes.DistanceField32)
            {
                strokeSize = FontStyleModifier * 32;
            }

            EditorApplication.update += OnUpdate;

            ThreadPool.QueueUserWorkItem(_ =>
            {
                TMPro_FontPlugin.Render_Characters
                (
                    buffer: m_textureBuffer,
                    buffer_width: AtlasWidth,
                    buffer_height: AtlasHeight,
                    character_padding: padding,
                    asc_set: characterSet,
                    char_count: m_characterCount,
                    style: FontStyle,
                    style_mod: strokeSize,
                    autoSize: autoSizing,
                    renderMode: RenderMode,
                    method: ( int )PackingMethod,
                    fontData: ref m_fontFaceInfo,
                    Output: m_fontGlyphInfo
                );

                EditorApplication.delayCall += () =>
                {
                    OnDone();

                    if (onComplete != null)
                    {
                        onComplete();
                    }
                };
            });
        }
Esempio n. 12
0
    static void RenderUpdate()
    {
        if (renderCompleted)
        {
            if (textureChannel == 0)
            {
                for (int i = 0; i < textureColors.Length; i++)
                {
                    textureColors[i].r = textureBuffer[i];
                }
            }
            if (textureChannel == 1)
            {
                for (int i = 0; i < textureColors.Length; i++)
                {
                    textureColors[i].g = textureBuffer[i];
                }
            }
            if (textureChannel == 2)
            {
                for (int i = 0; i < textureColors.Length; i++)
                {
                    textureColors[i].b = textureBuffer[i];
                }
            }
            if (textureChannel == 3)
            {
                for (int i = 0; i < textureColors.Length; i++)
                {
                    textureColors[i].a = textureBuffer[i];
                }
            }

            var size       = (float)textureSize;
            var ascender   = faceInfo.ascender;
            var glyphCount = faceInfo.characterCount;

            var charSet = new HashSet <int>();

            for (int i = 0; i < glyphCount; i++)
            {
                var charInfo = new CharacterInfo();
                var id       = glyphInfo[i].id;
                var x        = (glyphInfo[i].x - charPadding);
                var y        = (glyphInfo[i].y - charPadding);
                var width    = (glyphInfo[i].width + charPadding + charPadding);
                var height   = (glyphInfo[i].height + charPadding + charPadding);
                var xOffset  = glyphInfo[i].xOffset;
                var yOffset  = glyphInfo[i].yOffset - ascender;
                var xAdvance = glyphInfo[i].xAdvance;
                var uvMinX   = Mathf.Round(x) / size;
                var uvMinY   = Mathf.Round(size - y - height) / size;
                var uvMaxX   = Mathf.Round(x + width) / size;
                var uvMaxY   = Mathf.Round(size - y) / size;
                charInfoList.Add(charInfo);
                charInfo.uvTopLeft     = new Vector2(uvMinX, uvMinY);
                charInfo.uvTopRight    = new Vector2(uvMaxX, uvMinY);
                charInfo.uvBottomLeft  = new Vector2(uvMinX, uvMaxY);
                charInfo.uvBottomRight = new Vector2(uvMaxX, uvMaxY);
                charInfo.minX          = Mathf.RoundToInt(xOffset);
                charInfo.minY          = Mathf.RoundToInt(yOffset);
                charInfo.maxX          = Mathf.RoundToInt(xOffset + width);
                charInfo.maxY          = Mathf.RoundToInt(yOffset - height);
                charInfo.advance       = Mathf.RoundToInt(xAdvance);
                charInfo.index         = id;
                charSet.Add(id);
            }

            for (int i = 0; i < charCodes.Length; i++)
            {
                if (!charSet.Contains(charCodes[i]))
                {
                    Debug.Log("Missing: " + (char)charCodes[i] + "|" + i + "|" + charCodes[i] + "|0x" + charCodes[i].ToString("X4"));
                }
            }

            Debug.Log("Glyph:" + glyphCount + ", " + charCodes[0] + " - " + charCodes[charCodes.Length - 1]);

            if (textureChannel < 3)
            {
                CreateTexture(textureChannel + 1);
            }
            else
            {
                EditorUtility.ClearProgressBar();
                EditorApplication.update -= RenderUpdate;
                TMPro_FontPlugin.Destroy_FontEngine();

                var texturePath  = outputFolder + fontName + ".png";
                var materialPath = outputFolder + fontName + ".mat";
                var fontPath     = outputFolder + fontName + ".fontsettings";

                var texture = new Texture2D(textureSize, textureSize, TextureFormat.RGBA32, false, true);
                texture.SetPixels32(textureColors);
                File.WriteAllBytes(texturePath, texture.EncodeToPNG());
                AssetDatabase.SaveAssets();
                AssetDatabase.Refresh();
                var import = AssetImporter.GetAtPath(texturePath) as TextureImporter;
                import.textureCompression  = TextureImporterCompression.Uncompressed;
                import.alphaIsTransparency = false;
                import.mipmapEnabled       = false;
                AssetDatabase.ImportAsset(texturePath);

                var material = new Material(Shader.Find("SDF/GBK/Text"));
                material.mainTexture = AssetDatabase.LoadAssetAtPath <Texture2D>(texturePath);
                AssetDatabase.CreateAsset(material, materialPath);

                var font  = new Font(fontName);
                var mFont = new SerializedObject(font);
                mFont.FindProperty("m_FontSize").floatValue    = faceInfo.pointSize;
                mFont.FindProperty("m_LineSpacing").floatValue = faceInfo.lineHeight;
                mFont.ApplyModifiedProperties();
                font.material      = material;
                font.characterInfo = charInfoList.ToArray();
                AssetDatabase.CreateAsset(font, fontPath);
            }
        }
        else
        {
            float  progress     = TMPro_FontPlugin.Check_RenderProgress();
            string progressText = "Channel: " + textureChannel + " , Char: " + (int)(progress * charCount) + "/" + charCount;
            EditorUtility.DisplayProgressBar("Create Font", progressText, progress);
        }
    }
Esempio n. 13
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);
    }
Esempio n. 14
0
    private void GenerateFontAtlasButton()
    {
        if (!m_IsProcessing && m_SourceFontFile != null)
        {
            DestroyImmediate(m_FontAtlas);
            m_FontAtlas      = null;
            m_OutputFeedback = string.Empty;
            m_SavedFontAtlas = null;
            int errorCode;

            errorCode = TMPro_FontPlugin.Initialize_FontEngine(); // Initialize Font Engine
            if (errorCode != 0)
            {
                if (errorCode == 0xF0)
                {
                    //Debug.Log("Font Library was already initialized!");
                    errorCode = 0;
                }
                else
                {
                    Debug.Log("Error Code: " + errorCode + "  occurred while Initializing the FreeType Library.");
                }
            }

            string fontPath = AssetDatabase.GetAssetPath(m_SourceFontFile); // Get file path of TTF Font.

            if (errorCode == 0)
            {
                errorCode = TMPro_FontPlugin.Load_TrueType_Font(fontPath); // Load the selected font.

                if (errorCode != 0)
                {
                    if (errorCode == 0xF1)
                    {
                        //Debug.Log("Font was already loaded!");
                        errorCode = 0;
                    }
                    else
                    {
                        Debug.Log("Error Code: " + errorCode + "  occurred while Loading the [" + m_SourceFontFile.name + "] font file. This typically results from the use of an incompatible or corrupted font file.");
                    }
                }
            }

            if (errorCode == 0)
            {
                if (m_PointSizeSamplingMode == 0)
                {
                    m_PointSize = 72;                                   // If Auto set size to 72 pts.
                }
                errorCode = TMPro_FontPlugin.FT_Size_Font(m_PointSize); // Load the selected font and size it accordingly.
                if (errorCode != 0)
                {
                    Debug.Log("Error Code: " + errorCode + "  occurred while Sizing the font.");
                }
            }

            // Define an array containing the characters we will render.
            if (errorCode == 0)
            {
                int[] characterSet;
                if (m_CharacterSetSelectionMode == 7 || m_CharacterSetSelectionMode == 8)
                {
                    List <int> charList = new List <int>();

                    for (int i = 0; i < m_CharacterSequence.Length; i++)
                    {
                        // Check to make sure we don't include duplicates
                        if (charList.FindIndex(item => item == m_CharacterSequence[i]) == -1)
                        {
                            charList.Add(m_CharacterSequence[i]);
                        }
                        else
                        {
                            //Debug.Log("Character [" + characterSequence[i] + "] is a duplicate.");
                        }
                    }

                    characterSet = charList.ToArray();
                }
                else if (m_CharacterSetSelectionMode == 6)
                {
                    characterSet = ParseHexNumberSequence(m_CharacterSequence);
                }
                else
                {
                    characterSet = ParseNumberSequence(m_CharacterSequence);
                }

                m_CharacterCount = characterSet.Length;

                m_TextureBuffer = new byte[m_AtlasWidth * m_AtlasHeight];

                m_FontFaceInfo = new FT_FaceInfo();

                m_FontGlyphInfo = new FT_GlyphInfo[m_CharacterCount];

                int padding = m_Padding;

                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;
                }

                m_IsProcessing          = true;
                m_IsGenerationCancelled = false;

                // Start Stop Watch
                m_StopWatch = System.Diagnostics.Stopwatch.StartNew();

                ThreadPool.QueueUserWorkItem(someTask =>
                {
                    m_IsRenderingDone = false;

                    errorCode = TMPro_FontPlugin.Render_Characters(m_TextureBuffer, m_AtlasWidth, m_AtlasHeight,
                                                                   padding, characterSet, m_CharacterCount, m_FontStyle, strokeSize, autoSizing, m_RenderMode,
                                                                   (int)m_PackingMode, ref m_FontFaceInfo, m_FontGlyphInfo);

                    ThreadRenderBackupFont(0, m_AtlasWidth);

                    m_IsRenderingDone = true;
                });
            }
        }
    }
Esempio n. 15
0
        public static void CreateSDFAsset(TexFont font, string fontPath)
        {
            // Simple checks...
            if (!font.Font_Asset)
            {
                return;
            }
            // Expensive check, somewhat useless

            /*var objs = AssetDatabase.FindAssets("t:TMP_FontAsset");
             * foreach (var obj in objs)
             * {
             *  var asset = AssetDatabase.LoadAssetAtPath<TMP_FontAsset>(AssetDatabase.GUIDToAssetPath(obj));
             *  if (asset.name == font.name)
             *  {
             *      font.SDF_Asset = asset;
             *      return;
             *  }
             * }*/

            //TMPro_FontPlugin.LinkDebugLog();

            var error = 0;

            error = TMPro_FontPlugin.Initialize_FontEngine();
            if (error != 0 && error != 99)
            {
                throw new Exception("ERROR: " + error.ToString());
            }
            error = TMPro_FontPlugin.Load_TrueType_Font(fontPath);
            if (error != 0 && error != 99)
            {
                throw new Exception("ERROR: " + error.ToString());
            }
            error = TMPro_FontPlugin.FT_Size_Font(72);
            if (error != 0 && error != 99)
            {
                throw new Exception("ERROR: " + error.ToString());
            }

            _buffers = new byte[_bufferWidth * _bufferHeight];
            var charSet = new int[font.chars.Length];

            _glyphsInfo = new FT_GlyphInfo[font.chars.Length];
            _atlasInfo  = null;

            for (int i = 0; i < font.chars.Length; i++)
            {
                charSet[i] = font.chars[i].characterIndex;
            }
            float strokeSize = _styleStrokeSize;

            if (_render == RenderModes.DistanceField16)
            {
                strokeSize = _styleStrokeSize * 16;
            }
            if (_render == RenderModes.DistanceField32)
            {
                strokeSize = _styleStrokeSize * 32;
            }

            EditorApplication.update += OnUpdate;

            _renderedFont = font;
            ThreadPool.QueueUserWorkItem(SomeTask =>
            {
                onRendering = true;

                error = TMPro_FontPlugin.Render_Characters(_buffers, _bufferWidth, _bufferHeight, _padding,
                                                           charSet, charSet.Length, _style, strokeSize, true, _render, _optimized ? 4 : 0,
                                                           ref _faceInfo, _glyphsInfo);

                if (error != 0 && error != 99)
                {
                    onRendering = false;
                    throw new Exception("ERROR: " + error.ToString());
                }
                // Can't call OnFinished here because this isn't a Main thread
                hasRendered = true;

                Debug.LogFormat("Font Rendering of {0}.ttf is completed.", font.id);
            });
        }