SDL_ttf: Added support for float point sizes

From 1ed8ed8cce50e744a97264ab5199b04043cf66d4 Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Thu, 26 Sep 2024 22:37:23 -0700
Subject: [PATCH] Added support for float point sizes

---
 examples/glfont.c          | 12 ++++++------
 examples/showfont.c        | 12 ++++++------
 examples/testapp.c         |  4 ++--
 include/SDL3_ttf/SDL_ttf.h | 10 +++++-----
 src/SDL_ttf.c              | 23 ++++++++++++-----------
 5 files changed, 31 insertions(+), 30 deletions(-)

diff --git a/examples/glfont.c b/examples/glfont.c
index b017c880..74574197 100644
--- a/examples/glfont.c
+++ b/examples/glfont.c
@@ -36,7 +36,7 @@
 
 #include <SDL3/SDL_opengl.h>
 
-#define DEFAULT_PTSIZE  18
+#define DEFAULT_PTSIZE  18.0f
 #define DEFAULT_TEXT    "The quick brown fox jumped over the lazy dog"
 #define WIDTH   640
 #define HEIGHT  480
@@ -167,7 +167,7 @@ int main(int argc, char *argv[])
     SDL_GLContext context;
     TTF_Font *font;
     SDL_Surface *text = NULL;
-    int ptsize;
+    float ptsize;
     int i, done;
     SDL_Color white = { 0xFF, 0xFF, 0xFF, SDL_ALPHA_OPAQUE };
     SDL_Color black = { 0x00, 0x00, 0x00, SDL_ALPHA_OPAQUE };
@@ -261,11 +261,11 @@ int main(int argc, char *argv[])
     }
 
     /* Open the font file with the requested point size */
-    ptsize = 0;
+    ptsize = 0.0f;
     if (argc > 1) {
-        ptsize = SDL_atoi(argv[1]);
+        ptsize = (float)SDL_atof(argv[1]);
     }
