please add functions below, they can fast cut utf8 string to TextArea or RichText:
typedef void (*TTF_CutUTF8_Callback)(void* data, int width);
int TTF_CutUTF8(TTF_Font *font, const char *text, int max_w, int *text_width, TTF_CutUTF8_Callback callback, void* data)
{
int x, z;
int minx, maxx;
int miny, maxy;
c_glyph *glyph;
FT_Error error;
FT_Long use_kerning;
FT_UInt prev_index = 0;
int outline_delta = 0;
size_t textlen;
int src_len = 0;
int cur_len = 0;
TTF_CHECKPOINTER(text, -1);
/* Initialize everything to 0 */
minx = maxx = 0;
miny = maxy = 0;
/* check kerning */
use_kerning = FT_HAS_KERNING( font->face ) && font->kerning;
/* Init outline handling */
if ( font->outline > 0 ) {
outline_delta = font->outline * 2;
}
/* Load each character and sum it's bounding box */
textlen = SDL_strlen(text);
cur_len = textlen;
src_len = textlen;
*text_width = 0;
x= 0;
while ( textlen > 0 ) {
Uint16 c = UTF8_getch(&text, &textlen);
if ( c == UNICODE_BOM_NATIVE || c == UNICODE_BOM_SWAPPED ) {
cur_len = textlen;
if (callback) callback(data, *text_width);
continue;
}
error = Find_Glyph(font, c, CACHED_METRICS);
if ( error ) {
TTF_SetFTError("Couldn't find glyph", error);
return -1;
}
glyph = font->current;
/* handle kerning */
if ( use_kerning && prev_index && glyph->index ) {
FT_Vector delta;
FT_Get_Kerning( font->face, prev_index, glyph->index, ft_kerning_default, &delta );
x += delta.x >> 6;
}
#if 0
if ( (ch == text) && (glyph->minx < 0) ) {
/* Fixes the texture wrapping bug when the first letter
* has a negative minx value or horibearing value. The entire
* bounding box must be adjusted to be bigger so the entire
* letter can fit without any texture corruption or wrapping.
*
* Effects: First enlarges bounding box.
* Second, xstart has to start ahead of its normal spot in the
* negative direction of the negative minx value.
* (pushes everything to the right).
*
* This will make the memory copy of the glyph bitmap data
* work out correctly.
* */
z -= glyph->minx;
}
#endif
z = x + glyph->minx;
if ( minx > z ) {
minx = z;
}
if ( TTF_HANDLE_STYLE_BOLD(font) ) {
x += font->glyph_overhang;
}
if ( glyph->advance > glyph->maxx ) {
z = x + glyph->advance;
} else {
z = x + glyph->maxx;
}
if ( maxx < z ) {
maxx = z;
}
x += glyph->advance;
if ( glyph->miny < miny ) {
miny = glyph->miny;
}
if ( glyph->maxy > maxy ) {
maxy = glyph->maxy;
}
prev_index = glyph->index;
if ((maxx - minx) + outline_delta > max_w)
break;
*text_width = (maxx - minx) + outline_delta;
cur_len = textlen;
if (callback) callback(data, *text_width);
}
return src_len - cur_len;
}
int TTF_PosUTF8(TTF_Font *font, const char *text, int offset)
{
int x, z;
int minx, maxx;
int miny, maxy;
c_glyph *glyph;
FT_Error error;
FT_Long use_kerning;
FT_UInt prev_index = 0;
int outline_delta = 0;
size_t textlen;
int cur_width = 0;
int tmp = 0;
TTF_CHECKPOINTER(text, -1);
/* Initialize everything to 0 */
minx = maxx = 0;
miny = maxy = 0;
/* check kerning */
use_kerning = FT_HAS_KERNING( font->face ) && font->kerning;
/* Init outline handling */
if ( font->outline > 0 ) {
outline_delta = font->outline * 2;
}
/* Load each character and sum it's bounding box */
textlen = SDL_strlen(text);
x= 0;
while ( textlen > 0 ) {
Uint16 c = UTF8_getch(&text, &textlen);
if ( c == UNICODE_BOM_NATIVE || c == UNICODE_BOM_SWAPPED ) {
continue;
}
error = Find_Glyph(font, c, CACHED_METRICS);
if ( error ) {
TTF_SetFTError("Couldn't find glyph", error);
return -1;
}
glyph = font->current;
/* handle kerning */
if ( use_kerning && prev_index && glyph->index ) {
FT_Vector delta;
FT_Get_Kerning( font->face, prev_index, glyph->index, ft_kerning_default, &delta );
x += delta.x >> 6;
}
#if 0
if ( (ch == text) && (glyph->minx < 0) ) {
/* Fixes the texture wrapping bug when the first letter
* has a negative minx value or horibearing value. The entire
* bounding box must be adjusted to be bigger so the entire
* letter can fit without any texture corruption or wrapping.
*
* Effects: First enlarges bounding box.
* Second, xstart has to start ahead of its normal spot in the
* negative direction of the negative minx value.
* (pushes everything to the right).
*
* This will make the memory copy of the glyph bitmap data
* work out correctly.
* */
z -= glyph->minx;
}
#endif
z = x + glyph->minx;
if ( minx > z ) {
minx = z;
}
if ( TTF_HANDLE_STYLE_BOLD(font) ) {
x += font->glyph_overhang;
}
if ( glyph->advance > glyph->maxx ) {
z = x + glyph->advance;
} else {
z = x + glyph->maxx;
}
if ( maxx < z ) {
maxx = z;
}
x += glyph->advance;
if ( glyph->miny < miny ) {
miny = glyph->miny;
}
if ( glyph->maxy > maxy ) {
maxy = glyph->maxy;
}
prev_index = glyph->index;
tmp = (maxx - minx) + outline_delta;
if (tmp - (tmp - cur_width) / 2 > offset) break;
cur_width = tmp;
}
return cur_width;
}