Author Topic: Text baseline calculation  (Read 4022 times)

Nanaky

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 1
    • View Profile
Text baseline calculation
« on: February 28, 2014, 05:45:26 AM »
Hi ArenMook!

Some time ago, while trying to align text chunks drawn with multiple dynamic fonts (and multiple sizes), I noticed that they did not always line up properly.

You used at the time a hack to try and get a baseline value for the fonts. I was skimming through the code of a recent version of NGUI and saw that you still uses a trick that depends on the specific shape of some characters. That reminded me that I think I found something a bit more reliable back then, but completely forgot to post it on the forum. It may help you, so here it is.

I tried to make sense of the values returned by Unity when using GetCharacterInfo(). The y values seem random, but can be used to get the baseline. For that the space character can be used. (It is rightfully empty in virtually every font, hence more reliable.)

First get the (seemingly arbitrary) y value for the baseline using the space character (once per font per size):
  1. dynamicFont.GetCharacterInfo(' ', out tempChar, size, style);
  2. float baseline = tempChar.vert.y;
  3.  

Then when drawing text,
Get each character offset to the baseline:
  1. dynamicFont.GetCharacterInfo(ch, out tempChar, size, style);
  2. float baselineOffset = tempChar.vert.yMin + tempChar.vert.height - baseline;
  3.  
And compute its vertical position:
  1. v0.y = size - baselineOffset;
  2.  

When drawing this way all the baselines will line up.
   
The calculation of the size of a piece of text also has to be updated, or the descenders of the last line of text won't be taken into account. (Looks like font size is the size from the baseline to the top of the highest ascenders.) For this I haven't found anything great, but one can add the baseline offset of a character with a descender, such as 'j'. :s

Maybe you knew that all along, but just in case. :)

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Text baseline calculation
« Reply #1 on: February 28, 2014, 07:06:45 PM »
The problem is that NGUI doesn't use the baseline the same way as word. In word, all characters originate on the baseline -- that is, all characters seem to "sit" on it. It's fine for printing text, but in case of NGUI all text must fit inside a rectangle defined by the height of the font -- and the best way to do it is to center the printed text. This is what NGUI does -- centers the text, more or less ignoring the unreliable baseline.

I am doing the same thing in 3.5.2 when accessing FreeType directly. Although the baseline is there and I can use it, I pretty much ignore it and calculate my own offset based on the min and max pixels of characters within the font.

mohydine

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 6
    • View Profile
Re: Text baseline calculation
« Reply #2 on: March 09, 2014, 07:42:06 AM »
Hi,

So I having some issues with the baselines too ;)
Here is a rich text editor I am creating for NGUI:
http://forum.unity3d.com/threads/233204-Rich-Text-Editor-for-Unity-Alpha-0-1

And yes baseline is still a bit off but I am working on it. ArenMook, why do you say that the baseline is somehow a bit unreliable?

Stephane

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Text baseline calculation
« Reply #3 on: March 09, 2014, 09:50:57 AM »
When drawing text in the game you get a rectangle into which the text must fit. If the text is centered, it must appear directly in the center. If the text uses a bottom pivot it should appear on the bottom, but still within the bounds of the rectangle. If the text uses a top pivot, it should appear on top, directly below the top edge of the rectangle, but still within the bounds. Neither of these 3 uses the baseline.

I say baseline is unreliable because not all fonts use it, and because the values returned by Unity's dynamic font system make zero sense.