Search Unity

Pick all chars from TTF

Discussion in 'UGUI & TextMesh Pro' started by Rafael_CS, Jan 20, 2019.

  1. Rafael_CS

    Rafael_CS

    Joined:
    Sep 16, 2013
    Posts:
    162
    Hello guys, i made an editor script to help pick all chars from a TTF (in my case, i downloaded some Vector TTFs and just want to convert it to TMP Font Asset)

    I suggest to update the Font Asset Creator to add an option to pick ALL CHARs from a TTF.
    (use PickAllCharsRangeFromFont to do it, if original creator want to easy integrate it to Original TextMeshPro Font Asset Creator Window)

    Best Regards
    Rafael

    upload_2019-1-20_19-16-1.png

    Code (CSharp):
    1.  
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using UnityEngine;
    5. using UnityEditor;
    6. namespace TMPro
    7. {
    8.     public class CharsInTTFWindow : EditorWindow
    9.     {
    10.         #region Private Variables
    11.         [SerializeField]
    12.         string m_charsRange = "";
    13.         [SerializeField]
    14.         Font m_font;
    15.         Vector2 _scroll = Vector2.zero;
    16.         #endregion
    17.         #region Static Init
    18.         [MenuItem("Window/TextMeshPro/Chars in Font")]
    19.         static void Init()
    20.         {
    21.             // Get existing open window or if none, make a new one:
    22.             CharsInTTFWindow window = (CharsInTTFWindow)EditorWindow.GetWindow(typeof(CharsInTTFWindow));
    23.             window.titleContent = new GUIContent("Chars in Font");
    24.             window.ShowUtility();
    25.         }
    26.         #endregion
    27.         #region Unity Functions
    28.         protected virtual void OnGUI()
    29.         {
    30.             if (m_font != null)
    31.             {
    32.                 using (new EditorGUILayout.HorizontalScope())
    33.                 {
    34.                     GUILayout.FlexibleSpace();
    35.                     if (GUILayout.Button("Recalculate", GUILayout.Width(150)))
    36.                     {
    37.                         m_charsRange = PickAllCharsRangeFromFont(m_font);
    38.                     }
    39.                 }
    40.             }
    41.             EditorGUILayout.Space();
    42.             var v_newFont = EditorGUILayout.ObjectField("Source Font File", m_font, typeof(Font), false) as Font;
    43.             if (m_font != v_newFont)
    44.             {
    45.                 m_font = v_newFont;
    46.                 m_charsRange = PickAllCharsRangeFromFont(m_font);
    47.             }
    48.             EditorGUILayout.Space();
    49.             _scroll = EditorGUILayout.BeginScrollView(_scroll);
    50.             EditorGUILayout.LabelField("Character Sequence (Decimal)", EditorStyles.boldLabel);
    51.             EditorGUILayout.TextArea(m_charsRange);
    52.             EditorGUILayout.EndScrollView();
    53.         }
    54.         #endregion
    55.         #region Helper Static Functions
    56.         public static string PickAllCharsRangeFromFont(Font p_font)
    57.         {
    58.             string v_charsRange = "";
    59.             if (p_font != null)
    60.             {
    61.                 TrueTypeFontImporter v_fontReimporter = null;
    62.                 //A GLITCH: Unity's Font.CharacterInfo doesn't work
    63.                 //properly on dynamic mode, we need to change it to Unicode first
    64.                 if (p_font.dynamic)
    65.                 {
    66.                     var assetPath = AssetDatabase.GetAssetPath(p_font);
    67.                     v_fontReimporter = (TrueTypeFontImporter)AssetImporter.GetAtPath(assetPath);
    68.                     v_fontReimporter.fontTextureCase = FontTextureCase.Unicode;
    69.                     v_fontReimporter.SaveAndReimport();
    70.                 }
    71.                 //Only Non-Dynamic Fonts define the characterInfo array
    72.                 Vector2Int v_minMaxRange = new Vector2Int(-1, -1);
    73.                 for (int i = 0; i < p_font.characterInfo.Length; i++)
    74.                 {
    75.                     var v_charInfo = p_font.characterInfo[i];
    76.                     var v_apply = true;
    77.                     if (v_minMaxRange.x < 0 || v_minMaxRange.y < 0)
    78.                     {
    79.                         v_apply = false;
    80.                         v_minMaxRange = new Vector2Int(v_charInfo.index, v_charInfo.index);
    81.                     }
    82.                     else if (v_charInfo.index == v_minMaxRange.y + 1)
    83.                     {
    84.                         v_apply = false;
    85.                         v_minMaxRange.y = v_charInfo.index;
    86.                     }
    87.                     if (v_apply || i == p_font.characterInfo.Length - 1)
    88.                     {
    89.                         if (!string.IsNullOrEmpty(v_charsRange))
    90.                             v_charsRange += "\n,";
    91.                         v_charsRange += v_minMaxRange.x + "-" + v_minMaxRange.y;
    92.                         if (i == p_font.characterInfo.Length - 1)
    93.                         {
    94.                             if (v_charInfo.index >= 0 && (v_charInfo.index  < v_minMaxRange.x || v_charInfo.index > v_minMaxRange.y))
    95.                                 v_charsRange += "\n," + v_charInfo.index + "-" + v_charInfo.index;
    96.                         }
    97.                         else
    98.                             v_minMaxRange = new Vector2Int(v_charInfo.index, v_charInfo.index);
    99.                     }
    100.                 }
    101.                 // Change back to dynamic font
    102.                 if (v_fontReimporter != null)
    103.                 {
    104.                     v_fontReimporter.fontTextureCase = FontTextureCase.Dynamic;
    105.                     v_fontReimporter.SaveAndReimport();
    106.                 }
    107.             }
    108.             return v_charsRange;
    109.         }
    110.         #endregion
    111.     }
    112. }
    113.  
    114.  
     
    Last edited: Jan 25, 2019
    Neohun, TheAshenWolf and TylerJoGames like this.
  2. Stephan_B

    Stephan_B

    Joined:
    Feb 26, 2017
    Posts:
    6,595
    At some point, I do plan to update the Font Asset Creator to show valid unicode ranges available for a selected font file.
     
    Rafael_CS likes this.
  3. TylerJoGames

    TylerJoGames

    Joined:
    Oct 9, 2018
    Posts:
    17
    Thank you this is so useful!
     
    Rafael_CS likes this.
  4. Gillissie

    Gillissie

    Joined:
    May 16, 2011
    Posts:
    305
    I know this is an old thread, but I need to get characters from a font for a different reason.
    I use text files to store font characters for 2 reasons:
    1. Generate the font from those characters.
    2. Use those characters to validate input fields to only allow those characters to be input, to prevent input of characters that can't be displayed.
    When it comes to Japanese fonts, I need to get all the characters in the font so I can add them to a text file for both those reasons. I don't need the unicode numbers, I need the characters themselves.
    It would be super awesome if TMP had a utility to extract characters this way.
     
  5. Gillissie

    Gillissie

    Joined:
    May 16, 2011
    Posts:
    305
    Here is the key piece of code needed for me to get what I needed, in case anyone was searching for the same thing:

    Code (CSharp):
    1. string unicodeString = char.ConvertFromUtf32(characterInfo.index);