Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by janzdott · Jul 11, 2013 at 11:00 AM · guifontfontsize

How to determine font metrics?

Hello, I'm currently making a GUI framework and doing all the rendering with the GL class. To render text, I use GL and the CharacterInfo class, which works very well. The hard part is, how do I go about formatting the text? I need access to the font metrics (baseline, ascend, descend etc) so I know where the top, bottom and baseline of the font is. I think it's actually pretty absurd that Unity doesn't provide access to these values, since they are used under the hood already.

So does anybody know if there is a way I can access them? Maybe via Reflection? Because if I can't, my only option would be to write an AssetPostProcessor and read the actual font file, then store the metrics in a ScriptableObject, which is a pretty ugly solution. And would also cause problems when the user tries to use one of Unity's fonts.

I would like to avoid doing that, but I'll probably end up having to. Everything in Unity ends up an ugly mess for me because of all the limitations. But if anyone has any insight that would be great!

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

1 Reply

· Add your reply
  • Sort: 
avatar image
1
Best Answer

Answer by janzdott · Jul 12, 2013 at 08:05 PM

I just threw together a method which should provide a less ugly solution. The method determines the normalized ascend and descend metrics for a given font. The results aren't exact, but they should be very close. Close enough to allow me to implement good text formatting in my GUI framework. For Arial, it figures the ascend and descend to be approximatedly 0.774 and 0.226 respectively. And the code is below.

 public static void GetFontMetrics(Font font, int fontSize) {
             //Get a string containing all characters
             StringBuilder stringBuilder = new StringBuilder();
             for (int i = 32; i < 127; i++) {
                 stringBuilder.Append((char)i);
             }
             string allCharacters = stringBuilder.ToString();
 
             //Make sure all characters are included in font texture
             font.RequestCharactersInTexture(allCharacters);
 
             //Dictionary keeps track of each different baseline, and how many characters use it
             Dictionary<float, int> baseLines = new Dictionary<float, int>();
 
             //The height of the highest and lowest characters
             float highest = float.NegativeInfinity;
             float lowest = float.PositiveInfinity;
 
             //Loop through all characters
             for (int i = 0; i < allCharacters.Length; i++) {
                 CharacterInfo info;
                 bool exists = font.GetCharacterInfo(allCharacters[i], out info, fontSize);
 
                 //Make sure character exists in font texture
                 if (exists) {
                     //Pixel values for top and bottom of character
                     float bottom = info.vert.height + info.vert.y;
                     float top = info.vert.y;
 
                     //Add bottom of character to baselines
                     if (baseLines.ContainsKey(bottom)) {
                         baseLines[bottom]++;
                     }
                     else {
                         baseLines[bottom] = 1;
                     }
 
                     //Is this the highest or lowest character so far?
                     if (top > highest) {
                         highest = top;
                     }
                     if (bottom < lowest) {
                         lowest = bottom;
                     }
                 }
             }
 
             //Loop through all different baselines.
             //The one used the most is the baseline
             int highestBaseLineCount = 0;
             float baseLine = 0;
             foreach (KeyValuePair<float, int> pair in baseLines) {
                 if (pair.Value > highestBaseLineCount) {
                     highestBaseLineCount = pair.Value;
                     baseLine = pair.Key;
                 }
             }
 
             //Calculate metrics
             float ascend = (highest - baseLine) / (highest - lowest);
             float descend = (baseLine - lowest) / (highest - lowest);
 
 
             Debug.Log(string.Format("Ascend: {0}", ascend));
             Debug.Log(string.Format("Descend: {0}", descend));
         }
Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

15 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Subscripts and superscripts in Unity new GUI 2 Answers

Change Font Size of GUI Table 0 Answers

Fonts in Android... 0 Answers

GUIBox fontSize without changing other labels? 3 Answers

How do I increase font size properly? 4 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges