TTF_GetFontKerningSize issue

Hello!

I was working with fonts and faced a necessity of obtainig of kerning of glyph pair.
Documentation here: http://www.libsdl.org/projects/SDL_ttf/docs/ gave me no info on it.
So I spent some time to write own routine. When I finally looked into SDL_ttf.c I was quite surprised to find TTF_GetFontKerningSize function.
So the first point about TTF_GetFontKerningSize is old documentation on top of google search. Please, somebody, fix it :slight_smile:
Second point is the fact that TTF_GetFontKerningSize behaviour looks strange (or even incorrect).
That is, it looks like the function takes characters codes and returns pair’s kerning. But it doesn’t.
If you look at the code of this function and at the code of appropriate text rendering function, you may notice that technically
TTF_GetFontKerningSize takes glyph’s indices:

Code:

int TTF_GetFontKerningSize(TTF_Font* f, int prev_index, int index)
{
FT_Vector delta;
FT_Get_Kerning( font->face, prev_index, index, ft_kerning_default, &delta );
return (delta.x >> 6);
}

And those indices cannot be obtained using other API’s functions.
Considering above, I think its body should look like as follows (calculations in double is to increase acuracy :slight_smile: ):

Code:

int TTF_GetFontKerningSize(TTF_Font* f, int p, int c)
{
double res = 0.0;
int glyph_index = -1;
int prev_index = -1;

if(c == UNICODE_BOM_NATIVE || c == UNICODE_BOM_SWAPPED)
{
	return 0.0;
}
if(p == UNICODE_BOM_NATIVE || p == UNICODE_BOM_SWAPPED)
{
	return 0.0;
}

int error = Find_Glyph(f, c, CACHED_METRICS);
if(error)
{
	TTF_SetFTError("Couldn't find glyph", error);
	return -1;
}
glyph_index = f->current->index;

error = Find_Glyph(f, p, CACHED_METRICS);
if ( error )
{
	TTF_SetFTError("Couldn't find glyph", error);
	return -1;
}        
prev_index = f->current->index;

if ( prev_index && glyph_index )
{
	FT_Vector delta;
	FT_Get_Kerning( f->face, prev_index, glyph_index, ft_kerning_default, &delta );
	res = delta.x;
	res /= 64.0;
}

return (int)res;

}

I’ve tried this solution and it looks working.

Thank you for your attention.

Hi, there!

I’m glad that you have spent some effort looking into this issue, as I noticed it, too, but didn’t have the time to investigate).

I can verify the same zero kerning behavior you describe with the official branch, too. Unfortunately, my results do not differ whatsoever when using your patch, though, which brings me to ask a few questions about your testing:

a) What font(s) did you use?
b) What text string(s) did you use?

Cheers,
Jeffrey Carpenter
<@Jeffrey_Carpenter>On 2014/06/ 02, at 11:03, D216 wrote:

Hello!

I was working with fonts and faced a necessity of obtainig of kerning of glyph pair.
Documentation here: http://www.libsdl.org/projects/SDL_ttf/docs/ gave me no info on it.
So I spent some time to write own routine. When I finally looked into SDL_ttf.c I was quite surprised to find TTF_GetFontKerningSize function.
So the first point about TTF_GetFontKerningSize is old documentation on top of google search. Please, somebody, fix it
Second point is the fact that TTF_GetFontKerningSize behaviour looks strange (or even incorrect).
That is, it looks like the function takes characters codes and returns pair’s kerning. But it doesn’t.
If you look at the code of this function and at the code of appropriate text rendering function, you may notice that technically
TTF_GetFontKerningSize takes glyph’s indices:

Code:

int TTF_GetFontKerningSize(TTF_Font* f, int prev_index, int index)
{
FT_Vector delta;
FT_Get_Kerning( font->face, prev_index, index, ft_kerning_default, &delta );
return (delta.x >> 6);
}

And those indices cannot be obtained using other API’s functions.
Considering above, I think its body should look like as follows (calculations in double is to increase acuracy ):

Code:

