SDL_ttf icon indicating copy to clipboard operation
SDL_ttf copied to clipboard

Sized String Support = Optimizations

Open manuel-fischer opened this issue 3 years ago • 6 comments

Added sized string support, such that it can be used for example with C++ std::string_view. Introducing an internal StringView struct, that contains a pointer, the size of the string and the encoding.

This allows to reduce string allocations, which were needed to convert to UTF8 and for splitting the strings in wrapped rendering. Instead I have solved both problems by almost always using sized strings and by moving the encoding specific string operations deeper into the call chain.

Also the way how layouting with the position buffer works is changed. The arrays are extracted from the font struct into an own position array, the struct contains a dummy element for ABI stability. The new array-struct is passed as an explicit parameter, which can be left NULL, to avoid allocation in TTF_Size_Internal.

New functions

Each function related to rendering text has added an additional parameter size_t text_size after the text parameter.

  • TTF_Size*_SZ
  • TTF_Measure*_SZ
  • TTF_Render*_Solid_SZ
  • TTF_Render*_Shaded_SZ
  • TTF_Render*_Blended_SZ
  • TTF_Render*_Solid_Wrapped_SZ
  • TTF_Render*_Shaded_Wrapped_SZ
  • TTF_Render*_Blended_Wrapped_SZ

* represents all of TEXT, UTF8, UNICODE

For the documentation of the new functions

For UTF8 and TEXT text_size denotes the number of bytes, for UNICODE it denotes the number of words (number of bytes / 2)

NULL can be passed as a paramter, as long as the size is also 0. The range [text, text+text_size) should be a valid string and thus a valid memory range.

Showfont

Added new command line parameter [-wrap width] which forces to use the *_Wrapped functions with width as the wrapLength parameter.

Problem

One problem, that might need to be discussed is the combinatoric explosion of rendering functions for the different formats.

manuel-fischer avatar Feb 22 '22 19:02 manuel-fischer

The patch does not apply: you generated against an older git revision. It seems like you miss this commit: https://github.com/libsdl-org/SDL_ttf/commit/8368ea92c8bb86d65dd28ba10eeeeecefbd7d214

sezero avatar Feb 22 '22 19:02 sezero

The patch does not apply: you generated against an older git revision. It seems like you miss this commit: 8368ea9

It was a bug, that I have found while rewriting the code, it can be discarded, because I have rewritten that part in the code.

manuel-fischer avatar Feb 22 '22 19:02 manuel-fischer

it can be discarded, because I have rewritten that part in the code.

You should rebase your patchset, instead.

sezero avatar Feb 22 '22 20:02 sezero

I also want to look at this (end of next week probably). Quickly:

  • there are still things commented out you could remove (About pa allocation).
  • do we really need a posbuf array.(is this reallocated more than once, since we use a new one each time). But I may need to read more precisely

1bsyl avatar Feb 23 '22 13:02 1bsyl

  • do we really need a posbuf array.(is this reallocated more than once, since we use a new one each time). But I may need to read more precisely

The array is first used for determining the size and positions of the glyphs (in TTF_Size_Internal), then it is used to render the glyphs into the surface. For wrapped rendering, the array gets reused. But before rendering, with TTF_Size_Internal the width and height of the surface are determined, by currently passing NULL as the array, so no allocations are done here. Also for TTF_SizeUTF8 etc. NULL gets passed to TTF_Size_Internal, such that it is now a little more cheap to call these functions.

Multiple Reallocations do happen for the posbuf, while previously the posbuf is permanently saved in the font and not resized, if it was large enough. But this could be improved by either allocating directly by the amount of glyphs in the string or by rewriting it to not use allocated arrays at and iterate again through the string characters. Note that for the latter, the glyph-lookup would not change, because it is already looked up again, when iterating through the posbuf-array.

manuel-fischer avatar Feb 23 '22 18:02 manuel-fischer

ok, I've looked and tried (but not fully) Just to make sure I saw no regression with some multi lang test I have. I also run a fuzzy test, and it didn't crash.

Maybe not a problem, but there is lot of modification in the wrap version. and there were corner cases and special behavior (with wrap-length == 0 for instance). hope we have no regression.

I see now it decodes unicode and text, instead of converting to utf8, which somehow requires more testing in case of bug. So not sure if this is better. As you said, API is longer with all _SZ variants for string_view.

Measuring the time with some bench, I didn't see a noticeable speed improvement, so I wonder if this worth adding more complexity in sdl_ttf code and if string_view API could just be built on top of RenderUTF8 function.

1bsyl avatar Mar 05 '22 22:03 1bsyl