4646// SYSTEM INCLUDES ////////////////////////////////////////////////////////////
4747#include < stdlib.h>
4848#include < stdio.h>
49+ #include < string.h>
4950
5051// USER INCLUDES //////////////////////////////////////////////////////////////
5152#include " Common/Debug.h"
@@ -59,7 +60,8 @@ namespace
5960{
6061// GeneralsX @bugfix GitHubCopilot 20/05/2026 Resolve a usable Unicode fallback font on macOS/Linux when localized font names are unavailable.
6162// GeneralsX @tweak GitHubCopilot 27/05/2026 Add explicit stderr tracing for Unicode fallback font lookup decisions.
62- FontCharsClass *LoadUnicodeFallbackFont (Int size, Bool bold)
63+ // GeneralsX @bugfix GitHubCopilot 29/05/2026 Prevent circular Unicode fallback when the localized unicode family equals the base font family.
64+ FontCharsClass *LoadUnicodeFallbackFont (Int size, Bool bold, const char *base_name)
6365{
6466 const char *preferred_name = nullptr ;
6567 char log_buffer[512 ];
@@ -69,13 +71,14 @@ FontCharsClass *LoadUnicodeFallbackFont(Int size, Bool bold)
6971 }
7072
7173 sprintf (log_buffer,
72- " [GX-ISSUE144] W3DFont fallback start size=%d bold=%d preferred=%s" ,
74+ " [GX-ISSUE144] W3DFont fallback start size=%d bold=%d preferred=%s base=%s " ,
7375 size,
7476 bold,
75- preferred_name ? preferred_name : " <none>" );
77+ preferred_name ? preferred_name : " <none>" ,
78+ base_name ? base_name : " <none>" );
7679 fprintf (stderr, " %s\n " , log_buffer);
7780
78- if (preferred_name != nullptr ) {
81+ if (preferred_name != nullptr && (base_name == nullptr || strcmp (preferred_name, base_name) != 0 ) ) {
7982 FontCharsClass *font = WW3DAssetManager::Get_Instance ()->Get_FontChars (preferred_name, size, bold);
8083 if (font != nullptr ) {
8184 sprintf (log_buffer, " [GX-ISSUE144] W3DFont fallback hit preferred=%s" , preferred_name);
@@ -86,6 +89,10 @@ FontCharsClass *LoadUnicodeFallbackFont(Int size, Bool bold)
8689 sprintf (log_buffer, " [GX-ISSUE144] W3DFont fallback miss preferred=%s" , preferred_name);
8790 fprintf (stderr, " %s\n " , log_buffer);
8891 }
92+ else if (preferred_name != nullptr ) {
93+ sprintf (log_buffer, " [GX-ISSUE144] W3DFont fallback skip preferred=%s reason=same-as-base" , preferred_name);
94+ fprintf (stderr, " %s\n " , log_buffer);
95+ }
8996
9097 static const char *kFallbackUnicodeFonts [] = {
9198 " Arial Unicode MS" ,
@@ -168,7 +175,7 @@ Bool W3DFontLibrary::loadFontData( GameFont *font )
168175 font->height = fontChar->Get_Char_Height ();
169176
170177 // load Unicode of same point size
171- fontChar->AlternateUnicodeFont = LoadUnicodeFallbackFont (size, bold);
178+ fontChar->AlternateUnicodeFont = LoadUnicodeFallbackFont (size, bold, name );
172179 sprintf (log_buffer,
173180 " [GX-ISSUE144] W3DFont alternate unicode %s for base=%s" ,
174181 fontChar->AlternateUnicodeFont ? " assigned" : " missing" ,
0 commit comments