int TTF_GetFontKerningSize(TTF_Font* f, int p, int c)
{
double res = 0.0;
int glyph_index = -1;
int prev_index = -1;

if(c == UNICODE_BOM_NATIVE || c == UNICODE_BOM_SWAPPED)
{
return 0.0;
}
if(p == UNICODE_BOM_NATIVE || p == UNICODE_BOM_SWAPPED)
{
return 0.0;
}

int error = Find_Glyph(f, c, CACHED_METRICS);
if(error)
{
TTF_SetFTError(“Couldn’t find glyph”, error);
return -1;
}
glyph_index = f->current->index;

error = Find_Glyph(f, p, CACHED_METRICS);
if ( error )
{
TTF_SetFTError(“Couldn’t find glyph”, error);
return -1;
}
prev_index = f->current->index;

if ( prev_index && glyph_index )
{
FT_Vector delta;
FT_Get_Kerning( f->face, prev_index, glyph_index, ft_kerning_default, &delta );
res = delta.x;
res /= 64.0;
}

return (int)res;

}

I’ve tried this solution and it looks working.

Thank you for your attention.


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

Hello again!

Finally conversation :slight_smile:

Answers are:

a) It was “Droid Sans”, “Droid Sans Fallback Full”, “Liberation Serif Regular”, “Sketch Block”, “Times New Roman”, “Times New Roman Cyr Regular”.
b) Main test objects was strings like “WAV” (where ‘V’, ‘A’, ‘W’ follow each other in random way). Also I’ve tested many strings in natural language, including in Russian language.
My custom text rendering routine that uses SDL_ttf for glyph rendering only, renders text pixel-to-pixel exactly as TTF_RenderUNICODE does if I use modified TTF_GetFontKerningSize.

If it matters, I am working on xubuntu 14, SDL_ttf is from repo, plus this modification.

I spent some time looking into my issues, and it turns out that your code does indeed fix the problem for me, too! =D My OS is Mac OS X v10.9.3, so it’s a relief to know that your patch corrects it under both operating systems.

I think my problem might have been not taking point size into consideration, testing it with too small of a font…

I am happy that you filed a bug report (I was going to before noticing yours), and posted a diff patch and commented that it works for me, too. Now all that is left for me to do is pray that it gets pushed upstream sooner than later! :slight_smile:

Cheers,
Jeffrey Carpenter
<@Jeffrey_Carpenter>On 2014/06/ 09, at 14:18, D216 wrote:

Hello again!

Finally conversation

Answers are:

a) It was “Droid Sans”, “Droid Sans Fallback Full”, “Liberation Serif Regular”, “Sketch Block”, “Times New Roman”, “Times New Roman Cyr Regular”.
b) Main test objects was strings like “WAV” (where ‘V’, ‘A’, ‘W’ follow each other in random way). Also I’ve tested many strings in natural language, including in Russian language.
My custom text rendering routine that uses SDL_ttf for glyph rendering only, renders text pixel-to-pixel exactly as TTF_RenderUNICODE does if I use modified TTF_GetFontKerningSize.

If it matters, I am working on xubuntu 14, SDL_ttf is from repo, plus this modification.


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

It has been pushed, thanks!On Thu, Jun 12, 2014 at 4:30 PM, Jeffrey Carpenter wrote:

I spent some time looking into my issues, and it turns out that your code
does indeed fix the problem for me, too! =D My OS is Mac OS X v10.9.3, so
it’s a relief to know that your patch corrects it under both operating
systems.

I think my problem might have been not taking point size into
consideration, testing it with too small of a font…

I am happy that you filed a bug report (I was going to before noticing
yours), and posted a diff patch and commented that it works for me, too.
Now all that is left for me to do is pray that it gets pushed upstream
sooner than later! :slight_smile:

Cheers,
Jeffrey Carpenter

On 2014/06/ 09, at 14:18, D216 wrote:

Hello again!

Finally conversation

Answers are:

a) It was “Droid Sans”, “Droid Sans Fallback Full”, “Liberation Serif
Regular”, “Sketch Block”, “Times New Roman”, “Times New Roman Cyr Regular”.
b) Main test objects was strings like “WAV” (where ‘V’, ‘A’, ‘W’ follow
each other in random way). Also I’ve tested many strings in natural
language, including in Russian language.
My custom text rendering routine that uses SDL_ttf for glyph rendering
only, renders text pixel-to-pixel exactly as TTF_RenderUNICODE does if I
use modified TTF_GetFontKerningSize.

If it matters, I am working on xubuntu 14, SDL_ttf is from repo, plus
this modification.


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org