| Summary: | Font metrics of some glyphs exceed maximum values | ||
|---|---|---|---|
| Product: | SDL_ttf | Reporter: | niektory |
| Component: | misc | Assignee: | Sam Lantinga <slouken> |
| Status: | NEW --- | QA Contact: | Sam Lantinga <slouken> |
| Severity: | normal | ||
| Priority: | P2 | CC: | sylvain.becker |
| Version: | 2.0.15 | ||
| Hardware: | x86_64 | ||
| OS: | Linux | ||
| Attachments: |
The font used
The font used (DejaVuSans) |
||
Created attachment 4441 [details]
The font used
Created attachment 4442 [details]
The font used (DejaVuSans)
I think this is ok. otherwise you would have the rendered text/letter truncated, which would be worse. you may want to check the latest head/dev version: https://hg.libsdl.org/SDL_ttf/ This is problematic mainly because it makes it cumbersome to determine where the baseline is for aligning the text properly. Currently I'm checking the metrics of every glyph in the rendered string one by one and making adjustments based on that, and I'm not even sure if it's reliable. I did check the latest dev version and at first glance it seemed to behave the same. This is what is done in SDL_ttf latest version for rendering a string: you need to check all the glyphs first to make sure the glyph won't be outside the surface. (there was issues in the bug tracker called negative y/x with same problem detected) The other option would be to crop you character. So, just to make sure, this pseudocode is the correct way to do it?
ascent = TTF_FontAscent(font);
descent = TTF_FontDescent(font);
for (i = 0; i < unicode_string.length(); ++i) {
if (TTF_GlyphMetrics(font, unicode_string[i], NULL, NULL, &miny, &maxy, NULL) == 0) {
if (ascent < maxy)
ascent = maxy;
if (descent > miny)
descent = miny;
}
}
return ascent, descent;
The internal code is here: https://hg.libsdl.org/SDL_ttf/file/72b8861dbc01/SDL_ttf.c#l2716 https://hg.libsdl.org/SDL_ttf/file/72b8861dbc01/SDL_ttf.c#l2736 for miny/maxy TTF_SizeUTF8 I think it's easier to call TTF_SizeUTF8() for you case ! (and event easier to call TTF_RenderUTF8()) But TTF_SizeUTF8() or TTF_RenderUTF8() only give me the size. I want to align two strings side by side so their baseline is on the same height. Their size alone doesn't give me enough information because I don't know if it expanded upwards (ascent) or downwards (descent). ok make sense! About your code: I am not 100% sure about it. It probably only involves miny/maxy/ascent/descent. you may only need to compare ascent with miny. find the min of all miny glyphs. if (miny < 0) new_ascent = ascent + abs(miny) I think there should be a function that tells you where the baseline in the rendered string is. My current method doesn't give me confidence, since (ascent-descent==height) is not always true, and it really feels like a hack. |
miny and maxy returned by TTF_GlyphMetrics in some cases exceed the values returned by TTF_FontDescent and TTF_FontAscent. The height returned by TTF_SizeUTF8 in some cases exceeds the one returned by TTF_FontHeight. This should not happen, right? DejaVuSans size 12: TTF_FontDescent = -2; but TTF_GlyphMetrics('p') miny = -3 TTF_FontHeight = 14; but TTF_SizeUTF8('p') = 15 DejaVuSans-Bold size 14: TTF_FontAscent = 13; but TTF_GlyphMetrics('Ö') maxy = 14 TTF_FontHeight = 17; but TTF_SizeUTF8('Ö')=18