Maelstrom: Handle UI texts as Unicode

From c87a2642487bacd94bdfca17bbdb10c8af7ec578 Mon Sep 17 00:00:00 2001
From: Pino Toscano <[EMAIL REDACTED]>
Date: Thu, 7 May 2026 13:07:58 +0200
Subject: [PATCH] Handle UI texts as Unicode

The text rendering code so far assumed all the characters can be
represented each in a single byte. This means that the "COPYRIGHT SIGN"
character in two UI definitions is encoded as ISO-8859.

Tweak a bit the handling of the text, using SDL APIs to iterate through
the codepoints as such (rather than byte by byte). While it works, it is
still limited by the availability of characters in the fonts, which will
likely not have anything more than what available in ISO-8859.

As result, Data/UI/main.xml can be converted to UTF-8:
  $ iconv -f ISO-8859-15 -t UTF-8 -o Data/UI/main.xml Data/UI/main.xml
---
 Data/UI/main.xml        |  4 ++--
 maclib/Mac_FontServ.cpp | 35 +++++++++++++++++++++++------------
 2 files changed, 25 insertions(+), 14 deletions(-)

diff --git a/Data/UI/main.xml b/Data/UI/main.xml
index 16be92db..b6e2c513 100644
--- a/Data/UI/main.xml
+++ b/Data/UI/main.xml
@@ -266,7 +266,7 @@
 				<Label template="SmallYellow" text="Port to SDL by Sam Lantinga">
 					<Anchor anchorFrom="CENTER" anchorTo="CENTER" anchor="image" y="52"/>
 				</Label>
-				<Label template="SmallWhite" text="1992-4 Ambrosia Software, Inc.">
+				<Label template="SmallWhite" text="©1992-4 Ambrosia Software, Inc.">
 					<Anchor anchorFrom="BOTTOMLEFT" anchorTo="TOPLEFT" anchor="hdivider_right" x="9" y="-2"/>
 				</Label>
 				<Image image="logo">
@@ -473,7 +473,7 @@
 				<Label template="SmallYellow" text="Port to SDL by Sam Lantinga">
 					<Anchor anchorFrom="CENTER" anchorTo="CENTER" anchor="image" y="52"/>
 				</Label>
-				<Label template="SmallWhite" text="1992-4 Ambrosia Software, Inc.">
+				<Label template="SmallWhite" text="©1992-4 Ambrosia Software, Inc.">
 					<Anchor anchorFrom="BOTTOM" anchorTo="BOTTOM" y="-50"/>
 				</Label>
 
diff --git a/maclib/Mac_FontServ.cpp b/maclib/Mac_FontServ.cpp
index d0cb2004..e503db27 100644
--- a/maclib/Mac_FontServ.cpp
+++ b/maclib/Mac_FontServ.cpp
@@ -276,7 +276,9 @@ FontServ::FreeFont(MFont *font)
 Uint16
 FontServ::TextWidth(const char *text, MFont *font, Uint8 style)
 {
-	int nchars, i;
+	Uint32 codepoint;
+	const char *textptr;
+	size_t remaining_bytes;
 	int space_width;	/* The width of the whole character */
 	int extra_width;	/* Stylistic width */
 	Uint16 Width;
@@ -299,15 +301,18 @@ FontServ::TextWidth(const char *text, MFont *font, Uint8 style)
 					break;
 		default:		return(0);
 	}
-	nchars = (int)SDL_strlen(text);
+	textptr = text;
+	remaining_bytes = SDL_strlen(text);
 
 	Width = 0;
-	for ( i = 0; i < nchars; ++i ) {
+	while ( ( codepoint = SDL_StepUTF8(&textptr, &remaining_bytes) ) != 0 ) {
 		/* check to see if this character is defined */
-		if (font->owTable[(Uint8)text[i]] <= 0)
+		if ( (Sint16)codepoint < (font->header)->firstChar ||
+			(Sint16)codepoint > (font->header)->lastChar ||
+			font->owTable[codepoint] <= 0 )
 			continue;
 		
-		space_width = LoByte(font->owTable[(Uint8)text[i]]);
+		space_width = LoByte(font->owTable[codepoint]);
 #ifdef WIDE_BOLD
 		Width += (space_width+extra_width);
 #else
@@ -337,7 +342,9 @@ FontServ::TextImage(const char *text, MFont *font, Uint8 style, SDL_Color fg)
 	int width, height;
 	SDL_Texture *image;
 	Uint32 *bitmap;
-	int nchars;
+	Uint32 codepoint;
+	size_t nbytes, remaining_bytes;
+	const char *textptr;
 	int bit_offset;		/* The current bit offset into a scanline */
 	int space_width;	/* The width of the whole character */
 	int space_offset;	/* The offset into the character of glyph */
@@ -446,21 +453,25 @@ FontServ::TextImage(const char *text, MFont *font, Uint8 style, SDL_Color fg)
 
 	/* Print the individual characters */
 	/* Note: this could probably be optimized.. eh, who cares. :) */
-	nchars = (int)SDL_strlen(text);
+	nbytes = SDL_strlen(text);
 	for ( boldness=0; boldness <= bold_offset; ++boldness ) {
 		bit_offset=0;
-		for ( i = 0; i < nchars; ++i ) {
+		remaining_bytes = nbytes;
+		textptr = text;
+		while ( ( codepoint = SDL_StepUTF8(&textptr, &remaining_bytes) ) != 0 ) {
 			/* check to see if this character is defined */
 			/* According to the above comment, we should */
 			/* check if the table contains -1, but this  */
 			/* change seems to fix a SIGSEGV that would  */
 			/* otherwise occur in some cases.            */
-			if (font->owTable[(Uint8)text[i]] <= 0)
+			if ( (Sint16)codepoint < (font->header)->firstChar ||
+				(Sint16)codepoint > (font->header)->lastChar ||
+				font->owTable[codepoint] <= 0 )
 				continue;
 
-			space_width = LoByte(font->owTable[(Uint8)text[i]]);
-			space_offset = HiByte(font->owTable[(Uint8)text[i]]);
-			ascii = (Uint8)text[i] - (font->header)->firstChar;
+			space_width = LoByte(font->owTable[codepoint]);
+			space_offset = HiByte(font->owTable[codepoint]);
+			ascii = (Sint16)codepoint - (font->header)->firstChar;
 			glyph_line_offset = font->locTable[ascii]; 
 			glyph_width = (font->locTable[ascii+1] -
 							font->locTable[ascii]);