Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Merge 8.6. Introduce the new Unicode-handling functions here too: Tk 8.7 could be loaded in Tcl 8.6 .... Further improvements are still possible |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
2c72c39e73ded588dc6fd2541b720a8e |
User & Date: | jan.nijtmans 2019-12-04 22:38:47.051 |
Context
2019-12-04
| ||
23:11 | Use Tcl_UtfToChar16DString() in stead of Tcl_UtfToUniCharDString(), since the first is guaranteed to be 16-bit for any TCL_UTF_MAX value. check-in: d7b67f5b user: jan.nijtmans tags: trunk | |
22:38 | Merge 8.6. Introduce the new Unicode-handling functions here too: Tk 8.7 could be loaded in Tcl 8.6 .... Further improvements are still possible check-in: 2c72c39e user: jan.nijtmans tags: trunk | |
20:35 | Make MODULE_SCOPE functions start with "Tk". Also simplify TkUtfToNSString(), making use of Tcl_UtfToUniCharDString() check-in: f98feb70 user: jan.nijtmans tags: core-8-6-branch | |
14:18 | Fix [749bd9bb1b]: systemControlAccentColor can have incorrect RGB on older macOS systems. check-in: 239d7cf2 user: marc_culler tags: trunk | |
Changes
Changes to macosx/tkMacOSXClipboard.c.
︙ | ︙ | |||
31 32 33 34 35 36 37 | [type isEqualToString:NSStringPboardType]) { for (TkClipboardTarget *targetPtr = dispPtr->clipTargetPtr; targetPtr; targetPtr = targetPtr->nextPtr) { if (targetPtr->type == XA_STRING || targetPtr->type == dispPtr->utf8Atom) { for (TkClipboardBuffer *cbPtr = targetPtr->firstBufferPtr; cbPtr; cbPtr = cbPtr->nextPtr) { | < < < | | 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | [type isEqualToString:NSStringPboardType]) { for (TkClipboardTarget *targetPtr = dispPtr->clipTargetPtr; targetPtr; targetPtr = targetPtr->nextPtr) { if (targetPtr->type == XA_STRING || targetPtr->type == dispPtr->utf8Atom) { for (TkClipboardBuffer *cbPtr = targetPtr->firstBufferPtr; cbPtr; cbPtr = cbPtr->nextPtr) { NSString *s = TkUtfToNSString(cbPtr->buffer, cbPtr->length); [string appendString:s]; [s release]; } break; } } } |
︙ | ︙ | |||
126 127 128 129 130 131 132 | int haveExternalClip = ([[NSPasteboard generalPasteboard] changeCount] != changeCount); if (dispPtr && (haveExternalClip || dispPtr->clipboardActive) && selection == dispPtr->clipboardAtom && (target == XA_STRING || target == dispPtr->utf8Atom)) { NSString *string = nil; | < > < > | > > > < < < < < < < < < < | < | < | > > > | 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 | int haveExternalClip = ([[NSPasteboard generalPasteboard] changeCount] != changeCount); if (dispPtr && (haveExternalClip || dispPtr->clipboardActive) && selection == dispPtr->clipboardAtom && (target == XA_STRING || target == dispPtr->utf8Atom)) { NSString *string = nil; NSPasteboard *pb = [NSPasteboard generalPasteboard]; NSString *type = [pb availableTypeFromArray:[NSArray arrayWithObject: NSStringPboardType]]; if (type) { 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); } } } else { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "%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); |
︙ | ︙ |
Changes to macosx/tkMacOSXFont.c.
︙ | ︙ | |||
97 98 99 100 101 102 103 104 105 106 107 108 109 110 | GC gc, Tk_Font tkfont, const char *source, int numBytes, int rangeStart, int rangeLength, int x, int y, double angle); #pragma mark - #pragma mark Font Helpers: #define GetNSFontTraitsFromTkFontAttributes(faPtr) \ ((faPtr)->weight == TK_FW_BOLD ? NSBoldFontMask : NSUnboldFontMask) | \ ((faPtr)->slant == TK_FS_ITALIC ? NSItalicFontMask : NSUnitalicFontMask) /* *--------------------------------------------------------------------------- * | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 | GC gc, Tk_Font tkfont, const char *source, int numBytes, int rangeStart, int rangeLength, int x, int y, double angle); #pragma mark - #pragma mark Font Helpers: /* *--------------------------------------------------------------------------- * * TkUtfToNSString -- * * 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 function allows creating an NSString from a C-string which * has been encoded using this scheme. * * Results: * An NSString, which may be nil. * * Side effects: * None. *--------------------------------------------------------------------------- */ MODULE_SCOPE NSString* TkUtfToNSString( const char *source, size_t numBytes) { NSString *string; Tcl_DString ds; Tcl_DStringInit(&ds); Tcl_UtfToUniCharDString(source, numBytes, &ds); string = [[NSString alloc] initWithCharacters:(const unichar *)Tcl_DStringValue(&ds) length:(Tcl_DStringLength(&ds)>>1)]; Tcl_DStringFree(&ds); return string; } /* *--------------------------------------------------------------------------- * * 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. * * 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. * */ MODULE_SCOPE int TkUtfAtIndex( NSString *string, int index, char *uni, unsigned int *code) { 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: XMaxTransChars 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. */ MODULE_SCOPE char* TkNSStringToUtf( NSString *string, int *numBytes) { unsigned int code; size_t 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++; } } *ptr = '\0'; } if (numBytes) { *numBytes = ptr - bytes; } return bytes; } #define GetNSFontTraitsFromTkFontAttributes(faPtr) \ ((faPtr)->weight == TK_FW_BOLD ? NSBoldFontMask : NSUnboldFontMask) | \ ((faPtr)->slant == TK_FS_ITALIC ? NSItalicFontMask : NSUnitalicFontMask) /* *--------------------------------------------------------------------------- * |
︙ | ︙ | |||
840 841 842 843 844 845 846 | (maxLength == 0 && !(flags & TK_AT_LEAST_ONE))) { *lengthPtr = 0; return 0; } if (maxLength > 32767) { maxLength = 32767; } | | < | 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 | (maxLength == 0 && !(flags & TK_AT_LEAST_ONE))) { *lengthPtr = 0; return 0; } if (maxLength > 32767) { maxLength = 32767; } string = TkUtfToNSString((const char *)source, numBytes); if (!string) { length = 0; fit = rangeLength; goto done; } attributedString = [[NSAttributedString alloc] initWithString:string attributes:fontPtr->nsAttributes]; |
︙ | ︙ | |||
1120 1121 1122 1123 1124 1125 1126 | int h; if (rangeStart < 0 || rangeLength <= 0 || rangeStart + rangeLength > numBytes || !TkMacOSXSetupDrawingContext(drawable, gc, 1, &drawingContext)) { return; } | | < | 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 | int h; if (rangeStart < 0 || rangeLength <= 0 || rangeStart + rangeLength > numBytes || !TkMacOSXSetupDrawingContext(drawable, gc, 1, &drawingContext)) { return; } string = TkUtfToNSString((const char *)source, numBytes); if (!string) { return; } context = drawingContext.context; fg = TkMacOSXCreateCGColor(gc, gc->foreground); attributes = [fontPtr->nsAttributes mutableCopy]; |
︙ | ︙ |
Changes to macosx/tkMacOSXKeyEvent.c.
︙ | ︙ | |||
327 328 329 330 331 332 333 | if (repRange.location == 0) { TkWindow *winPtr = TkMacOSXGetTkWindow([self window]); Tk_Window focusWin = (Tk_Window) winPtr->dispPtr->focusPtr; TkSendVirtualEvent(focusWin, "TkAccentBackspace", NULL); } /* | | > | > | | | > > > > | | < < < < < < | | | < < < < < < < < < < | < | < | 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 | if (repRange.location == 0) { TkWindow *winPtr = TkMacOSXGetTkWindow([self window]); Tk_Window focusWin = (Tk_Window) winPtr->dispPtr->focusPtr; TkSendVirtualEvent(focusWin, "TkAccentBackspace", NULL); } /* * Next we generate an XEvent for each unicode character in our string. * * NSString uses UTF-16 internally, which means that a non-BMP character is * represented by a sequence of two 16-bit "surrogates". In principle we * could record this in the XEvent by setting the keycode to the 32-bit * unicode code point and setting the trans_chars string to the 4-byte * UTF-8 string for the non-BMP character. However, that will not work * when TCL_UTF_MAX is set to 3, as is the case for Tcl 8.6. A workaround * used internally by Tcl 8.6 is to encode each surrogate as a 3-byte * sequence using the UTF-8 algorithm (ignoring the fact that the UTF-8 * encoding specification does not allow encoding UTF-16 surrogates). * This gives a 6-byte encoding of the non-BMP character which we write into * the trans_chars field of the XEvent. */ for (i = 0; i < len; i++) { xEvent.xkey.nbytes = TkUtfAtIndex(str, i, xEvent.xkey.trans_chars, &xEvent.xkey.keycode); if (xEvent.xkey.keycode > 0xffff){ i++; } xEvent.xany.type = KeyPress; Tk_QueueWindowEvent(&xEvent, TCL_QUEUE_TAIL); } releaseCode = (UInt16) [str characterAtIndex: 0]; } /* * This required method is allowed to return nil. */ |
︙ | ︙ |
Changes to macosx/tkMacOSXPrivate.h.
︙ | ︙ | |||
140 141 142 143 144 145 146 | MODULE_SCOPE long tkMacOSXMacOSXVersion; /* * Prototypes for TkMacOSXRegion.c. */ | < < < < | 140 141 142 143 144 145 146 147 148 149 150 151 152 153 | MODULE_SCOPE long tkMacOSXMacOSXVersion; /* * Prototypes for TkMacOSXRegion.c. */ MODULE_SCOPE HIShapeRef TkMacOSXGetNativeRegion(Region r); MODULE_SCOPE void TkMacOSXSetWithNativeRegion(Region r, HIShapeRef rgn); MODULE_SCOPE HIShapeRef TkMacOSXHIShapeCreateEmpty(void); MODULE_SCOPE HIMutableShapeRef TkMacOSXHIShapeCreateMutableWithRect( const CGRect *inRect); MODULE_SCOPE OSStatus TkMacOSXHIShapeSetWithShape( |
︙ | ︙ | |||
235 236 237 238 239 240 241 242 243 244 245 246 247 248 | Tcl_Obj *const objv[]); MODULE_SCOPE void TkMacOSXDrawSolidBorder(Tk_Window tkwin, GC gc, int inset, int thickness); MODULE_SCOPE int TkMacOSXServices_Init(Tcl_Interp *interp); MODULE_SCOPE int TkMacOSXRegisterServiceWidgetObjCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); #pragma mark Private Objective-C Classes #define VISIBILITY_HIDDEN __attribute__((visibility("hidden"))) enum { tkMainMenu = 1, tkApplicationMenu, tkWindowsMenu, tkHelpMenu}; | > > > > | 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 | Tcl_Obj *const objv[]); MODULE_SCOPE void TkMacOSXDrawSolidBorder(Tk_Window tkwin, GC gc, int inset, int thickness); 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); #pragma mark Private Objective-C Classes #define VISIBILITY_HIDDEN __attribute__((visibility("hidden"))) enum { tkMainMenu = 1, tkApplicationMenu, tkWindowsMenu, tkHelpMenu}; |
︙ | ︙ |
Changes to macosx/tkMacOSXRegion.c.
︙ | ︙ | |||
171 172 173 174 175 176 177 | * * Side effects: * None. * *---------------------------------------------------------------------- */ | | | 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 | * * Side effects: * None. * *---------------------------------------------------------------------- */ static int TkMacOSXIsEmptyRegion( Region r) { return HIShapeIsEmpty((HIMutableShapeRef) r) ? 1 : 0; } /* |
︙ | ︙ |