RetroPie / EmulationStation

A Fork of Emulation Station for RetroPie. Emulation Station is a flexible emulator front-end supporting keyboardless navigation and custom system themes.
Other
863 stars 344 forks source link

Fix Font (texture) handling #882

Open o-p-a opened 4 months ago

o-p-a commented 4 months ago

When ES renders characters on the screen, it first uploads the glyphs to a texture and caches them. The size of each texture is 2048x512, and when one is used up, allocate another texture and used. If you are an alphabetic region, you probably won't need multiple textures. For example users East Asian countries who use Chinese characters, one texture is often not enough. (This is even more noticeable on high-resolution displays, where one character has more pixels.) When this happens, ES will not work properly. This PR will fix this.


In TextComponent, the text to be drawn is stored in the TextCache. If the glyphs used in the text span multiple textures for the reasons mentioned above, there will be more than one VertexList holding the vertices and textureId. This is constructed by Font::buildTextCache(), and the result of the calculation is set to cache->vertexLists at the end of the function, but the increment of i is forgotten and it is only stored in the first element. As a result, ES will abort. I will correct this by incrementing i appropriately.

However, this alone will not result in correct drawing.

Because, when (reasons mentioned above) a new texture is pushed back into mTextures, reallocation occurs when the std::vector is resized elements, and the texture is destroyed even if it is in use. FontTexture has a default copy ctor and dtor, so they are called when reallocate. The ctor simply copies the members, and the dtor destroys the associated texture. ...Oh, I just wanted to reallocate it, but it destroyed the texture!

I considered defining an appropriate copy constructor to fix this, but unfortunately mTextures[].textureId is referenced by pointer from the TextCache's vertexLists, so even if I did that, it would be necessary to update the TextCache's pointer every time mTextures is reallocated.

It's a bit of a hasty job, but I reserved 10 elements when generating the Font to prevent rearrangement. I think 10 is a sufficient number even in kanji-using countries. I also set up a guard to prevent any attempt to exceed 10.

pjft commented 4 months ago

I like this intent, thank you! Can we get this to be tested out by folks in the forums, hopefully even folks who'd use East Asian characters? I'm away for a few weeks, so I really won't be able to test this (well, I also wouldn't be using the character set for it), but I appreciate putting this together as it is indeed an issue for such character sets.

Thanks.

o-p-a commented 4 months ago

Thank you for reply! I have created this thread on the forum. I hope it will be merged once it is confirmed as OK.

pjft commented 4 months ago

Thanks. Let me know how it goes, otherwise I'll ping this in September and we'll take it from there.