KonajuGames / TrueTypeSharp

Updated version of the original TrueTypeSharp to bring it up to date with stb_truetype.
Other
8 stars 7 forks source link

Kerning/Spacing seems off #3

Open Raflos10 opened 6 years ago

Raflos10 commented 6 years ago

capture

I'm still figuring out how to use this library, but it seems like no matter what I try I can't get the letters spaced consistently. I tried GetGlyphKernAdvance() expecting to get the kerning values, but I tried it with quite a few char combinations and the only two that returned a value other than zero were 'V' and 'A'. I tried both this version and the original TrueTypeSharp (the one that's on nuget) and got the same results.

KonajuGames commented 6 years ago

The MonoGame SpriteFont processor is FreeType, and has been tested to match XNA's SpriteFont processor, which uses Windows GDI+ to rasterize fonts. TrueTypeSharp does not appear to do the exact same spacing and kerning as either GDI or FreeType, and this is likely due to some implementation detail in the original stb version. I haven't looked too closely into it at this stage.

Raflos10 commented 6 years ago

Thanks for the quick response. Since I've been trying to find a font solution, I've come across your name a lot and it seems like you know quite a lot about fonts. Would you happen to have a recommendation for a good method of rendering font in such a way that the quality remains consistent no matter the font size? I'd really appreciate it. I've tried Signed Distance Field fonts, but they require a new spritebatch call for each differently colored text on screen and I ended up with some seriously messy code.

KonajuGames commented 6 years ago

I have implemented SDF before, but not as a direct substitute for SpriteFont. There are other issues to address with them, but that's for another time. Shouldn't need a new sprite batch Begin to change colour though.

Are you trying to rasterize glyphs from the TTF at runtime or during content processing? We know FreeType gives correct spacing results, and TrueTypeSharp should give similar. It is interesting that it seems to return the same kerning values for every character pair except V and A. I might take a look at that.

Raflos10 commented 6 years ago

In case you're curious, for SDF I was using a spritebatch effect someone made specifically for Monogame. The problem was that it didn't process changing the effect's color property until spritebatch End. Even if that weren't a problem it was still messy enough with just the need to call spritebatch separately for fonts.

My plan with TrueTypeSharp was to only rasterize at launch and time the resolution changes in order to keep the font quality as high as possible. When testing though, it seemed to hold it's quality while scaling a lot better than spritefonts. I suspect the kerning function might be the problem since the VA spacing is almost identical in all three examples. Also worth noting that VA has one of the largest kerning offsets. So does "ry", but that returned zero.

Raflos10 commented 6 years ago

capture

After you mentioned the original stb_truetype, I realized I never looked there for this kerning issue, and sure enough someone had the same problem. https://github.com/nothings/stb/issues/281

Evidently it's normal for most kernings to be zero. So for that user and for me, it turned out to be a spacing issue rather than a kerning issue. The key is to increase the current position by the glyph's advance width * scale. Then place the next glyph at that position + the glyph's x offset (x2 in the above thread). I thought this is what I was doing before but I must have messed something up. Anyway, glad that it's fixed now. I appreciate the help!

KonajuGames commented 6 years ago

This was the result of my test using TrueTypeSharp in the MonoGame content processor instead of FreeType (one of them in black, the other in white, can't remember which is which right now). At larger point sizes, it was very close. The smaller the point size, the larger the error became. sfvstts

Raflos10 commented 6 years ago

Yeah there is a slight difference in spacing. It could be due to hinting. But it's not bad at all. I think before I was missing the entire right side bearing since I was calculating it wrong.