Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Enhanced proposed fix [6c0d7aec67]: unicode text input Windows 8. More places where Unicode surrogate handling could be improved. |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | rfe-6c0d7aec67 |
Files: | files | file ages | folders |
SHA1: |
158c61aa5ffd697b194a5f4d113c4966 |
User & Date: | jan.nijtmans 2016-09-19 12:05:28 |
Context
2016-09-26
| ||
09:50 | merge core-8-6-branch check-in: c8ba59a3 user: jan.nijtmans tags: rfe-6c0d7aec67 | |
2016-09-19
| ||
12:05 | Enhanced proposed fix [6c0d7aec67]: unicode text input Windows 8. More places where Unicode surrogate handling could be improved. check-in: 158c61aa user: jan.nijtmans tags: rfe-6c0d7aec67 | |
10:14 | More simplifications check-in: 2ed5f293 user: jan.nijtmans tags: rfe-6c0d7aec67 | |
2016-09-10
| ||
09:07 | Fixed [eb26817783] - listbox-13.3 fails on Linux check-in: faa07d44 user: fvogel tags: core-8-6-branch | |
Changes
Changes to generic/tkEntry.c.
︙ | ︙ | |||
1920 1921 1922 1923 1924 1925 1926 | /* * If we're displaying a special character instead of the value of the * entry, recompute the displayString. */ if (entryPtr->showChar != NULL) { | | | | | | 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 | /* * If we're displaying a special character instead of the value of the * entry, recompute the displayString. */ if (entryPtr->showChar != NULL) { int ch; char buf[6]; int size; /* * Normalize the special character so we can safely duplicate it in * the display string. If we didn't do this, then two malformed * characters might end up looking like one valid UTF character in the * resulting string. */ TkUtfToUniChar(entryPtr->showChar, &ch); size = TkUniCharToUtf(ch, buf); entryPtr->numDisplayBytes = entryPtr->numChars * size; p = ckalloc(entryPtr->numDisplayBytes + 1); entryPtr->displayString = p; for (i = entryPtr->numChars; --i >= 0; ) { memcpy(p, buf, size); |
︙ | ︙ |
Changes to generic/tkFont.c.
︙ | ︙ | |||
493 494 495 496 497 498 499 | switch ((enum options) index) { case FONT_ACTUAL: { int skip, result, n; const char *s; Tk_Font tkfont; Tcl_Obj *optPtr, *charPtr, *resultPtr; | | | 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 | switch ((enum options) index) { case FONT_ACTUAL: { int skip, result, n; const char *s; Tk_Font tkfont; Tcl_Obj *optPtr, *charPtr, *resultPtr; int uniChar = 0; const TkFontAttributes *faPtr; TkFontAttributes fa; /* * Params 0 and 1 are 'font actual'. Param 2 is the font name. 3-4 may * be '-displayof $window' */ |
︙ | ︙ | |||
558 559 560 561 562 563 564 | } /* * The 'charPtr' arg must be a single Unicode. */ if (charPtr != NULL) { | > > | > | < | 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 | } /* * The 'charPtr' arg must be a single Unicode. */ if (charPtr != NULL) { const char *string = Tcl_GetString(charPtr); int len = TkUtfToUniChar(string, &uniChar); if (len != charPtr->length) { resultPtr = Tcl_NewStringObj( "expected a single character but got \"", -1); Tcl_AppendLimitedToObj(resultPtr, string, -1, 40, "..."); Tcl_AppendToObj(resultPtr, "\"", -1); Tcl_SetObjResult(interp, resultPtr); Tcl_SetErrorCode(interp, "TK", "VALUE", "FONT_SAMPLE", NULL); return TCL_ERROR; } } /* * Find the font. */ tkfont = Tk_AllocFontFromObj(interp, tkwin, objv[2]); |
︙ | ︙ | |||
1690 1691 1692 1693 1694 1695 1696 | } else if (strcasecmp(family, "AvantGarde") == 0) { family = "AvantGarde"; } else if (strcasecmp(family, "ZapfChancery") == 0) { family = "ZapfChancery"; } else if (strcasecmp(family, "ZapfDingbats") == 0) { family = "ZapfDingbats"; } else { | | | | 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 | } else if (strcasecmp(family, "AvantGarde") == 0) { family = "AvantGarde"; } else if (strcasecmp(family, "ZapfChancery") == 0) { family = "ZapfChancery"; } else if (strcasecmp(family, "ZapfDingbats") == 0) { family = "ZapfDingbats"; } else { int ch; /* * Inline, capitalize the first letter of each word, lowercase the * rest of the letters in each word, and then take out the spaces * between the words. This may make the DString shorter, which is safe * to do. */ Tcl_DStringAppend(dsPtr, family, -1); src = dest = Tcl_DStringValue(dsPtr) + len; upper = 1; for (; *src != '\0'; ) { while (isspace(UCHAR(*src))) { /* INTL: ISO space */ src++; upper = 1; } src += TkUtfToUniChar(src, &ch); if (upper) { ch = Tcl_UniCharToUpper(ch); upper = 0; } else { ch = Tcl_UniCharToLower(ch); } dest += Tcl_UniCharToUtf(ch, dest); |
︙ | ︙ | |||
3245 3246 3247 3248 3249 3250 3251 | TextLayout *layoutPtr = (TextLayout *) layout; LayoutChunk *chunkPtr = layoutPtr->chunks; int baseline = chunkPtr->y; Tcl_Obj *psObj = Tcl_NewObj(); int i, j, len; const char *p, *glyphname; char uindex[5], c, *ps; | | | 3247 3248 3249 3250 3251 3252 3253 3254 3255 3256 3257 3258 3259 3260 3261 | TextLayout *layoutPtr = (TextLayout *) layout; LayoutChunk *chunkPtr = layoutPtr->chunks; int baseline = chunkPtr->y; Tcl_Obj *psObj = Tcl_NewObj(); int i, j, len; const char *p, *glyphname; char uindex[5], c, *ps; int ch; Tcl_AppendToObj(psObj, "[(", -1); for (i = 0; i < layoutPtr->numChunks; i++, chunkPtr++) { if (baseline != chunkPtr->y) { Tcl_AppendToObj(psObj, ")]\n[(", -1); baseline = chunkPtr->y; } |
︙ | ︙ | |||
3268 3269 3270 3271 3272 3273 3274 | /* * INTL: We only handle symbols that have an encoding as a glyph * from the standard set defined by Adobe. The rest get punted. * Eventually this should be revised to handle more sophsticiated * international postscript fonts. */ | | | 3270 3271 3272 3273 3274 3275 3276 3277 3278 3279 3280 3281 3282 3283 3284 | /* * INTL: We only handle symbols that have an encoding as a glyph * from the standard set defined by Adobe. The rest get punted. * Eventually this should be revised to handle more sophsticiated * international postscript fonts. */ p += TkUtfToUniChar(p, &ch); if ((ch == '(') || (ch == ')') || (ch == '\\') || (ch < 0x20)) { /* * Tricky point: the "03" is necessary in the sprintf below, * so that a full three digits of octal are always generated. * Without the "03", a number following this sequence could be * interpreted by Postscript as part of this sequence. */ |
︙ | ︙ | |||
3294 3295 3296 3297 3298 3299 3300 3301 3302 3303 3304 3305 3306 3307 3308 3309 3310 3311 3312 3313 3314 3315 3316 3317 3318 3319 3320 3321 3322 3323 3324 3325 3326 3327 | } /* * This character doesn't belong to the ASCII character set, so we * use the full glyph name. */ sprintf(uindex, "%04X", ch); /* endianness? */ glyphname = Tcl_GetVar2(interp, "::tk::psglyphs", uindex, 0); if (glyphname) { ps = Tcl_GetStringFromObj(psObj, &len); if (ps[len-1] == '(') { /* * In-place edit. Ewww! */ ps[len-1] = '/'; } else { Tcl_AppendToObj(psObj, ")/", -1); } Tcl_AppendToObj(psObj, glyphname, -1); Tcl_AppendToObj(psObj, "(", -1); } else { /* * No known mapping for the character into the space of * PostScript glyphs. Ignore it. :-( */ #ifdef TK_DEBUG_POSTSCRIPT_OUTPUT fprintf(stderr, "Warning: no mapping to PostScript " "glyphs for \\u%04x\n", ch); #endif } } | > > > > | 3296 3297 3298 3299 3300 3301 3302 3303 3304 3305 3306 3307 3308 3309 3310 3311 3312 3313 3314 3315 3316 3317 3318 3319 3320 3321 3322 3323 3324 3325 3326 3327 3328 3329 3330 3331 3332 3333 | } /* * This character doesn't belong to the ASCII character set, so we * use the full glyph name. */ if (ch > 0xffff) { goto noMapping; } sprintf(uindex, "%04X", ch); /* endianness? */ glyphname = Tcl_GetVar2(interp, "::tk::psglyphs", uindex, 0); if (glyphname) { ps = Tcl_GetStringFromObj(psObj, &len); if (ps[len-1] == '(') { /* * In-place edit. Ewww! */ ps[len-1] = '/'; } else { Tcl_AppendToObj(psObj, ")/", -1); } Tcl_AppendToObj(psObj, glyphname, -1); Tcl_AppendToObj(psObj, "(", -1); } else { /* * No known mapping for the character into the space of * PostScript glyphs. Ignore it. :-( */ noMapping: ; #ifdef TK_DEBUG_POSTSCRIPT_OUTPUT fprintf(stderr, "Warning: no mapping to PostScript " "glyphs for \\u%04x\n", ch); #endif } } |
︙ | ︙ |
Changes to generic/tkInt.h.
︙ | ︙ | |||
1192 1193 1194 1195 1196 1197 1198 | int rangeLength, int maxLength, int flags, int *lengthPtr); MODULE_SCOPE void TkUnderlineCharsInContext(Display *display, Drawable drawable, GC gc, Tk_Font tkfont, const char *string, int numBytes, int x, int y, int firstByte, int lastByte); MODULE_SCOPE void TkpGetFontAttrsForChar(Tk_Window tkwin, Tk_Font tkfont, | | | 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 | int rangeLength, int maxLength, int flags, int *lengthPtr); MODULE_SCOPE void TkUnderlineCharsInContext(Display *display, Drawable drawable, GC gc, Tk_Font tkfont, const char *string, int numBytes, int x, int y, int firstByte, int lastByte); MODULE_SCOPE void TkpGetFontAttrsForChar(Tk_Window tkwin, Tk_Font tkfont, int c, struct TkFontAttributes *faPtr); MODULE_SCOPE Tcl_Obj * TkNewWindowObj(Tk_Window tkwin); MODULE_SCOPE void TkpShowBusyWindow(TkBusy busy); MODULE_SCOPE void TkpHideBusyWindow(TkBusy busy); MODULE_SCOPE void TkpMakeTransparentWindowExist(Tk_Window tkwin, Window parent); MODULE_SCOPE void TkpCreateBusy(Tk_FakeWin *winPtr, Tk_Window tkRef, Window *parentPtr, Tk_Window tkParent, |
︙ | ︙ | |||
1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 | MODULE_SCOPE Status TkParseColor (Display * display, Colormap map, const char* spec, XColor * colorPtr); #endif #ifdef HAVE_XFT MODULE_SCOPE void TkUnixSetXftClipRegion(TkRegion clipRegion); #endif /* * Unsupported commands. */ MODULE_SCOPE int TkUnsupported1ObjCmd(ClientData clientData, Tcl_Interp *interp, int objc, | > > > > > > > > | 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 | MODULE_SCOPE Status TkParseColor (Display * display, Colormap map, const char* spec, XColor * colorPtr); #endif #ifdef HAVE_XFT MODULE_SCOPE void TkUnixSetXftClipRegion(TkRegion clipRegion); #endif #if TCL_UTF_MAX > 4 # define TkUtfToUniChar Tcl_UtfToUniChar # define TkUniCharToUtf Tcl_UniCharToUtf #else MODULE_SCOPE int TkUtfToUniChar(const char *, int *); MODULE_SCOPE int TkUniCharToUtf(int, char *); #endif /* * Unsupported commands. */ MODULE_SCOPE int TkUnsupported1ObjCmd(ClientData clientData, Tcl_Interp *interp, int objc, |
︙ | ︙ |
Changes to generic/tkText.c.
︙ | ︙ | |||
4455 4456 4457 4458 4459 4460 4461 | Tcl_Obj *stringPtr) /* Description of the tab stops. See the text * manual entry for details. */ { int objc, i, count; Tcl_Obj **objv; TkTextTabArray *tabArrayPtr; TkTextTab *tabPtr; | | | 4455 4456 4457 4458 4459 4460 4461 4462 4463 4464 4465 4466 4467 4468 4469 | Tcl_Obj *stringPtr) /* Description of the tab stops. See the text * manual entry for details. */ { int objc, i, count; Tcl_Obj **objv; TkTextTabArray *tabArrayPtr; TkTextTab *tabPtr; int ch; double prevStop, lastStop; /* * Map these strings to TkTextTabAlign values. */ static const char *const tabOptionStrings[] = { "left", "right", "center", "numeric", NULL }; |
︙ | ︙ | |||
4562 4563 4564 4565 4566 4567 4568 | continue; } /* * There may be a more efficient way of getting this. */ | | | 4562 4563 4564 4565 4566 4567 4568 4569 4570 4571 4572 4573 4574 4575 4576 | continue; } /* * There may be a more efficient way of getting this. */ TkUtfToUniChar(Tcl_GetString(objv[i+1]), &ch); if (!Tcl_UniCharIsAlpha(ch)) { continue; } i += 1; if (Tcl_GetIndexFromObjStruct(interp, objv[i], tabOptionStrings, sizeof(char *), "tab alignment", 0, &index) != TCL_OK) { |
︙ | ︙ | |||
5876 5877 5878 5879 5880 5881 5882 | if (searchSpecPtr->exact) { int maxExtraLines = 0; const char *startOfLine = Tcl_GetString(theLine); CLANG_ASSERT(pattern); do { | | | 5876 5877 5878 5879 5880 5881 5882 5883 5884 5885 5886 5887 5888 5889 5890 | if (searchSpecPtr->exact) { int maxExtraLines = 0; const char *startOfLine = Tcl_GetString(theLine); CLANG_ASSERT(pattern); do { int ch; const char *p; int lastFullLine = lastOffset; if (firstNewLine == -1) { if (searchSpecPtr->strictLimits && (firstOffset + matchLength > lastOffset)) { /* |
︙ | ︙ | |||
6106 6107 6108 6109 6110 6111 6112 | if (searchSpecPtr->backwards) { alreadySearchOffset = p - startOfLine - 1; if (alreadySearchOffset < 0) { break; } } else { firstOffset = p - startOfLine + | | | 6106 6107 6108 6109 6110 6111 6112 6113 6114 6115 6116 6117 6118 6119 6120 | if (searchSpecPtr->backwards) { alreadySearchOffset = p - startOfLine - 1; if (alreadySearchOffset < 0) { break; } } else { firstOffset = p - startOfLine + TkUtfToUniChar(startOfLine+matchOffset,&ch); } } } while (searchSpecPtr->all); } else { int maxExtraLines = 0; int matches = 0; int lastNonOverlap = -1; |
︙ | ︙ |
Changes to generic/tkTextDisp.c.
︙ | ︙ | |||
7577 7578 7579 7580 7581 7582 7583 | #else /* !TK_LAYOUT_WITH_BASE_CHUNKS */ bytesThatFit = CharChunkMeasureChars(chunkPtr, p, maxBytes, 0, -1, chunkPtr->x, maxX, TK_ISOLATE_END, &nextX); #endif /* TK_LAYOUT_WITH_BASE_CHUNKS */ if (bytesThatFit < maxBytes) { if ((bytesThatFit == 0) && noCharsYet) { | | | | 7577 7578 7579 7580 7581 7582 7583 7584 7585 7586 7587 7588 7589 7590 7591 7592 | #else /* !TK_LAYOUT_WITH_BASE_CHUNKS */ bytesThatFit = CharChunkMeasureChars(chunkPtr, p, maxBytes, 0, -1, chunkPtr->x, maxX, TK_ISOLATE_END, &nextX); #endif /* TK_LAYOUT_WITH_BASE_CHUNKS */ if (bytesThatFit < maxBytes) { if ((bytesThatFit == 0) && noCharsYet) { int ch; int chLen = TkUtfToUniChar(p, &ch); #if TK_LAYOUT_WITH_BASE_CHUNKS bytesThatFit = CharChunkMeasureChars(chunkPtr, line, lineOffset+chLen, lineOffset, -1, chunkPtr->x, -1, 0, &nextX); #else /* !TK_LAYOUT_WITH_BASE_CHUNKS */ bytesThatFit = CharChunkMeasureChars(chunkPtr, p, chLen, 0, -1, |
︙ | ︙ |
Changes to generic/tkTextIndex.c.
︙ | ︙ | |||
2294 2295 2296 2297 2298 2299 2300 | COUNT_DISPLAY_INDICES); } segPtr = TkTextIndexToSeg(indexPtr, &offset); while (1) { int chSize = 1; if (segPtr->typePtr == &tkTextCharType) { | | | | 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 | COUNT_DISPLAY_INDICES); } segPtr = TkTextIndexToSeg(indexPtr, &offset); while (1) { int chSize = 1; if (segPtr->typePtr == &tkTextCharType) { int ch; chSize = TkUtfToUniChar(segPtr->body.chars + offset, &ch); if (!Tcl_UniCharIsWordChar(ch)) { break; } firstChar = 0; } offset += chSize; indexPtr->byteIndex += chSize; |
︙ | ︙ | |||
2339 2340 2341 2342 2343 2344 2345 | */ segPtr = TkTextIndexToSeg(indexPtr, &offset); while (1) { int chSize = 1; if (segPtr->typePtr == &tkTextCharType) { | < > | | 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 | */ segPtr = TkTextIndexToSeg(indexPtr, &offset); while (1) { int chSize = 1; if (segPtr->typePtr == &tkTextCharType) { int ch; TkUtfToUniChar(segPtr->body.chars + offset, &ch); if (!Tcl_UniCharIsWordChar(ch)) { break; } if (offset > 0) { chSize = (segPtr->body.chars + offset - Tcl_UtfPrev(segPtr->body.chars + offset, segPtr->body.chars)); |
︙ | ︙ |
Changes to generic/tkUtil.c.
︙ | ︙ | |||
1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 | event.virtual.name = Tk_GetUid(eventName); if (detail != NULL) { event.virtual.user_data = detail; } Tk_QueueWindowEvent(&event.general, TCL_QUEUE_TAIL); } /* * Local Variables: * mode: c * c-basic-offset: 4 * fill-column: 78 * End: */ | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 | event.virtual.name = Tk_GetUid(eventName); if (detail != NULL) { event.virtual.user_data = detail; } Tk_QueueWindowEvent(&event.general, TCL_QUEUE_TAIL); } #if TCL_UTF_MAX <= 4 /* *--------------------------------------------------------------------------- * * TkUtfToUniChar -- * * Almost the same as Tcl_UtfToUniChar but using int instead of Tcl_UniChar. * This function is capable of collapsing a upper/lower pair to a single * unicode character. So, up to 6 bytes (two UTF-8 characters) might be read. * * Results: * *chPtr is filled with the Tcl_UniChar, and the return value is the * number of bytes from the UTF-8 string that were consumed. * * Side effects: * None. * *--------------------------------------------------------------------------- */ int TkUtfToUniChar( const char *src, /* The UTF-8 string. */ int *chPtr) /* Filled with the Tcl_UniChar represented by * the UTF-8 string. */ { Tcl_UniChar uniChar = 0; int len = Tcl_UtfToUniChar(src, &uniChar); if ((uniChar & 0xfc00) == 0xd800) { Tcl_UniChar high = uniChar; /* This can only happen when Tcl is compiled with TCL_UTF_MAX=4, * or when a high surrogate character is detected */ int len2 = Tcl_UtfToUniChar(src+len, &uniChar); if ((uniChar & 0xfc00) == 0xdc00) { *chPtr = ((high & 0x3ff) << 10) | (uniChar & 0x3ff) | 0x10000; len += len2; } else { *chPtr = high; } } else { *chPtr = uniChar; } return len; } /* *--------------------------------------------------------------------------- * * TkUniCharToUtf -- * * Almost the same as Tcl_UniCharToUtf but producing surrogates if * TCL_UTF_MAX==3. * * Results: * *buf is filled with the UTF-8 string, and the return value is the * number of bytes produced. * * Side effects: * None. * *--------------------------------------------------------------------------- */ int TkUniCharToUtf(int ch, char *buf) { int size = Tcl_UniCharToUtf(ch, buf); if ((ch > 0xffff) && (size < 4)) { /* Hey, this is wrong, we must be running TCL_UTF_MAX==3 * The best thing we can do is spit out 2 surrogates */ ch -= 0x10000; size = Tcl_UniCharToUtf(((ch >> 10) | 0xd800), buf); size += Tcl_UniCharToUtf(((ch & 0x3ff) | 0xdc00), buf+size); } return size; } #endif /* * Local Variables: * mode: c * c-basic-offset: 4 * fill-column: 78 * End: */ |
Changes to generic/ttk/ttkEntry.c.
︙ | ︙ | |||
278 279 280 281 282 283 284 | * of (the first character in the string) 'showChar'. * Used to compute the displayString if -show is non-NULL. */ static char *EntryDisplayString(const char *showChar, int numChars) { char *displayString, *p; int size; | | | | | | 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 | * of (the first character in the string) 'showChar'. * Used to compute the displayString if -show is non-NULL. */ static char *EntryDisplayString(const char *showChar, int numChars) { char *displayString, *p; int size; int ch; char buf[6]; TkUtfToUniChar(showChar, &ch); size = TkUniCharToUtf(ch, buf); p = displayString = ckalloc(numChars * size + 1); while (numChars--) { memcpy(p, buf, size); p += size; } *p = '\0'; |
︙ | ︙ | |||
402 403 404 405 406 407 408 | VREASON reason, /* Reason for change */ Tcl_DString *dsPtr) /* Result of %-substitutions */ { int spaceNeeded, cvtFlags; int number, length; const char *string; int stringLength; | | | 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 | VREASON reason, /* Reason for change */ Tcl_DString *dsPtr) /* Result of %-substitutions */ { int spaceNeeded, cvtFlags; int number, length; const char *string; int stringLength; int ch; char numStorage[2*TCL_INTEGER_SPACE]; while (*template) { /* Find everything up to the next % character and append it * to the result string. */ string = Tcl_UtfFindFirst(template, '%'); |
︙ | ︙ | |||
426 427 428 429 430 431 432 | template = string; } /* There's a percent sequence here. Process it. */ ++template; /* skip over % */ if (*template != '\0') { | | | 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 | template = string; } /* There's a percent sequence here. Process it. */ ++template; /* skip over % */ if (*template != '\0') { template += TkUtfToUniChar(template, &ch); } else { ch = '%'; } stringLength = -1; switch (ch) { case 'd': /* Type of call that caused validation */ |
︙ | ︙ | |||
476 477 478 479 480 481 482 | case 'V': /* type of validation in effect */ string = validateReasonStrings[reason]; break; case 'W': /* widget name */ string = Tk_PathName(entryPtr->core.tkwin); break; default: | | | 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 | case 'V': /* type of validation in effect */ string = validateReasonStrings[reason]; break; case 'W': /* widget name */ string = Tk_PathName(entryPtr->core.tkwin); break; default: length = TkUniCharToUtf(ch, numStorage); numStorage[length] = '\0'; string = numStorage; break; } spaceNeeded = Tcl_ScanCountedElement(string, stringLength, &cvtFlags); length = Tcl_DStringLength(dsPtr); |
︙ | ︙ |
Changes to macosx/tkMacOSXFont.c.
︙ | ︙ | |||
668 669 670 671 672 673 674 | *---------------------------------------------------------------------- */ void TkpGetFontAttrsForChar( Tk_Window tkwin, /* Window on the font's display */ Tk_Font tkfont, /* Font to query */ | | | | 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 | *---------------------------------------------------------------------- */ void TkpGetFontAttrsForChar( Tk_Window tkwin, /* Window on the font's display */ Tk_Font tkfont, /* Font to query */ int c, /* Character of interest */ TkFontAttributes* faPtr) /* Output: Font attributes */ { MacFont *fontPtr = (MacFont *) tkfont; NSFont *nsFont = fontPtr->nsFont; *faPtr = fontPtr->font.fa; if (nsFont && ![[nsFont coveredCharacterSet] characterIsMember:c]) { UTF16Char ch = (UTF16Char) c; nsFont = [nsFont bestMatchingFontForCharacters:&ch length:1 attributes:nil actualCoveredLength:NULL]; if (nsFont) { GetTkFontAttributesForNSFont(nsFont, faPtr); } } |
︙ | ︙ |
Changes to unix/tkUnixFont.c.
︙ | ︙ | |||
402 403 404 405 406 407 408 | * the conversion. */ int *dstCharsPtr) /* Filled with the number of characters that * correspond to the bytes stored in the * output buffer. */ { const char *srcStart, *srcEnd; char *dstStart, *dstEnd; | | | | | > > > > > > > > | 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 | * the conversion. */ int *dstCharsPtr) /* Filled with the number of characters that * correspond to the bytes stored in the * output buffer. */ { const char *srcStart, *srcEnd; char *dstStart, *dstEnd; int ch; int result; static char hexChars[] = "0123456789abcdef"; static char mapChars[] = { 0, 0, 0, 0, 0, 0, 0, 'a', 'b', 't', 'n', 'v', 'f', 'r' }; result = TCL_OK; srcStart = src; srcEnd = src + srcLen; dstStart = dst; dstEnd = dst + dstLen - 6; for ( ; src < srcEnd; ) { if (dst > dstEnd) { result = TCL_CONVERT_NOSPACE; break; } src += TkUtfToUniChar(src, &ch); dst[0] = '\\'; if (((size_t) ch < sizeof(mapChars)) && (mapChars[ch] != 0)) { dst[1] = mapChars[ch]; dst += 2; } else if (ch < 256) { dst[1] = 'x'; dst[2] = hexChars[(ch >> 4) & 0xf]; dst[3] = hexChars[ch & 0xf]; dst += 4; } else if (ch < 0x10000) { dst[1] = 'u'; dst[2] = hexChars[(ch >> 12) & 0xf]; dst[3] = hexChars[(ch >> 8) & 0xf]; dst[4] = hexChars[(ch >> 4) & 0xf]; dst[5] = hexChars[ch & 0xf]; dst += 6; } else { /* TODO we can do better here */ dst[1] = 'u'; dst[2] = 'f'; dst[3] = 'f'; dst[4] = 'f'; dst[5] = 'd'; dst += 6; } } *srcReadPtr = src - srcStart; *dstWrotePtr = dst - dstStart; *dstCharsPtr = dst - dstStart; return result; } |
︙ | ︙ | |||
942 943 944 945 946 947 948 | *---------------------------------------------------------------------- */ void TkpGetFontAttrsForChar( Tk_Window tkwin, /* Window on the font's display */ Tk_Font tkfont, /* Font to query */ | | | 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 | *---------------------------------------------------------------------- */ void TkpGetFontAttrsForChar( Tk_Window tkwin, /* Window on the font's display */ Tk_Font tkfont, /* Font to query */ int c, /* Character of interest */ TkFontAttributes *faPtr) /* Output: Font attributes */ { FontAttributes atts; UnixFont *fontPtr = (UnixFont *) tkfont; /* Structure describing the logical font */ SubFont *lastSubFontPtr = &fontPtr->subFontArray[0]; /* Pointer to subfont array in case |
︙ | ︙ | |||
1024 1025 1026 1027 1028 1029 1030 | lastSubFontPtr = &fontPtr->subFontArray[0]; if (numBytes == 0) { curX = 0; curByte = 0; } else if (maxLength < 0) { const char *p, *end, *next; | | | | 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 | lastSubFontPtr = &fontPtr->subFontArray[0]; if (numBytes == 0) { curX = 0; curByte = 0; } else if (maxLength < 0) { const char *p, *end, *next; int ch; SubFont *thisSubFontPtr; FontFamily *familyPtr; Tcl_DString runString; /* * A three step process: * 1. Find a contiguous range of characters that can all be * represented by a single screen font. * 2. Convert those chars to the encoding of that font. * 3. Measure converted chars. */ curX = 0; end = source + numBytes; for (p = source; p < end; ) { next = p + TkUtfToUniChar(p, &ch); thisSubFontPtr = FindSubFontForChar(fontPtr, ch, &lastSubFontPtr); if (thisSubFontPtr != lastSubFontPtr) { familyPtr = lastSubFontPtr->familyPtr; Tcl_UtfToExternalDString(familyPtr->encoding, source, p - source, &runString); if (familyPtr->isTwoByteFont) { curX += XTextWidth16(lastSubFontPtr->fontStructPtr, |
︙ | ︙ |
Changes to unix/tkUnixRFont.c.
︙ | ︙ | |||
611 612 613 614 615 616 617 | *---------------------------------------------------------------------- */ void TkpGetFontAttrsForChar( Tk_Window tkwin, /* Window on the font's display */ Tk_Font tkfont, /* Font to query */ | | | 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 | *---------------------------------------------------------------------- */ void TkpGetFontAttrsForChar( Tk_Window tkwin, /* Window on the font's display */ Tk_Font tkfont, /* Font to query */ int c, /* Character of interest */ TkFontAttributes *faPtr) /* Output: Font attributes */ { UnixFtFont *fontPtr = (UnixFtFont *) tkfont; /* Structure describing the logical font */ FcChar32 ucs4 = (FcChar32) c; /* UCS-4 character to map */ XftFont *ftFont = GetFont(fontPtr, ucs4, 0.0); |
︙ | ︙ | |||
664 665 666 667 668 669 670 | int len = 0; #endif /* DEBUG_FONTSEL */ curX = 0; curByte = 0; sawNonSpace = 0; while (numBytes > 0) { | | | | 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 | int len = 0; #endif /* DEBUG_FONTSEL */ curX = 0; curByte = 0; sawNonSpace = 0; while (numBytes > 0) { int unichar; clen = TkUtfToUniChar(source, &unichar); c = (FcChar32) unichar; if (clen <= 0) { /* * This can't happen (but see #1185640) */ |
︙ | ︙ |
Changes to win/tkWinFont.c.
︙ | ︙ | |||
22 23 24 25 26 27 28 | * instance of this structure. The most important shared property is the * character existence metrics, used to determine if a screen font can display * a given Unicode character. * * Under Windows, a "font family" is uniquely identified by its face name. */ | | < | | 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | * instance of this structure. The most important shared property is the * character existence metrics, used to determine if a screen font can display * a given Unicode character. * * Under Windows, a "font family" is uniquely identified by its face name. */ #define FONTMAP_SHIFT 12 #define FONTMAP_PAGES (1 << (21 - FONTMAP_SHIFT)) #define FONTMAP_BITSPERPAGE (1 << FONTMAP_SHIFT) typedef struct FontFamily { struct FontFamily *nextPtr; /* Next in list of all known font families. */ size_t refCount; /* How many SubFonts are referring to this * FontFamily. When the refCount drops to * zero, this FontFamily may be freed. */ |
︙ | ︙ | |||
739 740 741 742 743 744 745 | *---------------------------------------------------------------------- */ void TkpGetFontAttrsForChar( Tk_Window tkwin, /* Window on the font's display */ Tk_Font tkfont, /* Font to query */ | | | 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 | *---------------------------------------------------------------------- */ void TkpGetFontAttrsForChar( Tk_Window tkwin, /* Window on the font's display */ Tk_Font tkfont, /* Font to query */ int c, /* Character of interest */ TkFontAttributes *faPtr) /* Output: Font attributes */ { WinFont *fontPtr = (WinFont *) tkfont; /* Structure describing the logical font */ HDC hdc = GetDC(fontPtr->hwnd); /* GDI device context */ SubFont *lastSubFontPtr = &fontPtr->subFontArray[0]; |
︙ | ︙ | |||
824 825 826 827 828 829 830 | int *lengthPtr) /* Filled with x-location just after the * terminating character. */ { HDC hdc; HFONT oldFont; WinFont *fontPtr; int curX, moretomeasure; | | | 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 | int *lengthPtr) /* Filled with x-location just after the * terminating character. */ { HDC hdc; HFONT oldFont; WinFont *fontPtr; int curX, moretomeasure; int ch; SIZE size; FontFamily *familyPtr; Tcl_DString runString; SubFont *thisSubFontPtr, *lastSubFontPtr; const char *p, *end, *next = NULL, *start; if (numBytes == 0) { |
︙ | ︙ | |||
855 856 857 858 859 860 861 | */ moretomeasure = 0; curX = 0; start = source; end = start + numBytes; for (p = start; p < end; ) { | | | 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 | */ moretomeasure = 0; curX = 0; start = source; end = start + numBytes; for (p = start; p < end; ) { next = p + TkUtfToUniChar(p, &ch); thisSubFontPtr = FindSubFontForChar(fontPtr, ch, &lastSubFontPtr); if (thisSubFontPtr != lastSubFontPtr) { familyPtr = lastSubFontPtr->familyPtr; Tcl_UtfToExternalDString(familyPtr->encoding, start, (int) (p - start), &runString); size.cx = 0; familyPtr->getTextExtentPoint32Proc(hdc, |
︙ | ︙ | |||
917 918 919 920 921 922 923 | char buf[16]; int dstWrote; int lastSize = 0; familyPtr = lastSubFontPtr->familyPtr; Tcl_DStringInit(&runString); for (p = start; p < end; ) { | | | 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 | char buf[16]; int dstWrote; int lastSize = 0; familyPtr = lastSubFontPtr->familyPtr; Tcl_DStringInit(&runString); for (p = start; p < end; ) { next = p + TkUtfToUniChar(p, &ch); Tcl_UtfToExternal(NULL, familyPtr->encoding, p, (int) (next - p), 0, NULL, buf, sizeof(buf), NULL, &dstWrote, NULL); Tcl_DStringAppend(&runString,buf,dstWrote); size.cx = 0; familyPtr->getTextExtentPoint32Proc(hdc, (TCHAR *) Tcl_DStringValue(&runString), |
︙ | ︙ | |||
966 967 968 969 970 971 972 | if ((flags & TK_WHOLE_WORDS) && (p < end)) { /* * Scan the string for the last word break and than repeat the whole * procedure without the maxLength limit or any flags. */ const char *lastWordBreak = NULL; | | | | 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 | if ((flags & TK_WHOLE_WORDS) && (p < end)) { /* * Scan the string for the last word break and than repeat the whole * procedure without the maxLength limit or any flags. */ const char *lastWordBreak = NULL; int ch2; end = p; p = source; ch = ' '; while (p < end) { next = p + TkUtfToUniChar(p, &ch2); if ((ch != ' ') && (ch2 == ' ')) { lastWordBreak = p; } p = next; ch = ch2; } |
︙ | ︙ | |||
1439 1440 1441 1442 1443 1444 1445 | * following string. */ const char *source, /* Potentially multilingual UTF-8 string. */ int numBytes, /* Length of string in bytes. */ int x, int y, /* Coordinates at which to place origin of * string when drawing. */ double angle) { | | | | 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 | * following string. */ const char *source, /* Potentially multilingual UTF-8 string. */ int numBytes, /* Length of string in bytes. */ int x, int y, /* Coordinates at which to place origin of * string when drawing. */ double angle) { int ch; SIZE size; HFONT oldFont; FontFamily *familyPtr; Tcl_DString runString; const char *p, *end, *next; SubFont *lastSubFontPtr, *thisSubFontPtr; TEXTMETRICA tm; lastSubFontPtr = &fontPtr->subFontArray[0]; oldFont = SelectFont(hdc, fontPtr, lastSubFontPtr, angle); GetTextMetricsA(hdc, &tm); end = source + numBytes; for (p = source; p < end; ) { next = p + TkUtfToUniChar(p, &ch); thisSubFontPtr = FindSubFontForChar(fontPtr, ch, &lastSubFontPtr); if (thisSubFontPtr != lastSubFontPtr) { if (p > source) { familyPtr = lastSubFontPtr->familyPtr; Tcl_UtfToExternalDString(familyPtr->encoding, source, (int) (p - source), &runString); familyPtr->textOutProc(hdc, x-(tm.tmOverhang/2), y, |
︙ | ︙ |
Changes to win/tkWinKey.c.
︙ | ︙ | |||
84 85 86 87 88 89 90 91 92 93 94 95 96 97 | TkWindow *winPtr, /* Window where event occurred: needed to get * input context. */ XEvent *eventPtr, /* X keyboard event. */ Tcl_DString *dsPtr) /* Uninitialized or empty string to hold * result. */ { XKeyEvent *keyEv = &eventPtr->xkey; Tcl_DStringInit(dsPtr); if (keyEv->send_event == -1) { if (keyEv->nbytes > 0) { Tcl_ExternalToUtfDString(TkWinGetKeyInputEncoding(), keyEv->trans_chars, keyEv->nbytes, dsPtr); } | > > < < < < < < < < < < < < < < < < < < < < | | < | < < < < < < < < < | 84 85 86 87 88 89 90 91 92 93 94 95 96 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 | TkWindow *winPtr, /* Window where event occurred: needed to get * input context. */ XEvent *eventPtr, /* X keyboard event. */ Tcl_DString *dsPtr) /* Uninitialized or empty string to hold * result. */ { XKeyEvent *keyEv = &eventPtr->xkey; int len; char buf[6]; Tcl_DStringInit(dsPtr); if (keyEv->send_event == -1) { if (keyEv->nbytes > 0) { Tcl_ExternalToUtfDString(TkWinGetKeyInputEncoding(), keyEv->trans_chars, keyEv->nbytes, dsPtr); } } else if (keyEv->send_event == -3) { /* * Special case for WM_UNICHAR and win2000 multi-lingal IME input */ len = TkUniCharToUtf(keyEv->keycode, buf); Tcl_DStringAppend(dsPtr, buf, len); } else { /* * This is an event generated from generic code. It has no nchars or * trans_chars members. */ KeySym keysym = KeycodeToKeysym(keyEv->keycode, keyEv->state, 0); if (((keysym != NoSymbol) && (keysym > 0) && (keysym < 256)) || (keysym == XK_Return) || (keysym == XK_Tab)) { len = Tcl_UniCharToUtf((Tcl_UniChar) (keysym & 255), buf); Tcl_DStringAppend(dsPtr, buf, len); } } return Tcl_DStringValue(dsPtr); } |
︙ | ︙ |
Changes to win/tkWinX.c.
︙ | ︙ | |||
1576 1577 1578 1579 1580 1581 1582 | int i; n = ImmGetCompositionString(hIMC, GCS_RESULTSTR, buff, (unsigned) n); /* * Set up the fields pertinent to key event. * | | | | < | | | | 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 | int i; n = ImmGetCompositionString(hIMC, GCS_RESULTSTR, buff, (unsigned) n); /* * Set up the fields pertinent to key event. * * We set send_event to the special value of -3, so that TkpGetString * in tkWinKey.c knows that keycode already contains a UNICODE * char and there's no need to do encoding conversion. * * Note that the event *must* be zeroed out first; Tk plays cunning * games with the overalls structure. [Bug 2992129] */ winPtr = (TkWindow *) Tk_HWNDToWindow(hwnd); memset(&event, 0, sizeof(XEvent)); event.xkey.serial = winPtr->display->request++; event.xkey.send_event = -3; event.xkey.display = winPtr->display; event.xkey.window = winPtr->window; event.xkey.root = RootWindow(winPtr->display, winPtr->screenNum); event.xkey.subwindow = None; event.xkey.state = TkWinGetModifierState(); event.xkey.time = TkpGetMS(); event.xkey.same_screen = True; event.xkey.nbytes = 0; for (i=0; i<n; ) { /* * Simulate a pair of KeyPress and KeyRelease events for each * UNICODE character in the composition. */ event.xkey.keycode = ((unsigned char) buff[i++]) << 8; event.xkey.keycode += (unsigned char) buff[i++]; event.type = KeyPress; Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL); event.type = KeyRelease; Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL); } |
︙ | ︙ |