SDL_ttf: Add font weight functionality (dee59)

From dee597aaed6e2ef0a7689ea3acc9ff9589c2e689 Mon Sep 17 00:00:00 2001
From: TriangulumDesire <[EMAIL REDACTED]>
Date: Wed, 19 Mar 2025 01:55:29 +1000
Subject: [PATCH] Add font weight functionality

(cherry picked from commit 78c290f25e1cf37eac1512591c7ec3c1f07f2a8b)
---
 include/SDL3_ttf/SDL_ttf.h | 26 +++++++++++++++++++++++++-
 src/SDL_ttf.c              | 20 ++++++++++++++++++++
 src/SDL_ttf.sym            |  1 +
 3 files changed, 46 insertions(+), 1 deletion(-)

diff --git a/include/SDL3_ttf/SDL_ttf.h b/include/SDL3_ttf/SDL_ttf.h
index 7b1ae119..f1ca1877 100644
--- a/include/SDL3_ttf/SDL_ttf.h
+++ b/include/SDL3_ttf/SDL_ttf.h
@@ -445,7 +445,7 @@ extern SDL_DECLSPEC bool SDLCALL TTF_GetFontDPI(TTF_Font *font, int *hdpi, int *
  * SDL_ttf. A combination of these flags can be used with functions that set
  * or query font style, such as TTF_SetFontStyle or TTF_GetFontStyle.
  *
- * \since This function is available since SDL_ttf 3.0.0.
+ * \since This datatype is available since SDL_ttf 3.0.0.
  *
  * \sa TTF_SetFontStyle
  * \sa TTF_GetFontStyle
@@ -667,6 +667,30 @@ extern SDL_DECLSPEC bool SDLCALL TTF_SetFontSDF(TTF_Font *font, bool enabled);
  */
 extern SDL_DECLSPEC bool SDLCALL TTF_GetFontSDF(const TTF_Font *font);
 
+/**
+ * Query a font's weight, in terms of the lightness/heaviness of the strokes.
+ *
+ * \param font the font to query.
+ * \returns the font's current weight
+ *
+ * \threadsafety This function should be called on the thread that created the
+ *               font.
+ *
+ * \since This function is available since SDL_ttf 3.4.0.
+ */
+extern SDL_DECLSPEC int SDLCALL TTF_GetFontWeight(const TTF_Font *font);
+
+#define TTF_FONT_WEIGHT_THIN        100 /**< Thin (100) named font weight value */
+#define TTF_FONT_WEIGHT_EXTRA_LIGHT 200 /**< ExtraLight (200) named font weight value */
+#define TTF_FONT_WEIGHT_LIGHT       300 /**< Light (300) named font weight value */
+#define TTF_FONT_WEIGHT_NORMAL      400 /**< Normal (400) named font weight value */
+#define TTF_FONT_WEIGHT_MEDIUM      500 /**< Medium (500) named font weight value */
+#define TTF_FONT_WEIGHT_SEMI_BOLD   600 /**< SemiBold (600) named font weight value */
+#define TTF_FONT_WEIGHT_BOLD        700 /**< Bold (700) named font weight value */
+#define TTF_FONT_WEIGHT_EXTRA_BOLD  800 /**< ExtraBold (800) named font weight value */
+#define TTF_FONT_WEIGHT_BLACK       900 /**< Black (900) named font weight value */
+#define TTF_FONT_WEIGHT_EXTRA_BLACK 950 /**< ExtraBlack (950) named font weight value */
+
 /**
  * The horizontal alignment used when rendering wrapped text.
  *
diff --git a/src/SDL_ttf.c b/src/SDL_ttf.c
index 6463ab01..be517a18 100644
--- a/src/SDL_ttf.c
+++ b/src/SDL_ttf.c
@@ -31,6 +31,7 @@
 #include FT_STROKER_H
 #include FT_GLYPH_H
 #include FT_TRUETYPE_IDS_H
+#include FT_TRUETYPE_TABLES_H
 #include FT_IMAGE_H
 
 /* Enable rendering with color
@@ -306,6 +307,7 @@ struct TTF_Font {
 
     // The font style
     TTF_FontStyleFlags style;
+    int weight;
     int outline;
     FT_Stroker stroker;
 
@@ -2129,6 +2131,7 @@ TTF_Font *TTF_OpenFontWithProperties(SDL_PropertiesID props)
     // Set the default font style
     if (existing_font) {
         font->style = existing_font->style;
+        font->weight = existing_font->weight;
         font->outline = existing_font->outline;
         font->ft_load_target = existing_font->ft_load_target;
         font->enable_kerning = existing_font->enable_kerning;
@@ -2137,6 +2140,16 @@ TTF_Font *TTF_OpenFontWithProperties(SDL_PropertiesID props)
         font->outline = 0;
         font->ft_load_target = FT_LOAD_TARGET_NORMAL;
         TTF_SetFontKerning(font, true);
+
+        // Retrieve the weight from the OS2 TrueType table
+        const TT_OS2 *os2_table = (const TT_OS2 *)FT_Get_Sfnt_Table(face, FT_SFNT_OS2);
+        if (os2_table != NULL && os2_table->usWeightClass != 0) {
+            font->weight = os2_table->usWeightClass;
+        } else if (face->style_flags & FT_STYLE_FLAG_BOLD) {
+            font->weight = TTF_FONT_WEIGHT_BOLD;
+        } else {
+            font->weight = TTF_FONT_WEIGHT_NORMAL;
+        }
     }
 
 #if TTF_USE_HARFBUZZ
@@ -5794,6 +5807,13 @@ bool TTF_GetFontSDF(const TTF_Font *font)
     return font->render_sdf;
 }
 
+int TTF_GetFontWeight(const TTF_Font *font)
+{
+    TTF_CHECK_FONT(font, -1);
+
+    return font->weight;
+}
+
 void TTF_SetFontWrapAlignment(TTF_Font *font, TTF_HorizontalAlignment align)
 {
     TTF_CHECK_FONT(font,);
diff --git a/src/SDL_ttf.sym b/src/SDL_ttf.sym
index 0017cdd4..564eaf36 100644
--- a/src/SDL_ttf.sym
+++ b/src/SDL_ttf.sym
@@ -38,6 +38,7 @@ SDL3_ttf_0.0.0 {
     TTF_GetFontSize;
     TTF_GetFontStyle;
     TTF_GetFontStyleName;
+    TTF_GetFontWeight;
     TTF_GetFontWrapAlignment;
     TTF_GetFreeTypeVersion;
     TTF_GetGlyphImage;