From bdb580aa2563588e6e1f5090bb9b89369e2f2d4f Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Mon, 19 Sep 2016 10:14:52 +0000 Subject: More simplifications --- generic/tkEntry.c | 8 ++++---- generic/tkFont.c | 6 +++--- generic/tkInt.h | 6 ++++-- generic/tkText.c | 6 +++--- generic/tkTextDisp.c | 2 +- generic/tkTextIndex.c | 4 ++-- generic/tkUtil.c | 37 +++++++++++++++++++++++++++++++++++-- generic/ttk/ttkEntry.c | 14 +++++++------- unix/tkUnixFont.c | 20 ++++++++++++++------ unix/tkUnixRFont.c | 2 +- win/tkWinFont.c | 8 ++++---- win/tkWinKey.c | 38 +++++--------------------------------- win/tkWinX.c | 13 ++++++------- 13 files changed, 89 insertions(+), 75 deletions(-) diff --git a/generic/tkEntry.c b/generic/tkEntry.c index a66cf18..34f11d2 100644 --- a/generic/tkEntry.c +++ b/generic/tkEntry.c @@ -1926,8 +1926,8 @@ EntryComputeGeometry( */ if (entryPtr->showChar != NULL) { - Tcl_UniChar ch; - char buf[4]; + int ch; + char buf[6]; int size; /* @@ -1937,8 +1937,8 @@ EntryComputeGeometry( * resulting string. */ - Tcl_UtfToUniChar(entryPtr->showChar, &ch); - size = Tcl_UniCharToUtf(ch, buf); + TkUtfToUniChar(entryPtr->showChar, &ch); + size = TkUniCharToUtf(ch, buf); entryPtr->numDisplayBytes = entryPtr->numChars * size; p = ckalloc(entryPtr->numDisplayBytes + 1); diff --git a/generic/tkFont.c b/generic/tkFont.c index 4a45691..1947666 100644 --- a/generic/tkFont.c +++ b/generic/tkFont.c @@ -563,7 +563,7 @@ Tk_FontObjCmd( if (charPtr != NULL) { const char *string = Tcl_GetString(charPtr); - int len = TkUtfToUniChar2(string, &uniChar); + int len = TkUtfToUniChar(string, &uniChar); if (len != charPtr->length) { resultPtr = Tcl_NewStringObj( @@ -1714,7 +1714,7 @@ Tk_PostscriptFontName( src++; upper = 1; } - src += TkUtfToUniChar2(src, &ch); + src += TkUtfToUniChar(src, &ch); if (upper) { ch = (Tcl_UniChar) Tcl_UniCharToUpper(ch); upper = 0; @@ -3274,7 +3274,7 @@ Tk_TextLayoutToPostscript( * international postscript fonts. */ - p += TkUtfToUniChar2(p, &ch); + p += TkUtfToUniChar(p, &ch); if ((ch == '(') || (ch == ')') || (ch == '\\') || (ch < 0x20)) { /* * Tricky point: the "03" is necessary in the sprintf below, diff --git a/generic/tkInt.h b/generic/tkInt.h index 6d86e08..1615a81 100644 --- a/generic/tkInt.h +++ b/generic/tkInt.h @@ -1233,9 +1233,11 @@ MODULE_SCOPE void TkUnixSetXftClipRegion(TkRegion clipRegion); #endif #if TCL_UTF_MAX > 4 -# define TkUtfToUniChar2 Tcl_UtfToUniChar +# define TkUtfToUniChar Tcl_UtfToUniChar +# define TkUniCharToUtf Tcl_UniCharToUtf #else - MODULE_SCOPE int TkUtfToUniChar2(const char *src, int *chPtr); + MODULE_SCOPE int TkUtfToUniChar(const char *, int *); + MODULE_SCOPE int TkUniCharToUtf(int, char *); #endif /* diff --git a/generic/tkText.c b/generic/tkText.c index dacadbe..8ae17a5 100644 --- a/generic/tkText.c +++ b/generic/tkText.c @@ -4615,7 +4615,7 @@ TkTextGetTabs( * There may be a more efficient way of getting this. */ - TkUtfToUniChar2(Tcl_GetString(objv[i+1]), &ch); + TkUtfToUniChar(Tcl_GetString(objv[i+1]), &ch); if (!Tcl_UniCharIsAlpha(ch)) { continue; } @@ -5966,7 +5966,7 @@ SearchCore( CLANG_ASSERT(pattern); do { - Tcl_UniChar ch; + int ch; const char *p; int lastFullLine = lastOffset; @@ -6196,7 +6196,7 @@ SearchCore( } } else { firstOffset = p - startOfLine + - Tcl_UtfToUniChar(startOfLine+matchOffset,&ch); + TkUtfToUniChar(startOfLine+matchOffset,&ch); } } } while (searchSpecPtr->all); diff --git a/generic/tkTextDisp.c b/generic/tkTextDisp.c index 026023e..eb917cf 100644 --- a/generic/tkTextDisp.c +++ b/generic/tkTextDisp.c @@ -7582,7 +7582,7 @@ TkTextCharLayoutProc( if (bytesThatFit < maxBytes) { if ((bytesThatFit == 0) && noCharsYet) { int ch; - int chLen = TkUtfToUniChar2(p, &ch); + int chLen = TkUtfToUniChar(p, &ch); #if TK_LAYOUT_WITH_BASE_CHUNKS bytesThatFit = CharChunkMeasureChars(chunkPtr, line, diff --git a/generic/tkTextIndex.c b/generic/tkTextIndex.c index b794cdb..7aebc84 100644 --- a/generic/tkTextIndex.c +++ b/generic/tkTextIndex.c @@ -2300,7 +2300,7 @@ StartEnd( if (segPtr->typePtr == &tkTextCharType) { int ch; - chSize = TkUtfToUniChar2(segPtr->body.chars + offset, &ch); + chSize = TkUtfToUniChar(segPtr->body.chars + offset, &ch); if (!Tcl_UniCharIsWordChar(ch)) { break; } @@ -2345,7 +2345,7 @@ StartEnd( if (segPtr->typePtr == &tkTextCharType) { int ch; - TkUtfToUniChar2(segPtr->body.chars + offset, &ch); + TkUtfToUniChar(segPtr->body.chars + offset, &ch); if (!Tcl_UniCharIsWordChar(ch)) { break; } diff --git a/generic/tkUtil.c b/generic/tkUtil.c index a266cb3..19b343e 100644 --- a/generic/tkUtil.c +++ b/generic/tkUtil.c @@ -1197,7 +1197,7 @@ TkSendVirtualEvent( /* *--------------------------------------------------------------------------- * - * TkUtfToUniChar2 -- + * 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 @@ -1214,7 +1214,7 @@ TkSendVirtualEvent( */ int -TkUtfToUniChar2( +TkUtfToUniChar( const char *src, /* The UTF-8 string. */ int *chPtr) /* Filled with the Tcl_UniChar represented by * the UTF-8 string. */ @@ -1238,6 +1238,39 @@ TkUtfToUniChar2( } 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: diff --git a/generic/ttk/ttkEntry.c b/generic/ttk/ttkEntry.c index d80e1fd..a25574a 100644 --- a/generic/ttk/ttkEntry.c +++ b/generic/ttk/ttkEntry.c @@ -282,11 +282,11 @@ static char *EntryDisplayString(const char *showChar, int numChars) { char *displayString, *p; int size; - Tcl_UniChar ch; - char buf[4]; + int ch; + char buf[6]; - Tcl_UtfToUniChar(showChar, &ch); - size = Tcl_UniCharToUtf(ch, buf); + TkUtfToUniChar(showChar, &ch); + size = TkUniCharToUtf(ch, buf); p = displayString = ckalloc(numChars * size + 1); while (numChars--) { @@ -406,7 +406,7 @@ ExpandPercents( int number, length; const char *string; int stringLength; - Tcl_UniChar ch; + int ch; char numStorage[2*TCL_INTEGER_SPACE]; while (*template) { @@ -430,7 +430,7 @@ ExpandPercents( */ ++template; /* skip over % */ if (*template != '\0') { - template += Tcl_UtfToUniChar(template, &ch); + template += TkUtfToUniChar(template, &ch); } else { ch = '%'; } @@ -480,7 +480,7 @@ ExpandPercents( string = Tk_PathName(entryPtr->core.tkwin); break; default: - length = Tcl_UniCharToUtf(ch, numStorage); + length = TkUniCharToUtf(ch, numStorage); numStorage[length] = '\0'; string = numStorage; break; diff --git a/unix/tkUnixFont.c b/unix/tkUnixFont.c index 681d1d1..ce4eca9 100644 --- a/unix/tkUnixFont.c +++ b/unix/tkUnixFont.c @@ -405,7 +405,7 @@ ControlUtfProc( { const char *srcStart, *srcEnd; char *dstStart, *dstEnd; - Tcl_UniChar ch; + int ch; int result; static char hexChars[] = "0123456789abcdef"; static char mapChars[] = { @@ -426,9 +426,9 @@ ControlUtfProc( result = TCL_CONVERT_NOSPACE; break; } - src += Tcl_UtfToUniChar(src, &ch); + src += TkUtfToUniChar(src, &ch); dst[0] = '\\'; - if ((ch < sizeof(mapChars)) && (mapChars[ch] != 0)) { + if (((size_t) ch < sizeof(mapChars)) && (mapChars[ch] != 0)) { dst[1] = mapChars[ch]; dst += 2; } else if (ch < 256) { @@ -436,13 +436,21 @@ ControlUtfProc( dst[2] = hexChars[(ch >> 4) & 0xf]; dst[3] = hexChars[ch & 0xf]; dst += 4; - } else { + } 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; @@ -1027,7 +1035,7 @@ Tk_MeasureChars( curByte = 0; } else if (maxLength < 0) { const char *p, *end, *next; - Tcl_UniChar ch; + int ch; SubFont *thisSubFontPtr; FontFamily *familyPtr; Tcl_DString runString; @@ -1043,7 +1051,7 @@ Tk_MeasureChars( curX = 0; end = source + numBytes; for (p = source; p < end; ) { - next = p + Tcl_UtfToUniChar(p, &ch); + next = p + TkUtfToUniChar(p, &ch); thisSubFontPtr = FindSubFontForChar(fontPtr, ch, &lastSubFontPtr); if (thisSubFontPtr != lastSubFontPtr) { familyPtr = lastSubFontPtr->familyPtr; diff --git a/unix/tkUnixRFont.c b/unix/tkUnixRFont.c index 0ea1ec6..cf4127d 100644 --- a/unix/tkUnixRFont.c +++ b/unix/tkUnixRFont.c @@ -670,7 +670,7 @@ Tk_MeasureChars( while (numBytes > 0) { int unichar; - clen = TkUtfToUniChar2(source, &unichar); + clen = TkUtfToUniChar(source, &unichar); c = (FcChar32) unichar; if (clen <= 0) { diff --git a/win/tkWinFont.c b/win/tkWinFont.c index 30638ca..7c6c0ba 100644 --- a/win/tkWinFont.c +++ b/win/tkWinFont.c @@ -858,7 +858,7 @@ Tk_MeasureChars( start = source; end = start + numBytes; for (p = start; p < end; ) { - next = p + TkUtfToUniChar2(p, &ch); + next = p + TkUtfToUniChar(p, &ch); thisSubFontPtr = FindSubFontForChar(fontPtr, ch, &lastSubFontPtr); if (thisSubFontPtr != lastSubFontPtr) { familyPtr = lastSubFontPtr->familyPtr; @@ -920,7 +920,7 @@ Tk_MeasureChars( familyPtr = lastSubFontPtr->familyPtr; Tcl_DStringInit(&runString); for (p = start; p < end; ) { - next = p + TkUtfToUniChar2(p, &ch); + next = p + TkUtfToUniChar(p, &ch); Tcl_UtfToExternal(NULL, familyPtr->encoding, p, (int) (next - p), 0, NULL, buf, sizeof(buf), NULL, &dstWrote, NULL); @@ -975,7 +975,7 @@ Tk_MeasureChars( p = source; ch = ' '; while (p < end) { - next = p + TkUtfToUniChar2(p, &ch2); + next = p + TkUtfToUniChar(p, &ch2); if ((ch != ' ') && (ch2 == ' ')) { lastWordBreak = p; } @@ -1457,7 +1457,7 @@ MultiFontTextOut( end = source + numBytes; for (p = source; p < end; ) { - next = p + TkUtfToUniChar2(p, &ch); + next = p + TkUtfToUniChar(p, &ch); thisSubFontPtr = FindSubFontForChar(fontPtr, ch, &lastSubFontPtr); if (thisSubFontPtr != lastSubFontPtr) { if (p > source) { diff --git a/win/tkWinKey.c b/win/tkWinKey.c index 2698c4d..7fee101 100644 --- a/win/tkWinKey.c +++ b/win/tkWinKey.c @@ -88,6 +88,8 @@ TkpGetString( * result. */ { XKeyEvent *keyEv = &eventPtr->xkey; + int len; + char buf[6]; Tcl_DStringInit(dsPtr); if (keyEv->send_event == -1) { @@ -95,41 +97,14 @@ TkpGetString( Tcl_ExternalToUtfDString(TkWinGetKeyInputEncoding(), keyEv->trans_chars, keyEv->nbytes, dsPtr); } - } else if (keyEv->send_event == -2) { - /* - * Special case for win2000 multi-lingal IME input. xkey.trans_chars[] - * already contains a UNICODE char. - */ - - int unichar; - char buf[XMaxTransChars]; - int len; - - unichar = keyEv->trans_chars[1] & 0xff; - unichar <<= 8; - unichar |= keyEv->trans_chars[0] & 0xff; - - len = Tcl_UniCharToUtf((Tcl_UniChar) unichar, buf); - - Tcl_DStringAppend(dsPtr, buf, len); } else if (keyEv->send_event == -3) { - char buf[XMaxTransChars]; - int len; - /* - * Special case for WM_UNICHAR. + * Special case for WM_UNICHAR and win2000 multi-lingal IME input */ - len = Tcl_UniCharToUtf(keyEv->keycode, buf); - if ((keyEv->keycode <= 0xffff) || (len == XMaxTransChars)) { - Tcl_DStringAppend(dsPtr, buf, len); - } else { - Tcl_UniCharToUtf(((keyEv->keycode - 0x10000) >> 10) | 0xd800, buf); - Tcl_DStringAppend(dsPtr, buf, 3); - Tcl_UniCharToUtf(((keyEv->keycode - 0x10000) & 0x3ff) | 0xdc00, buf); - Tcl_DStringAppend(dsPtr, buf, 3); - } + len = TkUniCharToUtf(keyEv->keycode, buf); + Tcl_DStringAppend(dsPtr, buf, len); } else { /* * This is an event generated from generic code. It has no nchars or @@ -140,9 +115,6 @@ TkpGetString( if (((keysym != NoSymbol) && (keysym > 0) && (keysym < 256)) || (keysym == XK_Return) || (keysym == XK_Tab)) { - char buf[XMaxTransChars]; - int len; - len = Tcl_UniCharToUtf((Tcl_UniChar) (keysym & 255), buf); Tcl_DStringAppend(dsPtr, buf, len); } diff --git a/win/tkWinX.c b/win/tkWinX.c index 6be54e2..ce73aac 100644 --- a/win/tkWinX.c +++ b/win/tkWinX.c @@ -1580,8 +1580,8 @@ HandleIMEComposition( /* * Set up the fields pertinent to key event. * - * We set send_event to the special value of -2, so that TkpGetString - * in tkWinKey.c knows that trans_chars[] already contains a UNICODE + * 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 @@ -1592,7 +1592,7 @@ HandleIMEComposition( memset(&event, 0, sizeof(XEvent)); event.xkey.serial = winPtr->display->request++; - event.xkey.send_event = -2; + event.xkey.send_event = -3; event.xkey.display = winPtr->display; event.xkey.window = winPtr->window; event.xkey.root = RootWindow(winPtr->display, winPtr->screenNum); @@ -1600,8 +1600,7 @@ HandleIMEComposition( event.xkey.state = TkWinGetModifierState(); event.xkey.time = TkpGetMS(); event.xkey.same_screen = True; - event.xkey.keycode = 0; - event.xkey.nbytes = 2; + event.xkey.nbytes = 0; for (i=0; i