diff -Naur ./libgd-2.3.2-orig/src/entities.h ./libgd-2.3.2/src/entities.h
--- ./libgd-2.3.2-orig/src/entities.h	2021-01-11 17:09:45.000000000 -0700
+++ ./libgd-2.3.2/src/entities.h	2021-04-17 06:44:00.325639616 -0700
@@ -269,7 +269,7 @@
 		{"zwnj", 8204},
 	};
 
-#define ENTITY_NAME_LENGTH_MAX 8
+#define ENTITY_NAME_LENGTH_MAX 9
 #define NR_OF_ENTITIES 252
 
 #ifdef __cplusplus
diff -Naur ./libgd-2.3.2-orig/src/gdft.c ./libgd-2.3.2/src/gdft.c
--- ./libgd-2.3.2-orig/src/gdft.c	2021-03-03 00:15:02.000000000 -0700
+++ ./libgd-2.3.2/src/gdft.c	2021-04-17 07:05:45.456881557 -0700
@@ -267,14 +267,43 @@
 static gdCache_head_t *fontCache;
 static FT_Library library;
 
-#define Tcl_UniChar int
-#define TCL_UTF_MAX 3
+#define Tcl_UniChar uint64_t
+#define TCL_UTF_MAX 4
+const unsigned char totalBytes[256] = {
+    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+    2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+    3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
+#if TCL_UTF_MAX > 3
+    4,4,4,4,4,4,4,4,
+#else
+    1,1,1,1,1,1,1,1,
+#endif
+
+#if TCL_UTF_MAX > 4
+    5,5,5,5,
+#else
+    1,1,1,1,
+#endif
+
+#if TCL_UTF_MAX > 5
+    6,6,6,6
+#else
+    1,1,1,1
+#endif
+};
+
 static int
 gdTcl_UtfToUniChar (const char *str, Tcl_UniChar * chPtr)
 /* str is the UTF8 next character pointer */
 /* chPtr is the int for the result */
 {
-	int byte;
+	unsigned char byte;
+	uint64_t b0, b1, b2, b3;
 	char entity_name_buf[ENTITY_NAME_LENGTH_MAX+1];
 	char *p;
 	struct entities_s key, *res;
@@ -289,7 +318,7 @@
 		if (byte == '#') {
 			byte = *((unsigned char *) (str + 2));
 			if (byte == 'x' || byte == 'X') {
-				for (i = 3; i < 8; i++) {
+				for (i = 3; i < 9; i++) {
 					byte = *((unsigned char *) (str + i));
 					if (byte >= 'A' && byte <= 'F')
 						byte = byte - 'A' + 10;
@@ -302,7 +331,7 @@
 					n = (n * 16) + byte;
 				}
 			} else {
-				for (i = 2; i < 8; i++) {
+				for (i = 2; i < 9; i++) {
 					byte = *((unsigned char *) (str + i));
 					if (byte >= '0' && byte <= '9')
 						n = (n * 10) + (byte - '0');
@@ -400,9 +429,20 @@
 
 			*chPtr = (Tcl_UniChar) byte;
 			return 1;
+		} else if (byte < 0xF8) {
+			b0=str[0];
+			b1=str[1];
+			b2=str[2];
+			b3=str[3];
+			if (  ((b1 & 0xC0) == 0x80) && ((b2 & 0xC0) == 0x80) && ((b3 & 0xC0) == 0x80)  ) {
+				*chPtr = (Tcl_UniChar) (  ((b0 & 0x7) << 18) | ((b1 & 0x3F) << 12) | ((b2 & 0x3F) << 6) | (b3 & 0x3F));
+				return 4;
+			}
+			*chPtr = (Tcl_UniChar)b0;
+			return 1;
 		}
-#if TCL_UTF_MAX > 3
-		else {
+#if TCL_UTF_MAX > 4
+		  else {
 			int ch, total, trail;
 
 			total = totalBytes[byte];
@@ -442,7 +482,7 @@
 } glyphInfo;
 
 static ssize_t
-textLayout(uint32_t *text, int len,
+textLayout(uint64_t *text, uint64_t len,
 		FT_Face face, gdFTStringExtraPtr strex,
 		glyphInfo **glyph_info)
 {
@@ -1105,12 +1145,12 @@
 	FT_UInt glyph_index;
 	double sin_a = sin (angle);
 	double cos_a = cos (angle);
-	int  i, ch;
+	uint64_t  i, ch;
 	font_t *font;
 	fontkey_t fontkey;
-	const char *next;
+	char *next;
 	char *tmpstr = 0;
-	uint32_t *text;
+	uint64_t *text;
 	glyphInfo *info = NULL;
 	ssize_t count;
 	int render = (im && (im->trueColor || (fg <= 255 && fg >= -255)));
@@ -1300,7 +1340,7 @@
 #endif
 	}
 	if (encodingfound) {
-		FT_Set_Charmap(face, charmap);
+		FT_Select_Charmap(face, FT_ENCODING_UNICODE);
 	} else {
 		/* No character set found! */
 		gdCacheDelete (tc_cache);
@@ -1315,17 +1355,17 @@
 			any2eucjp (tmpstr, string, BUFSIZ);
 			next = tmpstr;
 		} else {
-			next = string;
+			next = (char *)string;
 		}
 #ifndef JISX0208
 	} else {
-		next = string;
+		next = (char *)string;
 	}
 #endif
 
 	oldpenf.x = oldpenf.y = 0; /* for postscript xshow operator */
 	penf.x = penf.y = 0;	/* running position of non-rotated glyphs */
-	text = (uint32_t*) gdCalloc (sizeof (uint32_t), strlen(next));
+	text = (uint64_t *) gdCalloc (sizeof (uint64_t), (const char *)strlen(next));
 	i = 0;
 	while (*next) {
 		int len;
@@ -1333,7 +1373,7 @@
 		switch (encoding) {
 		case gdFTEX_Unicode: {
 			/* use UTF-8 mapping from ASCII */
-			len = gdTcl_UtfToUniChar (next, &ch);
+			len = gdTcl_UtfToUniChar ((const char *)next, &ch);
 			/* EAM DEBUG */
 			/* TBB: get this exactly right: 2.1.3 *or better*, all possible cases. */
 			/* 2.0.24: David R. Morrison: use the more complete ifdef here. */
