Can I implement an alternative set of TTF functions?

Hi. I’m a first time poster. I had no idea SDL3 was so close. I haven’t heard anything about shaders so I thought it would be far off

Recently I implemented font loading for my project. TTF didn’t come close to working for me unfortunately so I implemented something with FreeType. It’s fresh in my mind, could I implement an alternative set of functions? I could possibly do it all this weekend. If there are no problems would it be able to launch with SDL3?

The functions would be for people who want to build an atlas and want to load every font in a font file. I could come up with the signatures before I implement it if you want to approve it.

To Submit Code to the Project:

SDL3’s TTF library is maintained on github. From a terminal you can use git to ‘clone’ the source which will make it possible to submit pull requests whenever you feel that your code is ready.
You can also help contribute by submitting “Issues” on the github page if you see a problem or a bug in the source code.

Sure I can submit a pull request. I’m assuming I don’t need to ping anyone here about it. I prefer knowing if the author likes the idea so I don’t write code for nothing. Is there someone I should hear from before writing?

I likely write some code in the morning. I have a pretty good idea of how it’d look like and the functionality is to fullfill a real use case I have

I’m planning to make some pretty significant changes to SDL_ttf for 3.0. If the code you wrote is a modification of SDL_ttf, feel free to submit a PR and I’ll be happy to review it. If it’s a separate set of functions for text with SDL you can of course make your own library and make it available to everyone.

Give me 48hrs I started writing this morning and I think you’ll like it

The code and one example is written in C (it uses TTF_AtlasLoadAll+TTF_DestroyAtlas as a simple solution). I like the C++ implementation more because it uses hashtables and shows how to load fonts into a single texture. Here’s a preview of the c++ example and what I’d add to the TTF header. Tomorrow I’ll clean things up and send a pull request

One of the features that I would like the TTF library to have is the possibility of varying the size of the letters without loading the font again.
I have an MSDF demo implemented but I cannot replace it directly from the code where I use TTF, the demo is opengl and where I use it is a normal sdl window.
Although this is all SDL2

Something like this: TTF_SetFontSize()?
Or on an individual letter basis? There is SDL_RTF that should do that. I don’t know much about that library personally, though.

Nice, I use in my code TTF_OpenFont with every point size i need !
If need 3 point size I call this word 3 times in every draw: I have time penalties or store every size and reuse? any limits in change size?

Having looked a bit into it, SDL_SetFontSize() might not be what you want, it destroys all the old font glyphs to reload the new size. That is a bit of a processing hit if you are resizing the font many times per frame.

It is convenient that you don’t need to know the name of the font you use it on if you store your fonts in a vector/array, though…

ok, then what I would like is to do what I did in the demo… I load a font and changing the size does not penalize the rendering…
MSDF font look like the better aproach then

Can I get some feedback from all of you. The examples should be easy to understand. Here’s the pull request Atlas First Draft by LevoDeLellis · Pull Request #358 · libsdl-org/SDL_ttf · GitHub The C++ example looks like this and the C example looks similar

phreda if the frame/background doesn’t change you can keep the texture around for a while. Maybe you’ll like my atlas code but there’s no kerning and other nice stuff that you get using the original set of functions

I use in a video background and the text with diferent font are animated, not problem loading every font with diferent sizes, but a dinamic size of font be nice.

The second draft is up and I think it’s easy enough to understand

The simple version is to write

fontTexture = TTF_AtlasLoadAll(filename, 16, renderer, &atlas);
//Draw a whole lot

Or you can use the advance functions (C++ version with hashmap) SDL_ttf/examples/Atlas.cpp at main · LevoDeLellis/SDL_ttf · GitHub

The DrawString function at the end shows you how you would use the atlas

Pull request if you want to see it Second Atlas Draft (Implemenattion done, examples/docs can improve) by LevoDeLellis · Pull Request #359 · libsdl-org/SDL_ttf · GitHub

I have a few questions:

  • Is it possible to add padding between the atlas entries to avoid “bleeding effects” (and also at the outermost border to avoid sharp edges) when rendering at a non-1-to-1 scale, or is that not an intended use case?
  • What is the meaning of the IDXor parameter?
  • What is the meaning of the return value from SDL_AtlasPred?

As far as I can see, ids is not actually used for anything useful inside the library itself and is only meant to be used by the user of the library for looking up the glyphs but if one is not careful when selecting the IDXor and SDL_AtlasPred return values it seems like you could run into duplicate id values. This leads me to the first question that popped into my head when I looked at your code:

  • Why do I have to implement the lookup myself? Why isn’t it part of the library?
  • And why do I even need to look up the entries at all? Why doesn’t the library provide the “DrawString” functionality for me?

At first I was confused why the “range length” had to be even but then I realized that you could supply multiple ranges and the “range length” didn’t represent the length of a range. Instead it represents the number of ranges divided by two (because each range is made up of two values). I wonder if the API wouldn’t be easier to understand (and less error prone to use) if you instead used a struct type to store the start and end of each range and let the number passed in as argument represent the number of such range objects in the array.

Just a thought. You say that you like the C++ example more but if you intend this to be part of SDL then perhaps you should mainly focus on making the API easy to use in C because SDL is a C library.

I’ll start with this question first

And why do I even need to look up the entries at all? Why doesn’t the library provide the “DrawString” functionality for me?

That’s a very good question. I have always done the rendering myself and the current TTF doesn’t render for you. It slipped my mind that people may want the library to do this. There would be a struct you have to passed in so it knows how tall lines are, how to treat tabs, etc. but it’s completely do-able

Do people want this? It’s easy enough to include. However I’ll need a hash function and a hash table. I don’t believe this is in SDL3? There are public domain hash functions and a hash table is something I written before. But this may sound much if the library should be slim

For the rest.

  1. It’s expected that you’d load the different sizes, font family, bold, etc then use the atlas. 1:1 is expected
  2. The name explains the meaning but the point is for the above. When the library goes through the font file it’ll add the unicode id to the entry, that’s about 21 bits IIRC. But then you’ll not know the difference between ‘A’ thats bold, ‘A’ that’s from a different font, ‘A’ thats a different size etc. The ID array is 64bits so you can use the high 32 (or 43) to track which font family, size, etc
  3. It’s the ID to put into the ID array with 0 mean not to use the character
  4. Yes you could have duplicates. I’m not sure if that’s a problem in practice
  5. Lets say you only load A-Z a-z and numbers, like a retro game. You could use an array instead of a hash table. I try not to demand which data structure a person uses

At first I was confused why the “range length”

I imagine many C programmers are like me and would push values into an int array and it’s easier to write array.len than array.len/2 (or /3 if youre using the width,height,id version). I think that’s the least error prone solution? Do people prefer using a struct type? Let me know because I’m leaning towards keeping it the current way

Last question: I like the C++ example because C++ has a standard map type which people seen/used before. That version doesn’t scan the array to find letters like the C example did

True, but it does have functions such as TTF_RenderUTF8_Shaded where you can pass a whole string without having to do it one character at a time.

Do people want this?

I don’t know what I want. I haven’t used font atlases before.

It’s easy enough to include. However I’ll need a hash function and a hash table. I don’t believe this is in SDL3?

SDL3 has an internal hash table implementation but I’m not sure whether it’s suitable for this or if it can even be used from SDL_ttf since it’s not part of the public API.

Since you read over the code, off the top of your head how was the readability? Coworkers and friends know my style and rarely have comments. I guess not using an Atlas before made this extra hard to read. Was there anything you heavily disliked?