font problem and ttf support

Nowadays, I develop a game which need custom font(ttf) to print the text in the game.
But now, orx doesn't support ttf. I think it is somewhat reasonable since ttf parsed may affect the performance of the game. The solution to replace this feature is using orxFontGen to generate a bitmap as a custom font. But the problem is the size of the letters in the bitmap is not the same. Some letters need a broad width while some need a narrow width relatively. now if every letter is the same, the space between letters will be broad, and have a bad effect to the beauty of the game.
my solution is to store every letter's width(get from ttf face's glyph advance) in the font section in config. and display every letter according to it. To realize it the places to modify include the orx lib, plugins, and the font gen tool.
I think I could complete this modification for orx by myself. But Before I work on it, I want to ask you is there any better solution to this issue. If agree with it, I will modify them. and hope to sync with thunk.
Maybe another solution to this is to realize ttf support. But it seems cost more time.


  • edited April 2011
    As you experienced, orx only supports monospaced fonts. Being able to read ttf fonts or not is a separate issue. Currently, orx font module and display plugins expect only characters of the same size.
    Changing orxFontGen to generate characters with different sizes isn't a big issue. Nor is adapting the internal code for storing width for each character than globally.
    The big problem that prevented me from supporting non-monospaced fonts is how to describe a different width for each character in config file.

    I could only think of two options, both of which have very strong limitations.
    If you can think of a way to overcome that very specific problem (ie. how to describe each character width in config that would work for all cases), supporting non-monospaced fonts will be very easy. :)
  • edited April 2011
    iarwain wrote:
    I could only think of two options, both of which have very strong limitations.
    If you can think of a way to overcome that very specific problem (ie. how to describe each character width in config that would work for all cases), supporting non-monospaced fonts will be very easy. :)

    I don't know whether I understood you correctly, but could it be something like this?

    Texture = path
    CharacterList = "IJK"
    CharacterSize = (5,20,0)#(10,20,0)#(10,20,0)
  • edited April 2011
    That was one of the options I could think of.

    Unfortunately this one, in addition of not being very human readable for people wanting to create bitmap fonts manually (ie. that are not based on ttf), limits the numbers of charaters to 255 (you can't have more than 255 items in a config list).

    As you know very well, it's not much a limitation for short latin-like alphabets but gets more tricky for languages such as Chinese.

    The other option would have been to have a collection of key-value pairs for all the defined characters (i = (5, 20, 0), ...) but that wouldn't work for special config characters such as ';', '=', ...
  • edited April 2011
    hum... I see.
    So the first option is dicarded.

    What if you define an escape sequence for those special chars in the second option? Something like

    i = (5,20,0)
    ; = (5,20,0)
    = = (10,20,0)

    To make things uniform you could require that all chars must have the escape char preceding them. Like

    i = (5,20,0)
    ; = (5,20,0)
    = = (10,20,0)
  • edited April 2011
    That could be an option. I thought of it at some point but I wasn't comfortable with the idea of making changes in the config parser for only one use case in a totally independent module.

    I could also go with the "none" markers used for block values and have block keys. Maybe that would be more homogeneous. That would make the parsing verification more complex though.

    For now I just commited a change that allows 65535 values per list without changing the memory footprint by packing some fields for the config value structure. Accessing long lists are more costly than short lists, but in the case of fonts, we only access the list when loading a font so that shouldn't matter at all.
    I'll add non-monospaced font support, including the orxFontGen tool, whenever I get some time, probably in the coming days.
    I'll try to keep the font definition compatible with what is used now so that people won't need to make any change to their code/config when using monospaced fonts.
  • edited April 2011
    the size of Charateristics in Chinese is almost the same. so the problem is not so obvious when using Chinese font. but problems is some English-like Font.
    I think the second suggestion given by Peso is good but I think if do it like that, the key in the config will be too long to manage it difficultly and waste more storage.

    Besides,I believe the first option is better and it is the way I want to realize. the number of Characters in a font are so many that users is difficult to manage it manually. Not many people likes to modify this long config manually. Therefore, the best way to do this feature is to use the font gen tool.

    the other issue is the difference between each letter would be only the width of letter, the height could still be the same. Therefore the array we only need to record is the widths.

    Moreover, the list could be still limited to 255.
    you could use CharacterWidth[Int] meanwhile CharacterWidth2,CharacterWidth3,.....if the charaters is more than 255.

    the example is like this:
    Texture = path
    CharacterList = "....." (more than 255)
    CharacterSize = (32,32,0)
    CharacterWidth1 = (5,20,0)#(10,20,0)#(10,20,0)#.....(255 times)
    CharacterWidth2 = (x,y,0)#.....

    Thanks for your help...
    and best wishes to your family and your mother. And I believe they include your father will be proud of you.
  • edited April 2011
    I regret to not have taken enough time to show him my work, but now it's too late anyway, so no need to think about what could have been done differently.

    As for non monospaced-fonts, orx now support them. It's 4 AM here, and I just finished writing the code so there might be some bugs in it. :)

    I haven't updated the orxFontGen tool yet, I'll try to do it soon (but not tonight, I need some rest ^^).

    Here's how it works:

    If CharacterSize is defined, the font will be monospaced and nothing changes.
    If it's not defined, orx will look for CharacterHeight and CharacterWidthList.
    The first one is a single float value whereas the second one is a list of all the character widths. It'll only work if the list contains one width for each character defined in the CharacterList string. The lists can now go up to 65535 values so we should be fine. :)
  • edited April 2011
    Thanks for your work and passion.
    Pay attention to your health. don't be so tired.
    nowadays, gmail in China is crazy slow, so I post some question here.
  • edited April 2011

    And it's better to ask questions here anyway so that it benefits to everybody. :)

    orxFontGen can now generate both monospace and non-monospace fonts. You can also add padding to the characters themselves, which might turn useful for non-monospace fonts when you don't want the characters to be glued together.
    orxFontGen --help will provide details about the new parameters (-m / -p).
    Let me know if you get any issues.

    EDIT: I only commited the windows binaries, if you want to run it on linux/mac you'll need to compile it yourself and replace liborx(d).a in the /lib folder with one you compiled yourself with static debug/release targets (non-embedded).
  • edited April 2011
    Mmh, after checking with different fonts, character spacing doesn't look always right. I'll check that tonight.
  • edited April 2011
    Ok, found the issue: some fonts are using a negative left position for glyphs which could make sense for some cursive ones but are just plain lazyness from the font designer most of the time.
    The bad news is that orx will not support backward glyph positionning which might introduce extra spaces visually when the advance component has been artificially extended. The reason for that is that we use a triangle strip for text display and going backward will have both a memory and CPU impact.
    To work around badly designed font, I'll introduce a packed mode in orxFontGen that will pack glyphs as much as possible and use the padding for extra spacing. That will be the default mode but I'll add a switch (-a) to use the exact glyph advance value instead. Should be ready shortly.
  • edited April 2011
    I tried the new font tool. no any Character printed in the output bitmap file.
    the ttf I use is Materhorn.ttf
  • edited April 2011
    With Matterhorn.ttf found on and orxFontGen.exe from the svn:

    orxFontGen.exe -f Matterhorn.ttf -t doxyfile -o Matterhorn -s 32

    [2011-04-15 13:44:54] <LOG> [OUTPUT]  Using output font name 'Matterhorn'.
    [2011-04-15 13:44:54] <LOG> [SIZE]    Character size set to '32'.
    [2011-04-15 13:44:54] <LOG> [FONT]    Using font 'Matterhorn.ttf'.
    [2011-04-15 13:44:54] <LOG> [LOAD]    'doxyfile': added 93 characters.
    [2011-04-15 13:44:54] <LOG> [LOAD]    'doxyfile': SUCCESS.
    [2011-04-15 13:44:54] <LOG> [MODE]    Output mode set to non-monospace.
    [2011-04-15 13:44:54] <LOG> [PACKING] Characters will be packed.
    [2011-04-15 13:44:54] <LOG> [PROCESS] Calculated character size:      25 x 32.
    [2011-04-15 13:44:54] <LOG> [PROCESS] Calculated character spacing:    2 x 2.
    [2011-04-15 13:44:54] <LOG> [PROCESS] Calculated texture size:       241 x 204.
    [2011-04-15 13:44:54] <LOG> [PROCESS] 93 glyphs generated in 'Matterhorn.tga'.
    [2011-04-15 13:44:54] <LOG> [SAVE]    'Matterhorn.ini': SUCCESS.

    CharacterList = " !"none"#$&'()*+,-./0123456789:;<=>@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~"
    CharacterWidthList = 25#7#9#20#13#16#4#8#8#11#15#4#9#5#12#15#10#16#15#17#16#16#15#16#15#5#5#16#15#16#22#16#14#14#15#16#15#15#15#6#14#17#16#19#14#15#15#14#14#18#17#14#15#25#17#17#16#10#12#9#15#19#9#13#12#12#12#12#12#13#12#4#11#14#13#15#11#12#12#11#12#14#13#11#13#20#14#13#13#9#5#9#16
    CharacterHeight = 32
    CharacterSpacing = (2, 2, 0)
    Texture = Matterhorn.tga

    Texture (had to convert it to PNG and negate it so that it can be viewed in the forum):

    Which version did you use? The windows one from the svn or one you compiled yourself?
  • edited April 2011
    but mine is like this...
    no any font shown
    I display tga in photoshop then change it to png

    I use the svn binary in window.
  • edited April 2011
    I follow orx development for some time.
    I tested the new orxFontgen from svn and it works on windows 7 64bit, with Matterhorn.ttf and the 26 standard latin characters.

    EDIT: FYI: I used Imagemagick to convert to png.
    orxFontGen.exe -f Matterhorn.ttf -t char.txt -o Matterhorn -s 32
    [2011-04-15 07:51:26] <LOG> [OUTPUT]  Using output font name 'Matterhorn'.
    [2011-04-15 07:51:26] <LOG> [SIZE]    Character size set to '32'.
    [2011-04-15 07:51:26] <LOG> [FONT]    Using font 'Matterhorn.ttf'.
    [2011-04-15 07:51:26] <LOG> [LOAD]    'char.txt': added 26 characters.
    [2011-04-15 07:51:26] <LOG> [LOAD]    'char.txt': SUCCESS.
    [2011-04-15 07:51:26] <LOG> [MODE]    Output mode set to non-monospace.
    [2011-04-15 07:51:26] <LOG> [PACKING] Characters will be packed.
    [2011-04-15 07:51:26] <LOG> [PROCESS] Calculated character size:      20 x 32.
    [2011-04-15 07:51:26] <LOG> [PROCESS] Calculated character spacing:    2 x 2.
    [2011-04-15 07:51:26] <LOG> [PROCESS] Calculated texture size:       108 x 136.
    [2011-04-15 07:51:26] <LOG> [PROCESS] 26 glyphs generated in 'Matterhorn.tga'.
    [2011-04-15 07:51:26] <LOG> [SAVE]    'Matterhorn.ini': SUCCESS.
  • edited April 2011
    @Waldvogel Hi and welcome. Thank you for testing on win7 64b! :)

    @laschweinski Your picture looks a lot like what happens when an image viewer doesn't know how to deal with TGA files that contain an alpha channel. What is the viewer you used for the conversion? Have you tried with something like xnview (free viewer/converter at
  • edited April 2011
    I use adobe photoshop as a viewer..

    then after use the convert is ok now.
    I haven't opened tga before in win xp.
    most of time I am in ubuntu.
  • edited April 2011
    Is there a way to control the width of the space character? I used the fontgen and everything is working pretty well except the space char that is too wide.
  • edited April 2011
    ah yes, I used the largest char size for characters with no ink data (such as char). I wrote some code to always use the advance info, even in packed mode for those characters but I didn't commit it and forgot about it.
    I'll check that in later today.
  • edited May 2011
    I tried your newest font system.
    the width between the letter have been solved, but the letter height still has error.
    as the picture I paste below

    it seems all letter are aligned to the top line rather than the base line. it seems need a height params for every letter to present y of baseline. 2011_05_04_230717_403x112_scrot.png
  • edited May 2011
    The tool is using the baseline, otherwise, in the previous font I pasted here, you'd see all the characters aligned up, including '_', ',' and '.'.

    Can you provide me with the .ttf you used?
  • edited May 2011
    I use Redocn.otf, seems not a standard ttf.
    I have tried Matterhorn.ttf is ok ths position of the baseline is corrected.
    I am wondering what is the difference between the two formats.
  • edited May 2011
    My guess is that it comes from what the ascender means in the font file. As seen on FreeType2's site:
    The ascender is the vertical distance from the horizontal baseline to the highest ‘character’ coordinate in a font face. Unfortunately, font formats define the ascender differently. For some, it represents the ascent of all capital latin characters (without accents), for others it is the ascent of the highest accented character, and finally, other formats define it as being equal to bbox.yMax.

    That will produce very different results, unfortunately.
  • edited May 2011
    first of all: kudos for implementing support non monospaced fonts!

    I'm having one problem:
    since I use non monospaced fonts I get extrem spaces inbetween words, where there should only be a single space character. In the CharacterWidthList the width for the space character is: 278, when CharacterHeight is 128.
    I'm not sure if I'm supposed to add a space to the list of characters. but even if I don't theres a huge space inbetween words.

    that's the font I'm using:
  • edited May 2011
    tdomhan wrote:
    first of all: kudos for implementing support non monospaced fonts!

    Thanks! =)
    I'm having one problem:
    since I use non monospaced fonts I get extrem spaces inbetween words, where there should only be a single space character. In the CharacterWidthList the width for the space character is: 278, when CharacterHeight is 128.
    I'm not sure if I'm supposed to add a space to the list of characters. but even if I don't theres a huge space inbetween words.

    You have to define the space characters, for sure, otherwise orx doesn't know what to display and it'll just leave a hole (not sure if the length is arbitrary or simply the same as the widest defined character).

    What command line parameter did you use?

    The space size should be the one defined in the font even if you don't provide the -a parameter. By default, if a glyph doesn't draw anything (usually the space character) I'll get its metrics from the font to know how wide it is supposed to be. It's only if I don't find that info that I'll use the widest character's size as value here.

    I'll test it on my side tonight to see how it behaves. :)
  • edited May 2011
    So I just checked the font, and yes the huge value for the space character is given to me by Freetype2, directly from the font metrics. Not much I can do against that, unfortunately.
    I guess you can not declare the space in the list of characters, and add manually at the end of your bitmap (if you're luck in the extra padding there enough space for it so you only need to add it to the 2 config lists). If there isn't enough space at the end of the last line, you'll have to add a full new empty line in your texture but that would be very unlucky. ;)
  • edited June 2011
    If I add a new space to the end of the characters list it will be trimmed by the engine end therefore result in an error. any way to prevent this?

    the ini file looks like:
    CharacterList = "!#%()+,-./0123456789:<=>?ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz "

    however when running the problem this character list will be trimmed to
  • edited June 2011
    I'll check the trimming problem tonight.
  • edited June 2011
    Fixed, sneaky one, thanks for finding it!

    Trailing spaces in config block values will now be conserved and the solution described above should now work for you (I successfully tested it with a custom font here).

    Let me know if you have another issue.
  • edited June 2011
    ok cool thanks for your help!
Sign In or Register to comment.