| Summary: | SDL2-ttf 2.0.12 - Font rendering: certain glyphs are misplaced. | ||
|---|---|---|---|
| Product: | SDL_ttf | Reporter: | Yohann Ferreira <yohann.ferreira> |
| Component: | misc | Assignee: | Sam Lantinga <slouken> |
| Status: | RESOLVED WORKSFORME | QA Contact: | Sam Lantinga <slouken> |
| Severity: | critical | ||
| Priority: | P2 | CC: | sylvain.becker, yohann.ferreira |
| Version: | unspecified | ||
| Hardware: | x86 | ||
| OS: | Windows (XP) | ||
| Attachments: |
picture showing mainly glyphs with lower part being misplaced (like p, q, ...).
spreadsheet showing differences in glyph metrics between the two versions |
||
|
Description
Yohann Ferreira
2013-09-18 16:51:29 UTC
Fixed the last sentence (I should have reread more carefully, sorry) "This version of the SDL2 libraries are a year old but when using them, glyph rendering on SDL2 is fine. May I assume this is a new bug in SDL_ttf or has the behaviour of certain font metrics function(s) been fixed/changed?" Happens also on Linux (Current Debian Sid) with the same library version. (2.0.12) Hi again, I'm working on analysing the glyph info given for each font and compared them between the 2.0.9 (on SDL1.2) and 2.0.12 (with SDL 2.0.0). As my application is using a glyph cache, all the rendering depends on what is returned by TTF_RenderGlyph_Blended() and TTF_GlyphMetrics(). I also set the hinting to LIGHT and enabled the kerning (doesn't change the rendering if disable both, just in case). The problem now is that the SDL2.0 version doesn't seem to create stdout.txt/stderr.txt anymore on Windows XP si it might take more time. Hi again, I took the time to compare the metrics given by TTF_GlyphMetrics() between 2.0.9 (SDL 1.2) and 2.0.12 (SDL 2.0) You can find the spreadsheet here showing the differences. In short, there are random differences in minx, maxx, maxy, and advance but never in the miny value given. You might want to check how those fields are obtained. Best regards, Created attachment 1411 [details]
spreadsheet showing differences in glyph metrics between the two versions
The SDL_ttf 2.0.9 and 2.0.12 are usually built against different FreeType versions. Can you verify that they're using the same version of FreeType? If so, the differences may be caused by bug-fixes in SDL_ttf since 2.0.9. Hi, What I can tell right away is that SDL_TTF 2.0.9 and 2.0.12 are using the file libfreetype-6.dll as a dependency (on windows). Now, it's not the same file size and creation date at all. Now, when I copied the libfreetype-6.dll file used by SDL_TTF2.0.12 into the SDL-1.2/SDL_TTF-2.0.9 installation on windows, overwriting the previous same-named dll, I had no font display problems there when running the SDL_TTF-2.0.9 app. The opposite cannot be done as the SDL-2.0 app won't start with the libfreetype-6.dll of the former version. Is that a sufficient answer? Best regards, You can also view the differences in dependencies more precisely with the debian pts, or I hope so: http://packages.debian.org/squeeze/libsdl-ttf2.0-0 (2.0.9) -> dep: libfreetype6 (>= 2.2.1) [kfreebsd-amd64, kfreebsd-i386] dep: libfreetype6 (>= 2.3.5) [non kfreebsd-amd64, kfreebsd-i386] http://packages.debian.org/sid/libs/libsdl2-ttf-2.0-0 (2.0.12) -> dep: libfreetype6 (>= 2.2.1) And I must precise the bug is also happening in Debian Sid atm, where I have libsdl_ttf(2.0.11-1) installed with libfreetype6 (>=2.2.1) and libsdl2-ttf(2.0.12-1) with libfreetype6 (>=2.2.1) as a dependency also. I'll check but I bet I'll have the exact same freetype .so file used for both. I hope it'll help you Best regards, Hi again, freetype 2.5.1 is out: http://sourceforge.net/projects/freetype/files/freetype2/2.5.1/ Among other changes, here is what can be read: - In TrueType fonts, hinting of composite glyphs could sometimes deliver incorrect positions of components or even distorted shapes. I do believe it might be linked to this issue. Best regards, Hi again :) Is a SDL_ttf release planned somewhere "soon", or should I rather compile the source myself against the latest libfreetype? This would help me deal with this bug but also with the #2127. Best regards, and... Merry Christmas! Hi again, It seems this issue is linked to the current one: https://bugzilla.libsdl.org/show_bug.cgi?id=2622 I would also like to request that the next libsdl ttf version is linked against the latest freetype version, as 2.4.8 is aging, and several fixes have been made in glyph metrics computation AFAIK. Thanks a lot and best regards, Bertram Hi there, Thanks to the recent work of Authenticate on Valyria Tear about SDL2, he's been able to determine that the 'top_y' or yoffset (in SDL_TTF) glyph value was the root cause of the problem. See here: https://github.com/authenticate/ValyriaTear/commit/a27d740c524facd353a4daa21030c295553aacd8 I'll try to sum up the what happened and what to do fix the problem: Previously, on SDL_TTF 2.0.9 (SDL 1.2): When caching a glyph into a surface/texture, we used to store the top_y value this way: This is just a sampled piece of code but is taken from our actual source the most faithfully possible way: // TTF_Font* font; struct Glyph { SDL_Surface* glyph; ... int minx; int maxx; int miny; int advance; int top_y; } Glyph glyph; char* character = 'j'; int minx = 0, maxx = 0, miny = 0; maxy = 0, advance = 0; TTF_GlyphMetrics(font, character, &minx, &maxx, &miny, &maxy, &advance); glyph.minx = minx; ... glyph.top_y = TTF_FontAscent(font) - maxy; Then, we were using the top_y value to place the texture when drawing, this way: // Where to draw the text (axices (0,0) value pair is top left). int xpos = 50; int ypos = 50; SDL_Rect surf_target; surf_target.x = xpos + glyph.min_x; surf_target.y = ypos + glyph.top_y; Draw() xpos += glyph.advance; This used to work well for us for SDL1.2. But on SDL2.0 / SDL_TTF2.0.12, it seems the top_y value aka the font Ascent minus the maxx of the glyph value was somehow set too low and the higher the glyph is, the lower it would end being displayed for us, giving the results shown on the previous screenshots. Authenticate's work ended up in completely ignoring the maxy and ascent value of the font to place glyphs when rendering and it fixed the problem for us. The rest of the code was basically the same. When looking at the SDL_ttf 2.0.12 code, in SDL_ttf.c line 640. It seems the yoffset value of the glyphs returned by Load_Glyph() is 0 when the font isn't scalable and other more obscure conditions. And this might explain why we had the problem, since we were always assuming the yoffset aka top_y was equal to the ascent - maxy while SDL_TTF is clearly not doing this every time. The problem may also be that in the SDL_TTF previous versions, our fonts were assumed to be scalable and answer the conditions to get a (correct?) yoffset value, while now, we have fonts not considered scalable, to the least. The last problem we have now is that the glyph's kerning is now handled through the undocumented TTF_GetFontKerningSize() function which is unfortunately touched by this bug https://bugzilla.libsdl.org/show_bug.cgi?id=2779 The patch there looks pretty fine AFAIK, btw. Thus, with all those conclusions, may I request you to add the TTF_GetFontKerningSize() to the SDL_TTF documentation? (Or maybe has it got to wait for the next SDL_TTF version?) And consider pushing the patch present in 2779 if it answers the code guidelines and QA tests? Also, do you know where I could grasp some older versions of the SDL_ttf code so that I can have a look at whether some conditions in setting the glyph metrics were changed? Ah, and anyone, feel free to correct me if you see something wrong in what I just wrote. Thanks a lot for reading all this and best regards, Hi, Just quicky read your text. But you are rendering glyph per glyph ! That is already what SDL is doing for you! Cheers, Sylvain Hi Sylvain, :)
> Just quicky read your text. But you are rendering glyph per glyph ! That is already what SDL is doing for you!
Yes, but for the need of our engine, we are storing the glyphs as part of gl texture, explaining our need to somehow extract the per-glyph rendering logic.
This is the fastest way to render text for us.
Of course, if we relied on SDL to render text, I wouldn't care about getting glyph metrics. :)
Regards,
Yohann
Hi there, A final comment to this before closing (Yes, I'm closing this bug :]) http://jcatki.no-ip.org:8080/SDL_ttf/SDL_ttf.html#SEC38 TTF_GLyphMetrics() documentation might need a change as now TTF_RenderGlyph*() do render a glyph already taking in the account the baseline and computing it isn't useful anymore: SDL_Rect rect; int minx,maxy,advance; TTF_GlyphMetrics(font,'g',&minx,NULL,NULL,&maxy,&advance); rect.x=X+minx; //rect.y=Y+TTF_FontAscent(font)-maxy; <---- Now useless SDL_BlitSurface(glyph,NULL,screen,&rect); X+=advance; The latest documentation does state that this needs to be done though: //TTF_Font *font; //SDL_Surface *glyph,*screen; SDL_Rect rect; int minx,maxy,advance; TTF_GlyphMetrics(font,'g',&minx,NULL,NULL,&maxy,&advance); rect.x=X+minx; rect.y=Y-maxy; <--- The font ascent doesn't need to be taken in account anymore according to the doc. SDL_BlitSurface(glyph,NULL,screen,&rect); X+=advance; We could render the text just fine by removing the equivalent to removing -maxx to Y, so the bug isn't a bug anymore, just some outer logic to upgrade. Thanks for your help and patience. |