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-16 02:45:17.258631506 -0700 @@ -269,7 +269,7 @@ {"zwnj", 8204}, }; -#define ENTITY_NAME_LENGTH_MAX 8 +#define ENTITY_NAME_LENGTH_MAX 12 #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 06:02:26.911902489 -0700 @@ -267,14 +267,47 @@ 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 6 +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; @@ -283,13 +316,13 @@ /* or in hexadecimal form, e.g. 水 */ byte = *((unsigned char *) str); if (byte == '&') { - int i, n = 0; + uint64_t i, n = 0; byte = *((unsigned char *) (str + 1)); if (byte == '#') { byte = *((unsigned char *) (str + 2)); if (byte == 'x' || byte == 'X') { - for (i = 3; i < 8; i++) { + for (i = 3; i < 11; i++) { byte = *((unsigned char *) (str + i)); if (byte >= 'A' && byte <= 'F') byte = byte - 'A' + 10; @@ -302,7 +335,7 @@ n = (n * 16) + byte; } } else { - for (i = 2; i < 8; i++) { + for (i = 2; i < 11; i++) { byte = *((unsigned char *) (str + i)); if (byte >= '0' && byte <= '9') n = (n * 10) + (byte - '0'); @@ -355,7 +388,9 @@ return 2; } else #endif /* JISX0208 */ + if (byte < 0xC0) { +//if (byte < 0x11000000) { /* * Handles properly formed UTF-8 characters between * 0x01 and 0x7F. Also treats \0 and naked trail @@ -366,6 +401,7 @@ *chPtr = (Tcl_UniChar) byte; return 1; } else if (byte < 0xE0) { +//}else if (byte < 0x11100000) { if ((str[1] & 0xC0) == 0x80) { /* * Two-byte-character lead-byte followed @@ -383,14 +419,20 @@ *chPtr = (Tcl_UniChar) byte; return 1; } else if (byte < 0xF0) { - if (((str[1] & 0xC0) == 0x80) && ((str[2] & 0xC0) == 0x80)) { + +//}else if (byte < 0x11110000) { + +b0=str[0]; +b1=str[1]; +b2=str[2]; + + if ( ((b1 & 0xC0) == 0x80) && ((b2 & 0xC0) == 0x80)) { /* * Three-byte-character lead byte followed by * two trail bytes. */ - - *chPtr = (Tcl_UniChar) (((byte & 0x0F) << 12) - | ((str[1] & 0x3F) << 6) | (str[2] & 0x3F)); + *chPtr = (Tcl_UniChar) (((b0 & 0x0F) << 12) + | ((b1 & 0x3F) << 6) | (b2 & 0x3F)); return 3; } /* @@ -398,12 +440,46 @@ * two trail-bytes represents itself. */ - *chPtr = (Tcl_UniChar) byte; + *chPtr = (Tcl_UniChar)b0; return 1; - } -#if TCL_UTF_MAX > 3 + } 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)); + + //buff = ((byte & 0x07) << 18); + // *chPtr = (Tcl_UniChar) ( buff | ((str[1] & 0x3F) << 12) | ((str[2] & 0x3F) << 6) | (str[3] & 0x3F)); + +//printf("4 byte\n"); + + //str[4] = 0; + + + + return 4; + } + *chPtr = (Tcl_UniChar)b0; + return 1; + } + + + + + +//if(byte > 0x1110F000 + + + + + +#if TCL_UTF_MAX > 4 else { - int ch, total, trail; + uint64_t ch, total, trail; total = totalBytes[byte]; trail = total - 1; @@ -425,6 +501,7 @@ } #endif + *chPtr = (Tcl_UniChar) byte; return 1; } @@ -442,7 +519,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 +1182,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 +1377,8 @@ #endif } if (encodingfound) { - FT_Set_Charmap(face, charmap); +// FT_Set_Charmap(face, charmap); +FT_Select_Charmap(face, FT_ENCODING_UNICODE); } else { /* No character set found! */ gdCacheDelete (tc_cache); @@ -1315,17 +1393,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), strlen((const char *)next)); i = 0; while (*next) { int len; @@ -1333,7 +1411,10 @@ switch (encoding) { case gdFTEX_Unicode: { /* use UTF-8 mapping from ASCII */ - len = gdTcl_UtfToUniChar (next, &ch); + len = gdTcl_UtfToUniChar ((const char *)next, &ch); +//ch = 129993; +//ch = 0x1F8B0; +//len = 4; /* 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. */ @@ -1346,7 +1427,7 @@ /* I do not know the significance of the constant 0xf000. */ /* It was determined by inspection of the character codes */ /* stored in Microsoft font symbol.ttf */ - ch |= 0xf000; +// ch |= 0xf000; } /* EAM DEBUG */ next += len; @@ -1473,7 +1554,7 @@ } } xshow_pos += sprintf(strex->xshow + xshow_pos, "%g ", - (double)(penf.x - oldpenf.x) * hdpi / (64 * METRIC_RES)); + (double)(penf.x + slot->metrics.horiBearingX - oldpenf.x) * hdpi / (64 * METRIC_RES)); } oldpenf.x = penf.x;