summaryrefslogtreecommitdiffstats
path: root/macosx/tkMacOSXFont.c
diff options
context:
space:
mode:
authorculler <culler>2019-11-16 16:58:36 (GMT)
committerculler <culler>2019-11-16 16:58:36 (GMT)
commitc500b0d754741b94324deccd875cc8f2d71f8bdf (patch)
treef1bb43057ec0dfd738509f1f9188ba785f56350c /macosx/tkMacOSXFont.c
parent7d9ab4e8bbc99150a6c6e1bba9913da381c45ddc (diff)
downloadtk-c500b0d754741b94324deccd875cc8f2d71f8bdf.zip
tk-c500b0d754741b94324deccd875cc8f2d71f8bdf.tar.gz
tk-c500b0d754741b94324deccd875cc8f2d71f8bdf.tar.bz2
On macOS make DrawCharsInContext accept byte sequences which contain UTF-16 surrogates encoded as 3-byte UTF-8-ish subsequences, so the Emoji demo works.
Diffstat (limited to 'macosx/tkMacOSXFont.c')
-rw-r--r--macosx/tkMacOSXFont.c23
1 files changed, 22 insertions, 1 deletions
diff --git a/macosx/tkMacOSXFont.c b/macosx/tkMacOSXFont.c
index 153ce3b..5f3ea54 100644
--- a/macosx/tkMacOSXFont.c
+++ b/macosx/tkMacOSXFont.c
@@ -1112,7 +1112,28 @@ DrawCharsInContext(
string = [[NSString alloc] initWithBytesNoCopy:(void*)source
length:numBytes encoding:NSUTF8StringEncoding freeWhenDone:NO];
if (!string) {
- return;
+
+ /*
+ * The decoding might have failed because we got a fake UTF-8 byte
+ * array in which UTF-16 surrogates had been encoded using the UTF-8
+ * algorithm, even though UTF-8 does not allow encoding surrogates.
+ * (When Tcl is compiled with TCL_UTF_MAX = 3 Tk uses this encoding
+ * internally.) We can attempt to decode the source using this
+ * encoding and see if Apple accepts the result as UTF-16.
+ */
+
+ const unichar *characters = ckalloc(numBytes*sizeof(unichar));
+ const char *in = source;
+ unichar *out = (unichar *) characters;
+ while (in < source + numBytes) {
+ in += Tcl_UtfToUniChar(in, out++);
+ }
+ string = [[NSString alloc] initWithCharacters:characters
+ length:(out - characters)];
+ ckfree(characters);
+ if (!string) {
+ return;
+ }
}
context = drawingContext.context;