-    if (ptsize == 0) {
+    if (ptsize == 0.0f) {
         i = 2;
         ptsize = DEFAULT_PTSIZE;
     } else {
@@ -273,7 +273,7 @@ int main(int argc, char *argv[])
     }
     font = TTF_OpenFont(argv[0], ptsize);
     if (font == NULL) {
-        fprintf(stderr, "Couldn't load %d pt font from %s: %s\n",
+        fprintf(stderr, "Couldn't load %g pt font from %s: %s\n",
                     ptsize, argv[0], SDL_GetError());
         cleanup(2);
     }
diff --git a/examples/showfont.c b/examples/showfont.c
index 6e6e4f8e..ed4799f9 100644
--- a/examples/showfont.c
+++ b/examples/showfont.c
@@ -29,7 +29,7 @@
 #include <stdio.h>
 #include <string.h>
 
-#define DEFAULT_PTSIZE  18
+#define DEFAULT_PTSIZE  18.0f
 #define DEFAULT_TEXT    "The quick brown fox jumped over the lazy dog"
 #define WIDTH   640
 #define HEIGHT  480
@@ -77,7 +77,7 @@ int main(int argc, char *argv[])
     TTF_Font *font;
     SDL_Surface *text = NULL;
     Scene scene;
-    int ptsize;
+    float ptsize;
     int i, done;
     SDL_Color white = { 0xFF, 0xFF, 0xFF, SDL_ALPHA_OPAQUE };
     SDL_Color black = { 0x00, 0x00, 0x00, SDL_ALPHA_OPAQUE };
@@ -193,11 +193,11 @@ int main(int argc, char *argv[])
     }
 
     /* Open the font file with the requested point size */
-    ptsize = 0;
+    ptsize = 0.0f;
     if (argc > 1) {
-        ptsize = SDL_atoi(argv[1]);
+        ptsize = (float)SDL_atof(argv[1]);
     }
-    if (ptsize == 0) {
+    if (ptsize == 0.0f) {
         i = 2;
         ptsize = DEFAULT_PTSIZE;
     } else {
@@ -205,7 +205,7 @@ int main(int argc, char *argv[])
     }
     font = TTF_OpenFont(argv[0], ptsize);
     if (font == NULL) {
-        SDL_Log("Couldn't load %d pt font from %s: %s\n",
+        SDL_Log("Couldn't load %g pt font from %s: %s\n",
                     ptsize, argv[0], SDL_GetError());
         cleanup(2);
     }
diff --git a/examples/testapp.c b/examples/testapp.c
index 95f58298..4c92260a 100644
--- a/examples/testapp.c
+++ b/examples/testapp.c
@@ -746,7 +746,7 @@ int main(void)
           saved_curr_size = curr_size;
           font_path = test_fonts[curr_font];
           SDL_Log("TTF_OpenFont: %s", font_path);
-          font = TTF_OpenFont(font_path, curr_size);
+          font = TTF_OpenFont(font_path, (float)curr_size);
           if (!font) {
 #if 1
              quit("Font load failed");
@@ -760,7 +760,7 @@ int main(void)
 
        if (saved_curr_size != curr_size) {
 #if defined(HAVE_SET_FONT_SIZE_FUNCTION)
-          TTF_SetFontSize(font, curr_size);
+          TTF_SetFontSize(font, (float)curr_size);
 #else
           if (font) {
              TTF_CloseFont(font);
diff --git a/include/SDL3_ttf/SDL_ttf.h b/include/SDL3_ttf/SDL_ttf.h
index 86eda398..2677dea0 100644
--- a/include/SDL3_ttf/SDL_ttf.h
+++ b/include/SDL3_ttf/SDL_ttf.h
@@ -158,7 +158,7 @@ extern SDL_DECLSPEC bool SDLCALL TTF_Init(void);
  *
  * \sa TTF_CloseFont
  */
-extern SDL_DECLSPEC TTF_Font * SDLCALL TTF_OpenFont(const char *file, int ptsize);
+extern SDL_DECLSPEC TTF_Font * SDLCALL TTF_OpenFont(const char *file, float ptsize);
 
 /**
  * Create a font from an SDL_IOStream, using a specified point size.
@@ -185,7 +185,7 @@ extern SDL_DECLSPEC TTF_Font * SDLCALL TTF_OpenFont(const char *file, int ptsize
  *
  * \sa TTF_CloseFont
  */
-extern SDL_DECLSPEC TTF_Font * SDLCALL TTF_OpenFontIO(SDL_IOStream *src, bool closeio, int ptsize);
+extern SDL_DECLSPEC TTF_Font * SDLCALL TTF_OpenFontIO(SDL_IOStream *src, bool closeio, float ptsize);
 
 /**
  * Create a font with the specified properties.
@@ -231,7 +231,7 @@ extern SDL_DECLSPEC TTF_Font * SDLCALL TTF_OpenFontWithProperties(SDL_Properties
 #define TTF_PROP_FONT_IOSTREAM_POINTER              "SDL_ttf.font.iostream"
 #define TTF_PROP_FONT_IOSTREAM_OFFSET_NUMBER        "SDL_ttf.font.iostream.offset"
 #define TTF_PROP_FONT_IOSTREAM_AUTOCLOSE_BOOLEAN    "SDL_ttf.font.iostream.autoclose"
-#define TTF_PROP_FONT_SIZE_NUMBER                   "SDL_ttf.font.size"
+#define TTF_PROP_FONT_SIZE_FLOAT                    "SDL_ttf.font.size"
 #define TTF_PROP_FONT_FACE_NUMBER                   "SDL_ttf.font.face"
 #define TTF_PROP_FONT_HORIZONTAL_DPI_NUMBER         "SDL_ttf.font.hdpi"
 #define TTF_PROP_FONT_VERTICAL_DPI_NUMBER           "SDL_ttf.font.vdpi"
@@ -270,7 +270,7 @@ extern SDL_DECLSPEC SDL_PropertiesID SDLCALL TTF_GetFontProperties(TTF_Font *fon
  *
  * \since This function is available since SDL_ttf 3.0.0.
  */
-extern SDL_DECLSPEC bool SDLCALL TTF_SetFontSize(TTF_Font *font, int ptsize);
+extern SDL_DECLSPEC bool SDLCALL TTF_SetFontSize(TTF_Font *font, float ptsize);
 
 /**
  * Set font size dynamically with target resolutions (in DPI).
@@ -289,7 +289,7 @@ extern SDL_DECLSPEC bool SDLCALL TTF_SetFontSize(TTF_Font *font, int ptsize);
  *
  * \since This function is available since SDL_ttf 3.0.0.
  */
-extern SDL_DECLSPEC bool SDLCALL TTF_SetFontSizeDPI(TTF_Font *font, int ptsize, unsigned int hdpi, unsigned int vdpi);
+extern SDL_DECLSPEC bool SDLCALL TTF_SetFontSizeDPI(TTF_Font *font, float ptsize, unsigned int hdpi, unsigned int vdpi);
 
 /**
  * Font style flags
diff --git a/src/SDL_ttf.c b/src/SDL_ttf.c
index 0bb24b91..dd347fc6 100644
--- a/src/SDL_ttf.c
+++ b/src/SDL_ttf.c
@@ -1756,7 +1756,7 @@ TTF_Font *TTF_OpenFontWithProperties(SDL_PropertiesID props)
     SDL_IOStream *src = SDL_GetPointerProperty(props, TTF_PROP_FONT_IOSTREAM_POINTER, NULL);
     Sint64 src_offset = SDL_GetNumberProperty(props, TTF_PROP_FONT_IOSTREAM_OFFSET_NUMBER, 0);
     bool closeio = SDL_GetBooleanProperty(props, TTF_PROP_FONT_IOSTREAM_AUTOCLOSE_BOOLEAN, false);
-    int ptsize = (int)SDL_GetNumberProperty(props, TTF_PROP_FONT_SIZE_NUMBER, 0);
+    float ptsize = SDL_GetFloatProperty(props, TTF_PROP_FONT_SIZE_FLOAT, 0);
     long index = (long)SDL_GetNumberProperty(props, TTF_PROP_FONT_FACE_NUMBER, 0);
     unsigned int hdpi = (unsigned int)SDL_GetNumberProperty(props, TTF_PROP_FONT_HORIZONTAL_DPI_NUMBER, 0);
     unsigned int vdpi = (unsigned int)SDL_GetNumberProperty(props, TTF_PROP_FONT_VERTICAL_DPI_NUMBER, 0);
@@ -1924,34 +1924,34 @@ TTF_Font *TTF_OpenFontWithProperties(SDL_PropertiesID props)
     return font;
 }
 
-TTF_Font *TTF_OpenFont(const char *file, int ptsize)
+TTF_Font *TTF_OpenFont(const char *file, float ptsize)
 {
     TTF_Font *font = NULL;
     SDL_PropertiesID props = SDL_CreateProperties();
     if (props) {
         SDL_SetStringProperty(props, TTF_PROP_FONT_FILENAME_STRING, file);
-        SDL_SetNumberProperty(props, TTF_PROP_FONT_SIZE_NUMBER, ptsize);
+        SDL_SetFloatProperty(props, TTF_PROP_FONT_SIZE_FLOAT, ptsize);
         font = TTF_OpenFontWithProperties(props);
         SDL_DestroyProperties(props);
     }
     return font;
 }
 
-TTF_Font *TTF_OpenFontIO(SDL_IOStream *src, bool closeio, int ptsize)
+TTF_Font *TTF_OpenFontIO(SDL_IOStream *src, bool closeio, float ptsize)
 {
     TTF_Font *font = NULL;
     SDL_PropertiesID props = SDL_CreateProperties();
     if (props) {
         SDL_SetPointerProperty(props, TTF_PROP_FONT_IOSTREAM_POINTER, src);
         SDL_SetBooleanProperty(props, TTF_PROP_FONT_IOSTREAM_AUTOCLOSE_BOOLEAN, closeio);
-        SDL_SetNumberProperty(props, TTF_PROP_FONT_SIZE_NUMBER, ptsize);
+        SDL_SetFloatProperty(props, TTF_PROP_FONT_SIZE_FLOAT, ptsize);
         font = TTF_OpenFontWithProperties(props);
         SDL_DestroyProperties(props);
     }
     return font;
 }
 
-bool TTF_SetFontSizeDPI(TTF_Font *font, int ptsize, unsigned int hdpi, unsigned int vdpi)
+bool TTF_SetFontSizeDPI(TTF_Font *font, float ptsize, unsigned int hdpi, unsigned int vdpi)
 {
     FT_Face face = font->face;
     FT_Error error;
@@ -1961,7 +1961,7 @@ bool TTF_SetFontSizeDPI(TTF_Font *font, int ptsize, unsigned int hdpi, unsigned
         /* Set the character size using the provided DPI.  If a zero DPI
          * is provided, then the other DPI setting will be used.  If both
          * are zero, then Freetype's default 72 DPI will be used.  */
-        error = FT_Set_Char_Size(face, 0, ptsize * 64, hdpi, vdpi);
+        error = FT_Set_Char_Size(face, 0, (int)SDL_roundf(ptsize * 64), hdpi, vdpi);
         if (error) {
             return TTF_SetFTError("Couldn't set font size", error);
         }
@@ -1974,10 +1974,11 @@ bool TTF_SetFontSizeDPI(TTF_Font *font, int ptsize, unsigned int hdpi, unsigned
         }
 
         /* within [0; num_fixed_sizes - 1] */
-        ptsize = SDL_max(ptsize, 0);
-        ptsize = SDL_min(ptsize, face->num_fixed_sizes - 1);
+        int index = (int)ptsize;
+        index = SDL_max(index, 0);
+        index = SDL_min(index, face->num_fixed_sizes - 1);
 
-        error = FT_Select_Size(face, ptsize);
+        error = FT_Select_Size(face, index);
         if (error) {
             return TTF_SetFTError("Couldn't select size", error);
         }
@@ -1997,7 +1998,7 @@ bool TTF_SetFontSizeDPI(TTF_Font *font, int ptsize, unsigned int hdpi, unsigned
     return true;
 }
 
-bool TTF_SetFontSize(TTF_Font *font, int ptsize)
+bool TTF_SetFontSize(TTF_Font *font, float ptsize)
 {
     return TTF_SetFontSizeDPI(font, ptsize, 0, 0);
 }