Author Topic: Dynamic font to NGUI font  (Read 13657 times)

kretin

  • Newbie
  • *
  • Thank You
  • -Given: 1
  • -Receive: 0
  • Posts: 29
    • View Profile
Re: Dynamic font to NGUI font
« Reply #15 on: September 08, 2014, 09:19:27 PM »
Still trying to get this working...

I've tried every test I can think of using an NGUI generated font, and cannot get any alternate space character to display. I've tried different unicode characters U+2009   U+202F  . I've tried using the character in the XML and the HTML code in the XML.

I've repeated my tests as Unity Mesh Text, Photoshop, OpenOffice, and in NGUI as a Unity font and they all show the spaces.

The Custom input box for Font Maker shows the characters there, but whether it's not being compiled or not being read, the character is ignored by NGUI and there is no space between my words.

Please help, I'm at a loss.


ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Dynamic font to NGUI font
« Reply #16 on: September 08, 2014, 09:27:42 PM »
I looked into this and it seems the thin space is not recognized by FreeType, so I went ahead and modified the code to just force a thin space character whether it's there or not. Modify NGUIText.GetGlyph like so:
  1. static public GlyphInfo GetGlyph (int ch, int prev)
  2.         {
  3.                 if (bitmapFont != null)
  4.                 {
  5.                         bool thinSpace = false;
  6.  
  7.                         if (ch == '\u2009')
  8.                         {
  9.                                 thinSpace = true;
  10.                                 ch = ' ';
  11.                         }
  12.  
  13.                         BMGlyph bmg = bitmapFont.bmFont.GetGlyph(ch);
  14.  
  15.                         if (bmg != null)
  16.                         {
  17.                                 int kern = (prev != 0) ? bmg.GetKerning(prev) : 0;
  18.                                 glyph.v0.x = (prev != 0) ? bmg.offsetX + kern : bmg.offsetX;
  19.                                 glyph.v1.y = -bmg.offsetY;
  20.  
  21.                                 glyph.v1.x = glyph.v0.x + bmg.width;
  22.                                 glyph.v0.y = glyph.v1.y - bmg.height;
  23.  
  24.                                 glyph.u0.x = bmg.x;
  25.                                 glyph.u0.y = bmg.y + bmg.height;
  26.  
  27.                                 glyph.u1.x = bmg.x + bmg.width;
  28.                                 glyph.u1.y = bmg.y;
  29.  
  30.                                 int adv = bmg.advance;
  31.                                 if (thinSpace) adv >>= 1;
  32.                                 glyph.advance = adv + kern;
  33.                                 glyph.channel = bmg.channel;
  34.                                 glyph.rotatedUVs = false;
  35.  
  36.                                 if (fontScale != 1f)
  37.                                 {
  38.                                         glyph.v0 *= fontScale;
  39.                                         glyph.v1 *= fontScale;
  40.                                         glyph.advance *= fontScale;
  41.                                 }
  42.                                 return glyph;
  43.                         }
  44.                 }
  45. #if DYNAMIC_FONT
  46. /// ... rest of the code remains unchanged
  47.  

kretin

  • Newbie
  • *
  • Thank You
  • -Given: 1
  • -Receive: 0
  • Posts: 29
    • View Profile
Re: Dynamic font to NGUI font
« Reply #17 on: September 09, 2014, 08:58:11 PM »
Thank you very much. That has got my thin space working, but there's still a bit of a problem...

Where the thin space is used "ShrinkContent" isn't working. It is however still working for labels that don't include the thin space.

kretin

  • Newbie
  • *
  • Thank You
  • -Given: 1
  • -Receive: 0
  • Posts: 29
    • View Profile
Re: Dynamic font to NGUI font
« Reply #18 on: September 09, 2014, 09:13:08 PM »
On a related but different topic, my previous workaround has been to include a middle dot in place of the thin space, and use that instead, but just delete the middle dot from the font atlas. That works, but while it's as small a space as I can get using a character, it is still a larger space than "thin space" so it's not ideal.

I would love to have access to the kerning data of the NGUI font so I could customize the space around the middle dot (as well as other kerning adjustments), kind of like with Unity's bitmap font...

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Dynamic font to NGUI font
« Reply #19 on: September 10, 2014, 01:27:23 AM »
That would be because GetGlyphWidth function above GetGlyph also needs to be modified in a similar fashion.
  1.         /// <summary>
  2.         /// Get the width of the specified glyph. Returns zero if the glyph could not be retrieved.
  3.         /// </summary>
  4.  
  5.         static public float GetGlyphWidth (int ch, int prev)
  6.         {
  7.                 if (bitmapFont != null)
  8.                 {
  9.                         bool thinSpace = false;
  10.  
  11.                         if (ch == '\u2009')
  12.                         {
  13.                                 thinSpace = true;
  14.                                 ch = ' ';
  15.                         }
  16.  
  17.                         BMGlyph bmg = bitmapFont.bmFont.GetGlyph(ch);
  18.  
  19.                         if (bmg != null)
  20.                         {
  21.                                 int adv = bmg.advance;
  22.                                 if (thinSpace) adv >>= 1;
  23.                                 return fontScale * ((prev != 0) ? adv + bmg.GetKerning(prev) : bmg.advance);
  24.                         }
  25.                 }
  26. #if DYNAMIC_FONT
  27.                 else if (dynamicFont != null)
  28.                 {
  29.                         if (dynamicFont.GetCharacterInfo((char)ch, out mTempChar, finalSize, fontStyle))
  30.                                 return mTempChar.width * fontScale * pixelDensity;
  31.                 }
  32. #endif
  33.                 return 0f;
  34.         }
...and while you're there, add it to NGUIText.IsSpace as well:
  1. static bool IsSpace (int ch) { return (ch == ' ' || ch == 0x200a || ch == 0x200b || ch == '\u2009'); }

kretin

  • Newbie
  • *
  • Thank You
  • -Given: 1
  • -Receive: 0
  • Posts: 29
    • View Profile
Re: Dynamic font to NGUI font
« Reply #20 on: September 10, 2014, 08:05:49 PM »
Thanks very much. That's got it ;D

Using your edits, I think I can figure out enough to add a non-breaking thin space too.

Much appreciated.