summaryrefslogtreecommitdiffstats
path: root/macosx
diff options
context:
space:
mode:
authorculler <culler>2020-05-17 22:08:09 (GMT)
committerculler <culler>2020-05-17 22:08:09 (GMT)
commit8fe8aab16504c4e9b91e295e0ee2a537797d0316 (patch)
tree833c96abacc4d8a988e5ea3b8172bdabb3e60fdc /macosx
parent5fbfe2a7ea51ec68286bee8b30c89059022279ba (diff)
downloadtk-8fe8aab16504c4e9b91e295e0ee2a537797d0316.zip
tk-8fe8aab16504c4e9b91e295e0ee2a537797d0316.tar.gz
tk-8fe8aab16504c4e9b91e295e0ee2a537797d0316.tar.bz2
Simplify Aqua text handling by moving encoding/decoding into the TKNSString class.
Diffstat (limited to 'macosx')
-rw-r--r--macosx/tkMacOSXClipboard.c25
-rw-r--r--macosx/tkMacOSXFont.c144
-rw-r--r--macosx/tkMacOSXPrivate.h26
3 files changed, 73 insertions, 122 deletions
diff --git a/macosx/tkMacOSXClipboard.c b/macosx/tkMacOSXClipboard.c
index 529b5fa..be1f16c 100644
--- a/macosx/tkMacOSXClipboard.c
+++ b/macosx/tkMacOSXClipboard.c
@@ -137,26 +137,19 @@ TkSelGetSelection(
string = [pb stringForType:type];
}
if (string) {
-
- /*
- * Encode the string using the encoding which is used in Tcl
- * when TCL_UTF_MAX = 3. This replaces each UTF-16 surrogate with
- * a 3-byte sequence generated using the UTF-8 algorithm. (Even
- * though UTF-8 does not allow encoding surrogates, the algorithm
- * does produce a 3-byte sequence.)
- */
-
- char *bytes = TkNSStringToUtf(string, NULL);
- result = proc(clientData, interp, bytes);
- if (bytes) {
- ckfree(bytes);
+ if (target == dispPtr->utf8Atom) {
+ result = proc(clientData, interp, string.UTF8String);
+ } else if (target == XA_STRING) {
+ const char *latin1 = [string
+ cStringUsingEncoding:NSISOLatin1StringEncoding];
+ result = proc(clientData, interp, latin1);
}
}
} else {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
- "%s selection doesn't exist or form \"%s\" not defined",
- Tk_GetAtomName(tkwin, selection),
- Tk_GetAtomName(tkwin, target)));
+ "%s selection doesn't exist or form \"%s\" not defined",
+ Tk_GetAtomName(tkwin, selection),
+ Tk_GetAtomName(tkwin, target)));
Tcl_SetErrorCode(interp, "TK", "SELECTION", "EXISTS", NULL);
}
return result;
diff --git a/macosx/tkMacOSXFont.c b/macosx/tkMacOSXFont.c
index 6bd5c55..7fc0113 100644
--- a/macosx/tkMacOSXFont.c
+++ b/macosx/tkMacOSXFont.c
@@ -103,7 +103,9 @@ static void DrawCharsInContext(Display *display, Drawable drawable,
/*
* To avoid an extra copy, a TKNSString object wraps a Tcl_DString with an
- * NSString that uses the DString's buffer as its character buffer.
+ * NSString that uses the DString's buffer as its character buffer. It can be
+ * constructed from a Tcl_DString and it has a DString property that handles
+ * converting from an NSString to a Tcl_DString
*/
@implementation TKNSString
@@ -124,6 +126,17 @@ static void DrawCharsInContext(Display *display, Drawable drawable,
return self;
}
+- (instancetype)initWithString:(NSString *)aString
+{
+ self = [self init];
+ if (self) {
+ _string = [[NSString alloc] initWithString:aString];
+ self.UTF8String = _string.UTF8String;
+ }
+ printf("Initialized with string %s\n", self.UTF8String);
+ return self;
+}
+
- (void)dealloc
{
Tcl_DStringFree(&_ds);
@@ -140,104 +153,53 @@ static void DrawCharsInContext(Display *display, Drawable drawable,
{
return [_string characterAtIndex:index];
}
-#ifndef __clang__
-@synthesize UTF8String = _UTF8String;
-#endif
-@end
-/*
- *---------------------------------------------------------------------------
- *
- * TkUtfAtIndex --
- *
- * Write a sequence of bytes up to length 6 which is an encoding of a UTF-16
- * character in an NSString. Also record the unicode code point of the character.
- * this may be a non-BMP character constructed by reading two surrogates from
- * the NSString. See the documentation for TKNSString in tkMacOSXPrivate.h.
- *
- * Results:
- * Returns the number of bytes written.
- *
- * Side effects:
- * Bytes are written to the char array referenced by the pointer uni and
- * the unicode code point is written to the integer referenced by the
- * pointer code.
- *
- */
+# ifndef __clang__
+@synthesize DString = _ds;
+#endif
-MODULE_SCOPE int
-TkUtfAtIndex(
- NSString *string,
- int index,
- char *uni,
- unsigned int *code)
+- (Tcl_DString)DString
{
- char *ptr = uni;
- UniChar uniChar = [string characterAtIndex: index];
- if (CFStringIsSurrogateHighCharacter(uniChar)) {
- UniChar lowChar = [string characterAtIndex: ++index];
- *code = CFStringGetLongCharacterForSurrogatePair(
- uniChar, lowChar);
- ptr += Tcl_UniCharToUtf(uniChar, ptr);
- ptr += Tcl_UniCharToUtf(lowChar, ptr);
- return ptr - uni;
- } else {
- *code = (int) uniChar;
- [[string substringWithRange: NSMakeRange(index, 1)]
- getCString: uni
- maxLength: 7
- encoding: NSUTF8StringEncoding];
- return strlen(uni);
- }
-}
-
-/*
- *---------------------------------------------------------------------------
- *
- * TkNSStringToUtf --
- *
- * Encodes the unicode string represented by an NSString object with the
- * internal encoding that Tcl uses when TCL_UTF_MAX = 3. This encoding
- * is similar to UTF-8 except that non-BMP characters are encoded as two
- * successive 3-byte sequences which are constructed from UTF-16 surrogates
- * by applying the UTF-8 algorithm. Even though the UTF-8 encoding does not
- * allow encoding surrogates, the algorithm does produce a well-defined
- * 3-byte sequence.
- *
- * Results:
- * Returns a pointer to a null-terminated byte array which encodes the
- * NSString.
- *
- * Side effects:
- * Memory is allocated to hold the byte array, which must be freed with
- * ckalloc. If the pointer numBytes is not NULL the number of non-null
- * bytes written to the array is stored in the integer it references.
- */
+ if ( _ds.string == NULL) {
-MODULE_SCOPE char*
-TkNSStringToUtf(
- NSString *string,
- int *numBytes)
-{
- unsigned int code;
- int i;
- char *ptr, *bytes = ckalloc(6*[string length] + 1);
-
- ptr = bytes;
- if (ptr) {
- for (i = 0; i < [string length]; i++) {
- ptr += TkUtfAtIndex(string, i, ptr, &code);
- if (code > 0xffff){
- i++;
+ /*
+ * The DString has not been initialized. Construct it from
+ * our string's unicode characters.
+ */
+
+ char buffer[2*TCL_UTF_MAX];
+ unsigned int index, length, ch;
+
+ Tcl_DStringInit(&_ds);
+#if TCL_UTF_MAX == 3
+ for (index = 0; index < [_string length]; index++) {
+ UniChar uni = [_string characterAtIndex: index];
+
+ if (CFStringIsSurrogateHighCharacter(uni)) {
+ UniChar low = [_string characterAtIndex: ++index];
+ ch = CFStringGetLongCharacterForSurrogatePair(uni, low);
+ } else {
+ ch = uni;
}
+ length = TkUniCharToUtf(ch, buffer);
+ Tcl_DStringAppend(&_ds, buffer, length);
}
- *ptr = '\0';
- }
- if (numBytes) {
- *numBytes = ptr - bytes;
+#else
+ for (index = 0; index < [_string length]; index++) {
+ ch = (int) [_string characterAtIndex: index];
+ length = Tcl_UniCharToUtf(ch, buffer);
+ Tcl_DStringAppend(&_ds, buffer, length);
+ }
+
+#endif
}
- return bytes;
+ return _ds;
}
+
+#ifndef __clang__
+@synthesize UTF8String = _UTF8String;
+#endif
+@end
#define GetNSFontTraitsFromTkFontAttributes(faPtr) \
((faPtr)->weight == TK_FW_BOLD ? NSBoldFontMask : NSUnboldFontMask) | \
diff --git a/macosx/tkMacOSXPrivate.h b/macosx/tkMacOSXPrivate.h
index 963eb6e..a0645f7 100644
--- a/macosx/tkMacOSXPrivate.h
+++ b/macosx/tkMacOSXPrivate.h
@@ -306,10 +306,6 @@ MODULE_SCOPE int TkMacOSXServices_Init(Tcl_Interp *interp);
MODULE_SCOPE int TkMacOSXRegisterServiceWidgetObjCmd(ClientData clientData,
Tcl_Interp *interp, int objc,
Tcl_Obj *const objv[]);
-MODULE_SCOPE NSString* TkUtfToNSString(const char *source, size_t numBytes);
-MODULE_SCOPE int TkUtfAtIndex(NSString *string, int index, char *uni,
- unsigned int *code);
-MODULE_SCOPE char* TkNSStringToUtf(NSString *string, int *numBytes);
MODULE_SCOPE unsigned TkMacOSXAddVirtual(unsigned int keycode);
#pragma mark Private Objective-C Classes
@@ -522,17 +518,16 @@ VISIBILITY_HIDDEN
*
* When Tcl is compiled with TCL_UTF_MAX = 3 (the default for 8.6) it cannot
* deal directly with UTF-8 encoded non-BMP characters, since their UTF-8
- * encoding requires 4 bytes.
- *
- * As a workaround, these versions of Tcl encode non-BMP characters as a string
- * of length 6 in which the high and low UTF-16 surrogates have been encoded
- * using the UTF-8 algorithm. The UTF-8 encoding does not allow encoding
- * surrogates, so these 6-byte strings are not valid UTF-8, and hence Apple's
- * NString class will refuse to instantiate an NSString from the 6-byte
- * encoding.
- *
- * This subclass of NSString adds a new initialization method which accepts
- * a C string encoded with the scheme described above.
+ * encoding requires 4 bytes. Instead, when using these versions of Tcl, Tk
+ * uses the CESU-8 encoding internally. This encoding is similar to UTF-8
+ * except that it allows encoding surrogate characters as 3-byte sequences
+ * using the same algorithm which UTF-8 uses for non-surrogates. This means
+ * that a non-BMP character is encoded as a string of length 6. Apple's
+ * NSString class does not provide a constructor which accepts a CESU-8 encoded
+ * byte sequence as initial data. So we add a new class which does provide
+ * such a constructor. It also has a DString property which is a DString whose
+ * string pointer is a byte sequence encoding the NSString with the current Tk
+ * encoding, namely UTF-8 if TCL_MAX >= 4 or CESU-8 if TCL_MAX = 3.
*
*---------------------------------------------------------------------------
*/
@@ -543,6 +538,7 @@ VISIBILITY_HIDDEN
NSString *_string;
}
@property const char *UTF8String;
+@property (readonly) Tcl_DString DString;
- (instancetype)initWithTclUtfBytes:(const void *)bytes
length:(NSUInteger)len;
@end