SDL_ttf: Use unique font generations for all fonts

From 94dbe5b6b3ea898f55ca2d89be9ccc2276278320 Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Mon, 17 Feb 2025 08:22:39 -0800
Subject: [PATCH] Use unique font generations for all fonts

It's possible that new font pointers can be identical to previously closed fonts, depending on the memory allocator. We use a global font generation to uniquely identify any given font generation.

Fixes https://github.com/libsdl-org/SDL_ttf/issues/511
---
 src/SDL_ttf.c | 17 ++++++++++++-----
 1 file changed, 12 insertions(+), 5 deletions(-)

diff --git a/src/SDL_ttf.c b/src/SDL_ttf.c
index ea9edfc1..5f7dec7e 100644
--- a/src/SDL_ttf.c
+++ b/src/SDL_ttf.c
@@ -378,6 +378,7 @@ static struct
 {
     SDL_InitState init;
     SDL_AtomicInt refcount;
+    SDL_AtomicInt generation;
     SDL_Mutex *lock;
     FT_Library library;
 } TTF_state;
@@ -409,6 +410,15 @@ typedef enum {
         false, 0, NULL, NULL
 
 
+static Uint32 TTF_GetNextFontGeneration(void)
+{
+    Uint32 id = (Uint32)SDL_AtomicIncRef(&TTF_state.generation) + 1;
+    if (id == 0) {
+        id = (Uint32)SDL_AtomicIncRef(&TTF_state.generation) + 1;
+    }
+    return id;
+}
+
 static bool Find_GlyphByIndex(TTF_Font *font, FT_UInt idx, int want_bitmap, int want_pixmap, int want_color, int want_lcd, int want_subpixel, int translation, c_glyph **out_glyph, TTF_Image **out_image);
 
 #if defined(USE_DUFFS_LOOP)
@@ -2056,7 +2066,7 @@ TTF_Font *TTF_OpenFontWithProperties(SDL_PropertiesID props)
     font->src = src;
     font->src_offset = src_offset;
     font->closeio = closeio;
-    font->generation = 1;
+    font->generation = TTF_GetNextFontGeneration();
 
     if (existing_font) {
         if (existing_font->name) {
@@ -2502,10 +2512,7 @@ static void Flush_Cache(TTF_Font *font)
     }
     font->positions = NULL;
 
-    ++font->generation;
-    if (font->generation == 0) {
-        ++font->generation;
-    }
+    font->generation = TTF_GetNextFontGeneration();
 }
 
 static bool Load_Glyph(TTF_Font *font, c_glyph *cached, int want, int translation)