Author Topic: Inaccurate font positioning  (Read 13955 times)

athos

  • Guest
Inaccurate font positioning
« on: October 15, 2012, 11:35:37 AM »
NGUI does not appear to take the base offset of fonts into account when it renders, so fonts are being positioned outside of the widget bounds. This causes all kinds of yucky alignment issues when swapping between fonts or if trying to programmatically position.

You can see this by using a font like Chalkboard SE, for instance, though most any font will do. Look at the gizmo rectangle for the widget bounds. You'll see a rather large gap above all the characters, and if you draw a "y" or "g" you'll see it drop below the widget bounds.

This overly large top gap is because the base offset of the bitmap font is not being used to center the base of the font within the line bounds. In any font that has characters with descenders, the line height of a font and the base offset are not the same. Unless the base offset is used, font positioning will be all over the place.

Is this a known issue?

Thanks!

athos

  • Guest
Re: Inaccurate font positioning
« Reply #1 on: October 15, 2012, 11:56:46 AM »
When I change the code in Print() and CalculatePrintedSize() to this:

  1. int y = mFont.baseOffset - mFont.charSize;
  2.  

I get results more consistent with what I would expect. Does that seem like the right fix?

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Inaccurate font positioning
« Reply #2 on: October 15, 2012, 12:25:52 PM »
Eh? o_O

Pics of what you mean would be helpful.

athos

  • Guest
Re: Inaccurate font positioning
« Reply #3 on: October 15, 2012, 02:16:42 PM »
I am attaching pics before and after the fix above.

The gist is, without the fix NGUI doesn't position characters fully inside the vertical bounds of a line. If you don't take the base offset into account, you end up with a bunch of extra space at the top and not enough at the bottom.

Put another way, NGUI seems to draw text starting from the bottom of a line instead of using the font's base offset. Using the base offset will vertically position text within the space of a line so that descenders don't make characters exceed the line height.

athos

  • Guest
Re: Inaccurate font positioning
« Reply #4 on: October 17, 2012, 11:21:28 AM »
Did the pics help to clarify the issue? Without the patch, the text is rendered below its base and you can't use the pivot to center it.

I checked out the C++ implementation of BMFont and see that it takes base into account when rendering.

  1. float CFont::GetBottomOffset()
  2. {
  3.         return scale * (base - fontHeight);
  4. }
  5.  
  6. float CFont::GetTopOffset()
  7. {
  8.         return scale * (base - 0);
  9. }
  10.  
  11. void CFont::InternalWrite(float x, float y, float z, const char *text, int count, float spacing)
  12. {
  13. ...
  14.         y += scale * float(base);
  15.  


ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Inaccurate font positioning
« Reply #5 on: October 17, 2012, 01:09:30 PM »
Can you send me the font that you've noticed this issue in? Because none of the fonts I have exhibit this issue. support@tasharen.com

athos

  • Guest
Re: Inaccurate font positioning
« Reply #6 on: October 22, 2012, 12:29:49 PM »
I mailed an example over last week. Let me know if it didn't make it.

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Inaccurate font positioning
« Reply #7 on: October 22, 2012, 05:09:35 PM »
Yup, I got it, thank you. I just haven't had a chance to look into it yet, but I will shortly.

athos

  • Guest
Re: Inaccurate font positioning
« Reply #8 on: October 22, 2012, 05:13:49 PM »
Thanks, just wanted to make sure a spam filter didn't eat it. :-)

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Inaccurate font positioning
« Reply #9 on: October 22, 2012, 08:42:09 PM »
I looked into this, and your fix breaks every single font I have in Windward -- they all start too high after the change.

I have a feeling something is wrong with your font itself.

athos

  • Guest
Re: Inaccurate font positioning
« Reply #10 on: October 22, 2012, 08:57:01 PM »
But of course the change breaks existing font layouts. That's the point. :) Fonts are currently positioned too low and so you've most likely offset them in your layout already to compensate. The fix centers text on the line where it belongs as specified by the bitmap font layout file.

There are 2 things I recommend looking at.

1. Where does the font sit on the line? Notice in my screenshots it's centered after the fix in the widget bounds. Where do your fonts sit within the widget bounds before and after?

2. Review the code. You're not using baseOffset anywhere. Logically, how can your line rendering offsets be correct if you're not using it?

If you're concerned about the breaking nature of this change, that's a separate issue. You could always add a boolean to the font to toggle use of the baseOffset in rendering if you don't want a break, but at least that would give us a way to enable accurate positioning so we can use widget pivots.

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Inaccurate font positioning
« Reply #11 on: October 22, 2012, 09:29:09 PM »
Well then why does every single font I have work and look perfectly fine, and stays within the box outline, but this font you've provided doesn't? Furthermore, I am unable to open the actual font file with the Windows font viewer. It says it's an invalid font file. Unity isn't able to open it either.

athos

  • Guest
Re: Inaccurate font positioning
« Reply #12 on: October 22, 2012, 09:42:01 PM »
What are the base and lineHeight values of your fonts?

As for why you're unable to open the font, the one I sent you was a TTC, which is a collection of TTFs. Macs can open these directly. You have to split a TTC if you want to open it on Windows.

Can you clarify why you believe the base offset is provided by fonts if it doesn't need to be used for rendering?

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Inaccurate font positioning
« Reply #13 on: October 22, 2012, 09:45:47 PM »
I spotted one difference between your font and all my fonts. All the fonts I have used up to date have "lineHeight" and "size" properties match, like so:
  1. info face="Pristina" size=32 bold=1 italic=0 charset="" unicode=1 stretchH=100 smooth=1 aa=1 padding=0,0,0,0 spacing=1,1 outline=0
  2. common lineHeight=32 base=21 scaleW=256 scaleH=256 pages=1 packed=0 alphaChnl=0 redChnl=4 greenChnl=4 blueChnl=4
...however in your size 64 font, "size" is indeed 64, but "lineHeight" is 80!

And just to clarify, I didn't say that baseHeight shouldn't be used. I said that the way it is now seems to work with every single font I have ever tried. Considering that this is the first time such an issue was brought up in almost a year of NGUI's existence, you can probably understand my hesitation to fix something that ain't broke (from my point of view). :)

athos

  • Guest
Re: Inaccurate font positioning
« Reply #14 on: October 22, 2012, 10:00:20 PM »
Size and lineHeight are often different since size is in points and lineHeight is in pixels, and the conversion ratio isn't always 1:1.

I understand your hesitation, but I'm not sure how else to explain the issue. The base is provided by the font specification for a reason, and if you don't use it, fonts won't render in the correct vertical position. Even the original C++ BMFont code uses it.

I can only speculate that this hasn't been brought up before because of the particular fonts people selected or because they just manually positioned the fonts and moved on.

I'll e-mail the example font extracted to TTF.