Suggestion: Add String::CharPointerType overload to graphics DrawText routines


#1

It would be very useful in some scenarios to be able to pass a StringRef to the DrawText routines when pushing a lot of text, thus not incurring a memory allocation/deallocation. This would have to extend to the Glyph code as well.

Since StringRef is only usable for UTF-8 users, a String::CharPointerType could be used instead. This would provide the const methods required to build the Glyphs and be very efficient.


#2

In general the places where I’ve used a const String& instead of a StringRef are ones where internally the function needs to use a String (e.g. to do a bit of manipulation). In those cases a StringRef would be the worst way to pass it.

Not sure if this is one of those places, but TBH it’d be a very minor optimisation even if it could be done, as the string allocation is a tiny fraction of the work incurred in building a glyph table and rendering it!


#3

Generally, I understand/agree with using a const String&, but because you are passing const String&, the StringRef or CharPointerType provide all of the const methods you need (length & []).

Also, I did preface this saying certain scenarios need this. The case that I have run into in JUCE and my previous platform is trying to push lots of numeric data into a Table at very high frame rates. The first optimization is to remove the component structure of the table (build a native data grid), which is the big hitter, but as you dig deeper, the constant allocations become an issue at high rates. Again, this is a very specific use case, and what you have done is excellent, and I am in no way saying something is wrong, just looking at incremental improvements.

Another option I have played with is re-doing JUCE String to use a different implementation more like the std::string implementation. With a SSO (small string optimization) in place, there are no allocations for these small strings since they can sit on the stack. I have had issues getting this in place though, as I am still learning parts of JUCE where the changes propagate to (removing ref count ripples around). The unit tests are helping though.


#4

Yeah, something we’ve been meaning to try here is to change String use a std::string internally as its storage, now that the standard library implementations finally all have highly-optimised implementations


#5

I tried starting with std::string as the implementation, but had issues because all of the JUCE code is actually in the CharPointerType vs string, and there is no way to set the length of a std::sting (if you write into the buffer manually).

I have implemented this code before, so have a version that is loosely based on std::string. The String is working, just have to deal with the ripples. If I get it working, I would be happy to share it with you, and you can massage as you see fit.