diff options
-rw-r--r-- | doc/text.n | 8 | ||||
-rw-r--r-- | generic/tkEntry.c | 16 | ||||
-rw-r--r-- | generic/tkFont.c | 36 | ||||
-rw-r--r-- | generic/tkFrame.c | 1 | ||||
-rw-r--r-- | generic/tkInt.h | 10 | ||||
-rw-r--r-- | generic/tkText.c | 8 | ||||
-rw-r--r-- | generic/tkTextDisp.c | 22 | ||||
-rw-r--r-- | generic/tkTextIndex.c | 8 | ||||
-rw-r--r-- | generic/tkTextTag.c | 2 | ||||
-rw-r--r-- | generic/tkUtil.c | 80 | ||||
-rw-r--r-- | generic/tkWindow.c | 2 | ||||
-rw-r--r-- | generic/ttk/ttkButton.c | 13 | ||||
-rw-r--r-- | generic/ttk/ttkEntry.c | 14 | ||||
-rw-r--r-- | generic/ttk/ttkImage.c | 34 | ||||
-rw-r--r-- | generic/ttk/ttkTheme.h | 2 | ||||
-rw-r--r-- | library/ttk/vistaTheme.tcl | 2 | ||||
-rw-r--r-- | macosx/tkMacOSXFont.c | 4 | ||||
-rw-r--r-- | macosx/tkMacOSXSubwindows.c | 2 | ||||
-rw-r--r-- | macosx/tkMacOSXXStubs.c | 2 | ||||
-rw-r--r-- | tests/filebox.test | 2 | ||||
-rw-r--r-- | tests/font.test | 12 | ||||
-rw-r--r-- | tests/text.test | 2 | ||||
-rw-r--r-- | tests/textDisp.test | 76 | ||||
-rw-r--r-- | tests/ttk/spinbox.test | 21 | ||||
-rw-r--r-- | unix/tkUnixFont.c | 22 | ||||
-rw-r--r-- | unix/tkUnixRFont.c | 10 | ||||
-rw-r--r-- | win/Makefile.in | 3 | ||||
-rw-r--r-- | win/rules.vc | 7 | ||||
-rw-r--r-- | win/tkWinFont.c | 19 | ||||
-rw-r--r-- | win/tkWinKey.c | 38 | ||||
-rw-r--r-- | win/tkWinX.c | 45 |
31 files changed, 355 insertions, 168 deletions
@@ -609,9 +609,11 @@ specified by the \fB\-foreground\fR tag option is used. \fB\-wrap \fImode\fR . \fIMode\fR specifies how to handle lines that are wider than the text's -window. It has the same legal values as the \fB\-wrap\fR option for the text -widget: \fBnone\fR, \fBchar\fR, or \fBword\fR. If this tag option is -specified, it overrides the \fB\-wrap\fR option for the text widget. +window. This option only applies to a display line if it applies to the +first non-elided character on that display line. It has the same legal +values as the \fB\-wrap\fR option for the text widget: \fBnone\fR, +\fBchar\fR, or \fBword\fR. If this tag option is specified, it +overrides the \fB\-wrap\fR option for the text widget. .PP If a character has several tags associated with it, and if their display options conflict, then the options of the highest priority tag are used. If a diff --git a/generic/tkEntry.c b/generic/tkEntry.c index c0ce47b..9e25bed 100644 --- a/generic/tkEntry.c +++ b/generic/tkEntry.c @@ -1924,8 +1924,8 @@ EntryComputeGeometry( */ if (entryPtr->showChar != NULL) { - Tcl_UniChar ch; - char buf[TCL_UTF_MAX]; + int ch; + char buf[6]; int size; /* @@ -1935,8 +1935,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); @@ -3412,7 +3412,7 @@ ExpandPercents( * list element. */ int number, length; register const char *string; - Tcl_UniChar ch; + int ch; char numStorage[2*TCL_INTEGER_SPACE]; while (1) { @@ -3445,7 +3445,7 @@ ExpandPercents( before++; /* skip over % */ if (*before != '\0') { - before += Tcl_UtfToUniChar(before, &ch); + before += TkUtfToUniChar(before, &ch); } else { ch = '%'; } @@ -3465,7 +3465,7 @@ ExpandPercents( string = Tk_PathName(entryPtr->tkwin); break; default: - length = Tcl_UniCharToUtf(ch, numStorage); + length = TkUniCharToUtf(ch, numStorage); numStorage[length] = '\0'; string = numStorage; break; @@ -3525,7 +3525,7 @@ ExpandPercents( string = Tk_PathName(entryPtr->tkwin); break; default: - length = Tcl_UniCharToUtf(ch, numStorage); + length = TkUniCharToUtf(ch, numStorage); numStorage[length] = '\0'; string = numStorage; break; diff --git a/generic/tkFont.c b/generic/tkFont.c index 102fc6e..bec8807 100644 --- a/generic/tkFont.c +++ b/generic/tkFont.c @@ -497,7 +497,7 @@ Tk_FontObjCmd( const char *s; Tk_Font tkfont; Tcl_Obj *optPtr, *charPtr, *resultPtr; - Tcl_UniChar uniChar = 0; + int uniChar = 0; const TkFontAttributes *faPtr; TkFontAttributes fa; @@ -562,17 +562,19 @@ Tk_FontObjCmd( */ if (charPtr != NULL) { - if (Tcl_GetCharLength(charPtr) != 1) { + 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, Tcl_GetString(charPtr), + 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; } - uniChar = Tcl_GetUniChar(charPtr, 0); } /* @@ -1694,7 +1696,7 @@ Tk_PostscriptFontName( } else if (strcasecmp(family, "ZapfDingbats") == 0) { family = "ZapfDingbats"; } else { - Tcl_UniChar ch; + int ch; /* * Inline, capitalize the first letter of each word, lowercase the @@ -1712,14 +1714,18 @@ Tk_PostscriptFontName( src++; upper = 1; } - src += Tcl_UtfToUniChar(src, &ch); - if (upper) { - ch = Tcl_UniCharToUpper(ch); - upper = 0; + src += TkUtfToUniChar(src, &ch); + if (ch <= 0xffff) { + if (upper) { + ch = Tcl_UniCharToUpper(ch); + upper = 0; + } else { + ch = Tcl_UniCharToLower(ch); + } } else { - ch = Tcl_UniCharToLower(ch); + upper = 0; } - dest += Tcl_UniCharToUtf(ch, dest); + dest += TkUniCharToUtf(ch, dest); } *dest = '\0'; Tcl_DStringSetLength(dsPtr, dest - Tcl_DStringValue(dsPtr)); @@ -3249,7 +3255,7 @@ Tk_TextLayoutToPostscript( int i, j, len; const char *p, *glyphname; char uindex[5], c, *ps; - Tcl_UniChar ch; + int ch; Tcl_AppendToObj(psObj, "[(", -1); for (i = 0; i < layoutPtr->numChunks; i++, chunkPtr++) { @@ -3272,7 +3278,7 @@ Tk_TextLayoutToPostscript( * international postscript fonts. */ - p += Tcl_UtfToUniChar(p, &ch); + p += TkUtfToUniChar(p, &ch); if ((ch == '(') || (ch == ')') || (ch == '\\') || (ch < 0x20)) { /* * Tricky point: the "03" is necessary in the sprintf below, @@ -3298,6 +3304,9 @@ Tk_TextLayoutToPostscript( * 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) { @@ -3318,6 +3327,7 @@ Tk_TextLayoutToPostscript( * 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 " diff --git a/generic/tkFrame.c b/generic/tkFrame.c index f6edfb0..0f1a1b3 100644 --- a/generic/tkFrame.c +++ b/generic/tkFrame.c @@ -458,7 +458,6 @@ TkListCreateFrame( * window associated with the interpreter. * Gives the base name to use for the new * application. */ - { int objc; Tcl_Obj **objv; diff --git a/generic/tkInt.h b/generic/tkInt.h index dd5dcad..1615a81 100644 --- a/generic/tkInt.h +++ b/generic/tkInt.h @@ -1196,7 +1196,7 @@ MODULE_SCOPE void TkUnderlineCharsInContext(Display *display, const char *string, int numBytes, int x, int y, int firstByte, int lastByte); MODULE_SCOPE void TkpGetFontAttrsForChar(Tk_Window tkwin, Tk_Font tkfont, - Tcl_UniChar c, struct TkFontAttributes *faPtr); + 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); @@ -1232,6 +1232,14 @@ MODULE_SCOPE Status TkParseColor (Display * display, 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. */ diff --git a/generic/tkText.c b/generic/tkText.c index 0e41ac8..412a7f2 100644 --- a/generic/tkText.c +++ b/generic/tkText.c @@ -4459,7 +4459,7 @@ TkTextGetTabs( Tcl_Obj **objv; TkTextTabArray *tabArrayPtr; TkTextTab *tabPtr; - Tcl_UniChar ch; + int ch; double prevStop, lastStop; /* * Map these strings to TkTextTabAlign values. @@ -4566,7 +4566,7 @@ TkTextGetTabs( * There may be a more efficient way of getting this. */ - Tcl_UtfToUniChar(Tcl_GetString(objv[i+1]), &ch); + TkUtfToUniChar(Tcl_GetString(objv[i+1]), &ch); if (!Tcl_UniCharIsAlpha(ch)) { continue; } @@ -5880,7 +5880,7 @@ SearchCore( CLANG_ASSERT(pattern); do { - Tcl_UniChar ch; + int ch; const char *p; int lastFullLine = lastOffset; @@ -6110,7 +6110,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 a135084..2171cd0 100644 --- a/generic/tkTextDisp.c +++ b/generic/tkTextDisp.c @@ -7542,6 +7542,9 @@ TkTextCharLayoutProc( * (b) at least one pixel of the character is visible, we have not * already exceeded the character limit, and the next character is a * white space character. + * In the specific case of 'word' wrapping mode however, include all space + * characters following the characters that fit in the space we've got, + * even if no pixel of them is visible. */ p = segPtr->body.chars + byteOffset; @@ -7581,8 +7584,8 @@ TkTextCharLayoutProc( if (bytesThatFit < maxBytes) { if ((bytesThatFit == 0) && noCharsYet) { - Tcl_UniChar ch; - int chLen = Tcl_UtfToUniChar(p, &ch); + int ch; + int chLen = TkUtfToUniChar(p, &ch); #if TK_LAYOUT_WITH_BASE_CHUNKS bytesThatFit = CharChunkMeasureChars(chunkPtr, line, @@ -7604,6 +7607,21 @@ TkTextCharLayoutProc( nextX = maxX; bytesThatFit++; } + if (wrapMode == TEXT_WRAPMODE_WORD) { + while (p[bytesThatFit] == ' ') { + /* + * Space characters that would go at the beginning of the + * next line are allocated to the current line. This gives + * the effect of trimming white spaces that would otherwise + * be seen at the beginning of wrapped lines. + * Note that testing for '\t' is useless here because the + * chunk always includes at most one trailing \t, see + * LayoutDLine. + */ + + bytesThatFit++; + } + } if (p[bytesThatFit] == '\n') { /* * A newline character takes up no space, so if the previous diff --git a/generic/tkTextIndex.c b/generic/tkTextIndex.c index 8820191..d227bd8 100644 --- a/generic/tkTextIndex.c +++ b/generic/tkTextIndex.c @@ -2298,9 +2298,9 @@ StartEnd( int chSize = 1; if (segPtr->typePtr == &tkTextCharType) { - Tcl_UniChar ch; + int ch; - chSize = Tcl_UtfToUniChar(segPtr->body.chars + offset, &ch); + chSize = TkUtfToUniChar(segPtr->body.chars + offset, &ch); if (!Tcl_UniCharIsWordChar(ch)) { break; } @@ -2343,9 +2343,9 @@ StartEnd( int chSize = 1; if (segPtr->typePtr == &tkTextCharType) { - Tcl_UniChar ch; - Tcl_UtfToUniChar(segPtr->body.chars + offset, &ch); + int ch; + TkUtfToUniChar(segPtr->body.chars + offset, &ch); if (!Tcl_UniCharIsWordChar(ch)) { break; } diff --git a/generic/tkTextTag.c b/generic/tkTextTag.c index a212615..dd3127d 100644 --- a/generic/tkTextTag.c +++ b/generic/tkTextTag.c @@ -30,7 +30,7 @@ static const char *const wrapStrings[] = { /* * The 'TkTextTabStyle' enum in tkText.h is used to define a type for the * -tabstyle option of the Text widget. These values are used as indices into - * the string table below. Tags are allowed an empty wrap value, but the + * the string table below. Tags are allowed an empty tabstyle value, but the * widget as a whole is not. */ diff --git a/generic/tkUtil.c b/generic/tkUtil.c index 6563165..e686826 100644 --- a/generic/tkUtil.c +++ b/generic/tkUtil.c @@ -1192,6 +1192,86 @@ TkSendVirtualEvent( 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 surrogate pair to a + * single unicode character. So, up to 6 bytes might be consumed. + * + * 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 if Tcl is compiled with TCL_UTF_MAX=4, + * or when a high surrogate character is detected in UTF-8 form */ + 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. So, up to 6 bytes might be produced. + * + * 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) && (ch <= 0x10ffff) && (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 diff --git a/generic/tkWindow.c b/generic/tkWindow.c index 0c60321..5855b7c 100644 --- a/generic/tkWindow.c +++ b/generic/tkWindow.c @@ -3101,7 +3101,7 @@ Initialize( Tcl_ListObjAppendElement(NULL, cmd, Tcl_NewStringObj("::safe::TkInit", -1)); Tcl_ListObjAppendElement(NULL, cmd, Tcl_GetObjResult(master)); - + /* * Step 2 : Eval in the master. The argument is the *reversed* interp * path of the slave. diff --git a/generic/ttk/ttkButton.c b/generic/ttk/ttkButton.c index bc44f25..c00754b 100644 --- a/generic/ttk/ttkButton.c +++ b/generic/ttk/ttkButton.c @@ -136,6 +136,15 @@ BaseCleanup(void *recordPtr) TtkFreeImageSpec(basePtr->base.imageSpec); } +static void +BaseImageChanged( + ClientData clientData, int x, int y, int width, int height, + int imageWidth, int imageHeight) +{ + Base *basePtr = (Base *)clientData; + TtkResizeWidget(&basePtr->core); +} + static int BaseConfigure(Tcl_Interp *interp, void *recordPtr, int mask) { Base *basePtr = recordPtr; @@ -149,8 +158,8 @@ static int BaseConfigure(Tcl_Interp *interp, void *recordPtr, int mask) } if (basePtr->base.imageObj) { - imageSpec = TtkGetImageSpec( - interp, basePtr->core.tkwin, basePtr->base.imageObj); + imageSpec = TtkGetImageSpecEx( + interp, basePtr->core.tkwin, basePtr->base.imageObj, BaseImageChanged, basePtr); if (!imageSpec) { goto error; } diff --git a/generic/ttk/ttkEntry.c b/generic/ttk/ttkEntry.c index 533637d..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[TCL_UTF_MAX]; + 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/generic/ttk/ttkImage.c b/generic/ttk/ttkImage.c index a5a3a52..e403e2d 100644 --- a/generic/ttk/ttkImage.c +++ b/generic/ttk/ttkImage.c @@ -25,6 +25,8 @@ struct TtkImageSpec { int mapCount; /* #state-specific overrides */ Ttk_StateSpec *states; /* array[mapCount] of states ... */ Tk_Image *images; /* ... per-state images to use */ + Tk_ImageChangedProc *imageChanged; + ClientData imageChangedClientData; }; /* NullImageChanged -- @@ -34,15 +36,41 @@ static void NullImageChanged(ClientData clientData, int x, int y, int width, int height, int imageWidth, int imageHeight) { /* No-op */ } +/* ImageSpecImageChanged -- + * Image changes should trigger a repaint. + */ +static void ImageSpecImageChanged(ClientData clientData, + int x, int y, int width, int height, int imageWidth, int imageHeight) +{ + Ttk_ImageSpec *imageSpec = (Ttk_ImageSpec *)clientData; + if (imageSpec->imageChanged != NULL) { + imageSpec->imageChanged(imageSpec->imageChangedClientData, + x, y, width, height, + imageWidth, imageHeight); + } +} + /* TtkGetImageSpec -- * Constructs a Ttk_ImageSpec * from a Tcl_Obj *. * Result must be released using TtkFreeImageSpec. * - * TODO: Need a variant of this that takes a user-specified ImageChanged proc */ Ttk_ImageSpec * TtkGetImageSpec(Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr) { + return TtkGetImageSpecEx(interp, tkwin, objPtr, NULL, NULL); +} + +/* TtkGetImageSpecEx -- + * Constructs a Ttk_ImageSpec * from a Tcl_Obj *. + * Result must be released using TtkFreeImageSpec. + * imageChangedProc will be called when not NULL when + * the image changes to allow widgets to repaint. + */ +Ttk_ImageSpec * +TtkGetImageSpecEx(Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr, + Tk_ImageChangedProc *imageChangedProc, ClientData imageChangedClientData) +{ Ttk_ImageSpec *imageSpec = 0; int i = 0, n = 0, objc; Tcl_Obj **objv; @@ -52,6 +80,8 @@ TtkGetImageSpec(Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr) imageSpec->mapCount = 0; imageSpec->states = 0; imageSpec->images = 0; + imageSpec->imageChanged = imageChangedProc; + imageSpec->imageChangedClientData = imageChangedClientData; if (Tcl_ListObjGetElements(interp, objPtr, &objc, &objv) != TCL_OK) { goto error; @@ -74,7 +104,7 @@ TtkGetImageSpec(Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr) /* Get base image: */ imageSpec->baseImage = Tk_GetImage( - interp, tkwin, Tcl_GetString(objv[0]), NullImageChanged, NULL); + interp, tkwin, Tcl_GetString(objv[0]), ImageSpecImageChanged, imageSpec); if (!imageSpec->baseImage) { goto error; } diff --git a/generic/ttk/ttkTheme.h b/generic/ttk/ttkTheme.h index 7bf2a7f..9251dea 100644 --- a/generic/ttk/ttkTheme.h +++ b/generic/ttk/ttkTheme.h @@ -372,6 +372,8 @@ MODULE_SCOPE void Ttk_RegisterNamedColor(Ttk_ResourceCache, const char *, XColor typedef struct TtkImageSpec Ttk_ImageSpec; TTKAPI Ttk_ImageSpec *TtkGetImageSpec(Tcl_Interp *, Tk_Window, Tcl_Obj *); +TTKAPI Ttk_ImageSpec *TtkGetImageSpecEx(Tcl_Interp *, Tk_Window, Tcl_Obj *, + Tk_ImageChangedProc *, ClientData); TTKAPI void TtkFreeImageSpec(Ttk_ImageSpec *); TTKAPI Tk_Image TtkSelectImage(Ttk_ImageSpec *, Ttk_State); diff --git a/library/ttk/vistaTheme.tcl b/library/ttk/vistaTheme.tcl index 99410cb..3f75f51 100644 --- a/library/ttk/vistaTheme.tcl +++ b/library/ttk/vistaTheme.tcl @@ -133,7 +133,7 @@ namespace eval ttk::theme::vista { Spinbox.background -sticky news -children { Spinbox.padding -sticky news -children { Spinbox.innerbg -sticky news -children { - Spinbox.textarea -expand 1 -sticky {} + Spinbox.textarea -expand 1 } } Spinbox.uparrow -side top -sticky ens diff --git a/macosx/tkMacOSXFont.c b/macosx/tkMacOSXFont.c index c48e56e..d3e0e41 100644 --- a/macosx/tkMacOSXFont.c +++ b/macosx/tkMacOSXFont.c @@ -672,14 +672,14 @@ void TkpGetFontAttrsForChar( Tk_Window tkwin, /* Window on the font's display */ Tk_Font tkfont, /* Font to query */ - Tcl_UniChar c, /* Character of interest */ + 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 = c; + UTF16Char ch = (UTF16Char) c; nsFont = [nsFont bestMatchingFontForCharacters:&ch length:1 attributes:nil actualCoveredLength:NULL]; diff --git a/macosx/tkMacOSXSubwindows.c b/macosx/tkMacOSXSubwindows.c index 9851474..f92d260 100644 --- a/macosx/tkMacOSXSubwindows.c +++ b/macosx/tkMacOSXSubwindows.c @@ -365,7 +365,7 @@ XMoveResizeWindow( CGFloat Y = (CGFloat)y; CGFloat Width = (CGFloat)width; CGFloat Height = (CGFloat)height; - CGFloat XOff = (CGFloat)macWin->winPtr->wmInfoPtr->xInParent; + CGFloat XOff = (CGFloat)macWin->winPtr->wmInfoPtr->xInParent; CGFloat YOff = (CGFloat)macWin->winPtr->wmInfoPtr->yInParent; NSRect r = NSMakeRect(X + XOff, tkMacOSXZeroScreenHeight - Y - YOff - Height, diff --git a/macosx/tkMacOSXXStubs.c b/macosx/tkMacOSXXStubs.c index a2d175b..1ed526d 100644 --- a/macosx/tkMacOSXXStubs.c +++ b/macosx/tkMacOSXXStubs.c @@ -897,7 +897,7 @@ XGetImage( * We do not support any other values here. */ int scalefactor = 1; - if (win && [win respondsToSelector:@selector(backingScaleFactor)]) { + if (win && [win respondsToSelector:@selector(backingScaleFactor)]) { scalefactor = ([win backingScaleFactor] == 2.0) ? 2 : 1; } int scaled_height = height * scalefactor; diff --git a/tests/filebox.test b/tests/filebox.test index 7b9fa2c..2573825 100644 --- a/tests/filebox.test +++ b/tests/filebox.test @@ -463,7 +463,7 @@ foreach mode $modes { } # The rest of the tests need to be executed on Unix only. - # The test whether the dialog box widgets were implemented correctly. + # They test whether the dialog box widgets were implemented correctly. # These tests are not # needed on the other platforms because they use native file dialogs. } diff --git a/tests/font.test b/tests/font.test index 9e44a93..23e09c4 100644 --- a/tests/font.test +++ b/tests/font.test @@ -145,6 +145,18 @@ test font-4.10 {font command: actual} -constraints win -body { test font-4.11 {font command: bad option} -body { font actual xyz -style } -returnCodes error -result {bad option "-style": must be -family, -size, -weight, -slant, -underline, or -overstrike} +test font-4.12 {font command: actual} -body { + font actual {-family times} -- \ud800 +} -match glob -result {*} +test font-4.13 {font command: actual} -body { + font actual {-family times} -- \udc00 +} -match glob -result {*} +test font-4.14 {font command: actual} -constraints win -body { + font actual {-family times} -family -- \ud800\udc00 +} -result {Times New Roman} +test font-4.15 {font command: actual} -body { + font actual {-family times} -- \udc00\ud800 +} -returnCodes 1 -match glob -result {expected a single character but got "*"} test font-5.1 {font command: configure} -body { diff --git a/tests/text.test b/tests/text.test index f640817..3e5b4b6 100644 --- a/tests/text.test +++ b/tests/text.test @@ -3828,7 +3828,7 @@ test text-19.16 {DeleteChars procedure, updates affecting topIndex} -setup { wm geometry .top +0+0 update } -body { - .top.t insert end "abc def\n01 2345 678 9101112\nLine 3\nLine 4\nLine 5\n6\n7\n8\n" + .top.t insert end "abc def\n01 2a345 678 9101112\nLine 3\nLine 4\nLine 5\n6\n7\n8\n" .top.t yview 2.4 .top.t delete 2.5 set x [.top.t index @0,0] diff --git a/tests/textDisp.test b/tests/textDisp.test index 99401c2..d3de2d8 100644 --- a/tests/textDisp.test +++ b/tests/textDisp.test @@ -253,8 +253,8 @@ test textDisp-2.5 {LayoutDLine, word wrap} {textfonts} { .t configure -wrap word .t delete 1.0 end .t insert 1.0 "This isx some sample text for testing." - list [.t bbox 1.13] [.t bbox 1.14] [.t bbox 1.19] -} [list [list 96 5 49 $fixedHeight] [list 5 [expr {$fixedDiff + 18}] 7 $fixedHeight] [list 40 [expr {$fixedDiff + 18}] 7 $fixedHeight]] + list [.t bbox 1.13] [.t bbox 1.19] [.t bbox 1.20] [.t bbox 1.21] +} [list [list 96 5 $fixedWidth $fixedHeight] [list 138 5 $fixedWidth $fixedHeight] [list 145 5 0 $fixedHeight] [list 5 [expr {$fixedDiff + 18}] $fixedWidth $fixedHeight]] test textDisp-2.6 {LayoutDLine, word wrap} { .t configure -wrap word .t delete 1.0 end @@ -353,16 +353,16 @@ test textDisp-2.16 {LayoutDLine, justification} {textfonts} { .t tag configure x -justify center .t tag add x 1.1 1.20 .t tag add x 1.21 1.end - list [.t bbox 1.0] [.t bbox 1.20] [.t bbox 1.36] [.t bbox 2.0] -} [list [list 5 5 7 $fixedHeight] [list 5 [expr {$fixedDiff + 18}] 7 $fixedHeight] [list 43 [expr {2*$fixedDiff + 31}] 7 $fixedHeight] [list 5 [expr {3*$fixedDiff + 44}] 7 $fixedHeight]] + list [.t bbox 1.0] [.t bbox 1.20] [.t bbox 1.41] [.t bbox 2.0] +} [list [list 5 5 7 $fixedHeight] [list 5 [expr {$fixedDiff + 18}] 7 $fixedHeight] [list 61 [expr {2*$fixedDiff + 31}] 7 $fixedHeight] [list 5 [expr {3*$fixedDiff + 44}] 7 $fixedHeight]] test textDisp-2.17 {LayoutDLine, justification} {textfonts} { .t configure -wrap word .t delete 1.0 end - .t insert 1.0 "Lots of long words, enough to force word wrap\nThen\nmore lines" + .t insert 1.0 "Lots of very long words, enough to force word wrap\nThen\nmore lines" .t tag configure x -justify center - .t tag add x 1.20 - list [.t bbox 1.0] [.t bbox 1.20] [.t bbox 1.36] [.t bbox 2.0] -} [list [list 5 5 7 $fixedHeight] [list 19 [expr {$fixedDiff + 18}] 7 $fixedHeight] [list 5 [expr {2*$fixedDiff + 31}] 7 $fixedHeight] [list 5 [expr {3*$fixedDiff + 44}] 7 $fixedHeight]] + .t tag add x 1.18 + list [.t bbox 1.0] [.t bbox 1.18] [.t bbox 1.35] [.t bbox 2.0] +} [list [list 5 5 7 $fixedHeight] [list 15 [expr {$fixedDiff + 18}] 7 $fixedHeight] [list 5 [expr {2*$fixedDiff + 31}] 7 $fixedHeight] [list 5 [expr {3*$fixedDiff + 44}] 7 $fixedHeight]] test textDisp-2.18 {LayoutDLine, justification} {textfonts} { .t configure -wrap none .t delete 1.0 end @@ -2337,7 +2337,7 @@ test textDisp-17.10 {TkTextScanCmd procedure, word wrapping} {textfonts} { set x [.t index @0,0] .t scan dragto 0 [expr {70 + $fixedDiff}] list $x [.t index @0,0] -} {9.15 8.31} +} {9.0 8.0} .t configure -xscrollcommand scroll -yscrollcommand {} test textDisp-18.1 {GetXView procedure} { .t configure -wrap none @@ -2563,7 +2563,7 @@ test textDisp-19.10.1 {Widget manipulation causes height miscount} { .t insert end "\nLine $i" } .t insert end "\nThis last line wraps around four " - .t insert end "times with a bit left on the last line." + .t insert end "times with a little bit left on the last line." .t yview insert update .t count -update -ypixels 1.0 end @@ -2577,7 +2577,7 @@ test textDisp-19.11 {GetYView procedure} { .t insert end "\nLine $i" } .t insert end "\nThis last line wraps around four " - .t insert end "times with a bit left on the last line." + .t insert end "times with a little bit left on the last line." .t yview insert update .t count -update -ypixels 1.0 end @@ -2599,7 +2599,7 @@ test textDisp-19.11.5.1 {TextWidgetCmd procedure, "count -displaylines"} { .t count -displaylines 16.0 16.5 } {0} test textDisp-19.11.6 {TextWidgetCmd procedure, "count -displaylines"} { - .t count -displaylines 16.0 16.20 + .t count -displaylines 16.0 16.24 } {1} test textDisp-19.11.7 {TextWidgetCmd procedure, "count -displaylines"} { .t count -displaylines 16.0 16.40 @@ -2652,14 +2652,14 @@ test textDisp-19.11.17 {TextWidgetCmd procedure, "index +displaylines"} { [.t index "12.0 +2d lines"] [.t index "11.0 +2d lines"] \ [.t index "13.0 +2d lines"] [.t index "13.1 +3d lines"] \ [.t index "13.0 +4d lines"] -} {15.5 16.0 15.0 16.0 16.15 16.33} +} {15.5 16.0 15.0 16.0 16.21 16.39} test textDisp-19.11.18 {TextWidgetCmd procedure, "index +displaylines"} { .t tag remove elide 1.0 end .t tag add elide "12.0" "14.0" list [.t index "15.5 -2d lines"] \ [.t index "16.0 -2d lines"] [.t index "15.0 -2d lines"] \ - [.t index "16.0 -3d lines"] [.t index "16.17 -4d lines"] \ - [.t index "16.36 -5d lines"] + [.t index "16.0 -3d lines"] [.t index "16.23 -4d lines"] \ + [.t index "16.42 -5d lines"] } {11.5 14.0 11.0 11.0 11.2 11.3} test textDisp-19.11.19 {TextWidgetCmd procedure, "count -displaylines"} { .t tag remove elide 1.0 end @@ -2673,14 +2673,14 @@ test textDisp-19.11.20 {TextWidgetCmd procedure, "index +displaylines"} { [.t index "12.0 +2d lines"] [.t index "11.0 +2d lines"] \ [.t index "13.0 +2d lines"] [.t index "13.0 +3d lines"] \ [.t index "13.0 +4d lines"] -} {16.38 16.50 16.33 16.50 16.67 17.0} +} {16.44 16.57 16.39 16.57 16.74 17.0} test textDisp-19.11.21 {TextWidgetCmd procedure, "index +displaylines"} { .t tag remove elide 1.0 end .t tag add elide "12.0" "16.0 +1displaylines" - list [.t index "16.38 -2d lines"] \ - [.t index "16.50 -3d lines"] [.t index "16.33 -2d lines"] \ - [.t index "16.53 -4d lines"] [.t index "16.69 -4d lines"] \ - [.t index "17.1 -5d lines"] + list [.t index "16.44 -2d lines"] \ + [.t index "16.57 -3d lines"] [.t index "16.39 -2d lines"] \ + [.t index "16.60 -4d lines"] [.t index "16.76 -4d lines"] \ + [.t index "17.0 -5d lines"] } {11.5 11.0 11.0 10.3 11.2 11.0} test textDisp-19.11.22 {TextWidgetCmd procedure, "index +displaylines"} { .t tag remove elide 1.0 end @@ -2688,7 +2688,7 @@ test textDisp-19.11.22 {TextWidgetCmd procedure, "index +displaylines"} { [.t index "end -3d lines"] [.t index "1.0 -2d lines"] \ [.t index "1.0 +4d lines"] [.t index "1.0 +50d lines"] \ [.t index "end -50d lines"] -} {17.0 16.33 1.0 5.0 17.0 1.0} +} {17.0 16.39 1.0 5.0 17.0 1.0} test textDisp-19.11.23 {TextWidgetCmd procedure, "index +displaylines"} { .t tag remove elide 1.0 end .t tag add elide "12.3" "16.0 +1displaylines" @@ -2697,7 +2697,7 @@ test textDisp-19.11.23 {TextWidgetCmd procedure, "index +displaylines"} { [.t index "12.0 +2d lines"] [.t index "11.0 +2d lines"] \ [.t index "13.0 +2d lines"] [.t index "13.0 +3d lines"] \ [.t index "13.0 +4d lines"] -} {16.17 16.33 16.28 16.46 16.28 16.49 16.65 16.72} +} {16.23 16.44 16.39 16.57 16.39 16.60 16.77 16.79} .t tag remove elide 1.0 end test textDisp-19.11.24 {TextWidgetCmd procedure, "index +/-displaylines"} { list [.t index "11.5 + -1 display lines"] \ @@ -2746,7 +2746,7 @@ test textDisp-19.14 {GetYView procedure} { .t insert end "\nLine $i" } .t insert end "\nThis last line wraps around four " - .t insert end "times with a bit left on the last line." + .t insert end "times with a little bit left on the last line." # Need to update so everything is calculated. update ; .t count -update -ypixels 1.0 end update ; after 10 ; update @@ -2766,7 +2766,7 @@ test textDisp-19.15 {GetYView procedure} { .t insert end "\nLine $i" } .t insert end "\nThis last line wraps around four " - .t insert end "times with a bit left on the last line." + .t insert end "times with a bit little left on the last line." update .t configure -yscrollcommand scrollError proc bgerror args { @@ -2794,7 +2794,7 @@ test textDisp-19.16 {count -ypixels} { .t insert end "\nLine $i" } .t insert end "\nThis last line wraps around four " - .t insert end "times with a bit left on the last line." + .t insert end "times with a little bit left on the last line." # Need to update so everything is calculated. update ; .t count -update -ypixels 1.0 end ; update set res {} @@ -2879,18 +2879,18 @@ test textDisp-20.1 {FindDLine} {textfonts} { test textDisp-20.2 {FindDLine} {textfonts} { .t yview 100.0 .t yview -pickplace 53.0 - list [.t dlineinfo 50.0] [.t dlineinfo 50.14] [.t dlineinfo 50.15] -} [list [list 3 [expr {-1 - $fixedDiff/2}] 105 [expr {$fixedDiff + 13}] [expr {$fixedDiff + 10}]] [list 3 [expr {-1 - $fixedDiff/2}] 105 [expr {$fixedDiff + 13}] [expr {$fixedDiff + 10}]] [list 3 [expr {12 + $fixedDiff/2}] 140 [expr {$fixedDiff + 13}] [expr {$fixedDiff + 10}]]] + list [.t dlineinfo 50.0] [.t dlineinfo 50.14] [.t dlineinfo 50.21] +} [list [list 3 [expr {-1 - $fixedDiff/2}] 140 [expr {$fixedDiff + 13}] [expr {$fixedDiff + 10}]] [list 3 [expr {-1 - $fixedDiff/2}] 140 [expr {$fixedDiff + 13}] [expr {$fixedDiff + 10}]] [list 3 [expr {12 + $fixedDiff/2}] 133 [expr {$fixedDiff + 13}] [expr {$fixedDiff + 10}]]] test textDisp-20.3 {FindDLine} {textfonts} { .t yview 100.0 .t yview 49.0 - list [.t dlineinfo 50.0] [.t dlineinfo 50.20] [.t dlineinfo 57.0] -} [list [list 3 [expr {$fixedDiff + 16}] 105 [expr {$fixedDiff + 13}] [expr {$fixedDiff + 10}]] [list 3 [expr {2*$fixedDiff + 29}] 140 [expr {$fixedDiff + 13}] [expr {$fixedDiff + 10}]] {}] + list [.t dlineinfo 50.0] [.t dlineinfo 50.24] [.t dlineinfo 57.0] +} [list [list 3 [expr {$fixedDiff + 16}] 140 [expr {$fixedDiff + 13}] [expr {$fixedDiff + 10}]] [list 3 [expr {2*$fixedDiff + 29}] 133 [expr {$fixedDiff + 13}] [expr {$fixedDiff + 10}]] {}] test textDisp-20.4 {FindDLine} {textfonts} { .t yview 100.0 .t yview 42.0 - list [.t dlineinfo 50.0] [.t dlineinfo 50.20] [.t dlineinfo 50.40] -} [list [list 3 [expr {8*$fixedDiff + 107}] 105 [expr {$fixedDiff + 13}] [expr {$fixedDiff + 10}]] [list 3 [expr {9*$fixedDiff + 120}] 140 [expr {$fixedDiff + 13}] [expr {$fixedDiff + 10}]] {}] + list [.t dlineinfo 50.0] [.t dlineinfo 50.24] [.t dlineinfo 50.40] +} [list [list 3 [expr {8*$fixedDiff + 107}] 140 [expr {$fixedDiff + 13}] [expr {$fixedDiff + 10}]] [list 3 [expr {9*$fixedDiff + 120}] 133 [expr {$fixedDiff + 13}] [expr {$fixedDiff + 10}]] {}] .t config -wrap none test textDisp-20.5 {FindDLine} {textfonts} { .t yview 100.0 @@ -2903,7 +2903,7 @@ test textDisp-21.1 {TkTextPixelIndex} {textfonts} { .t yview 48.0 list [.t index @-10,-10] [.t index @6,6] [.t index @22,6] \ [.t index @102,6] [.t index @38,[expr {$fixedHeight * 4 + 3}]] [.t index @44,67] -} {48.0 48.0 48.2 48.7 50.40 50.40} +} {48.0 48.0 48.2 48.7 50.45 50.45} .t insert end \n test textDisp-21.2 {TkTextPixelIndex} {textfonts} { .t yview 195.0 @@ -2959,7 +2959,7 @@ test textDisp-22.1 {TkTextCharBbox} {textfonts} { .t yview 48.0 list [.t bbox 47.2] [.t bbox 48.0] [.t bbox 50.5] [.t bbox 50.40] \ [.t bbox 58.0] -} [list {} [list 3 3 7 $fixedHeight] [list 38 [expr {3+2*$fixedHeight}] 7 $fixedHeight] [list 38 [expr {3+4*$fixedHeight}] 7 $fixedHeight] {}] +} [list {} [list 3 3 7 $fixedHeight] [list 38 [expr {3+2*$fixedHeight}] 7 $fixedHeight] [list 3 [expr {3+4*$fixedHeight}] 7 $fixedHeight] {}] test textDisp-22.2 {TkTextCharBbox} {textfonts} { .t config -wrap none .t yview 48.0 @@ -3083,13 +3083,13 @@ test textDisp-23.1 {TkTextDLineInfo} {textfonts} { .t yview 48.0 list [.t dlineinfo 47.3] [.t dlineinfo 48.0] [.t dlineinfo 50.40] \ [.t dlineinfo 56.0] -} [list {} [list 3 3 49 [expr {$fixedDiff + 13}] [expr {$fixedDiff + 10}]] [list 3 [expr {4*$fixedDiff + 55}] 126 [expr {$fixedDiff + 13}] [expr {$fixedDiff + 10}]] {}] +} [list {} [list 3 3 49 [expr {$fixedDiff + 13}] [expr {$fixedDiff + 10}]] [list 3 [expr {4*$fixedDiff + 55}] 91 [expr {$fixedDiff + 13}] [expr {$fixedDiff + 10}]] {}] test textDisp-23.2 {TkTextDLineInfo} {textfonts} { .t config -bd 4 -wrap word update .t yview 48.0 .t dlineinfo 50.40 -} [list 7 [expr {4*$fixedDiff + 59}] 126 [expr {$fixedDiff + 13}] [expr {$fixedDiff + 10}]] +} [list 7 [expr {4*$fixedDiff + 59}] 91 [expr {$fixedDiff + 13}] [expr {$fixedDiff + 10}]] .t config -bd 0 test textDisp-23.3 {TkTextDLineInfo} {textfonts} { .t config -wrap none @@ -3284,11 +3284,11 @@ test textDisp-24.17 {TkTextCharLayoutProc, -wrap word} {textfonts} { test textDisp-24.18 {TkTextCharLayoutProc, -wrap word} {textfonts} { .t configure -wrap word .t delete 1.0 end - .t insert 1.0 "xThis is a line that wraps around" + .t insert 1.0 "xxThis is a line that wraps around" wm geom . {} update - list [.t bbox 1.14] [.t bbox 1.15] [.t bbox 1.16] -} [list [list 101 3 7 $fixedHeight] [list 108 3 35 $fixedHeight] [list 3 [expr {$fixedDiff + 16}] 7 $fixedHeight]] + list [.t bbox 1.15] [.t bbox 1.16] [.t bbox 1.17] +} [list [list 108 3 7 $fixedHeight] [list 115 3 28 $fixedHeight] [list 3 [expr {$fixedDiff + 16}] 7 $fixedHeight]] test textDisp-24.19 {TkTextCharLayoutProc, -wrap word} {textfonts} { .t configure -wrap word .t delete 1.0 end diff --git a/tests/ttk/spinbox.test b/tests/ttk/spinbox.test index 32b77af..08f2bda 100644 --- a/tests/ttk/spinbox.test +++ b/tests/ttk/spinbox.test @@ -199,6 +199,27 @@ test spinbox-2.4 "current command -- value not in list" -constraints nyi -setup destroy .sb } -result -1 +test spinbox-3.0 "textarea should expand to fill widget" -setup { + set SBV 5 + set ::spinbox_test {} + ttk::spinbox .sb -from 0 -to 10 -textvariable SBV +} -body { + grid .sb -sticky ew + grid columnconfigure . 0 -weight 1 + bind . <Map> { + after idle { + wm geometry . "210x80" + after 100 {set ::spinbox_test [.sb identify element 5 5]} + } + bind . <Map> {} + } + after 500 {set ::spinbox_wait 1} ; vwait ::spinbox_wait + set ::spinbox_test +} -cleanup { + destroy .sb + unset -nocomplain ::spinbox_test SBV +} -result {textarea} + # nostomp: NB intentional difference between ttk::spinbox and tk::spinbox; # see also #1439266 # diff --git a/unix/tkUnixFont.c b/unix/tkUnixFont.c index a4998aa..4a466f1 100644 --- a/unix/tkUnixFont.c +++ b/unix/tkUnixFont.c @@ -406,7 +406,7 @@ ControlUtfProc( { const char *srcStart, *srcEnd; char *dstStart, *dstEnd; - Tcl_UniChar ch; + int ch; int result; static char hexChars[] = "0123456789abcdef"; static char mapChars[] = { @@ -427,9 +427,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) { @@ -437,13 +437,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; @@ -946,7 +954,7 @@ void TkpGetFontAttrsForChar( Tk_Window tkwin, /* Window on the font's display */ Tk_Font tkfont, /* Font to query */ - Tcl_UniChar c, /* Character of interest */ + int c, /* Character of interest */ TkFontAttributes *faPtr) /* Output: Font attributes */ { FontAttributes atts; @@ -1028,7 +1036,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; @@ -1044,7 +1052,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 36e5462..41cd096 100644 --- a/unix/tkUnixRFont.c +++ b/unix/tkUnixRFont.c @@ -615,7 +615,7 @@ void TkpGetFontAttrsForChar( Tk_Window tkwin, /* Window on the font's display */ Tk_Font tkfont, /* Font to query */ - Tcl_UniChar c, /* Character of interest */ + int c, /* Character of interest */ TkFontAttributes *faPtr) /* Output: Font attributes */ { UnixFtFont *fontPtr = (UnixFtFont *) tkfont; @@ -668,9 +668,9 @@ Tk_MeasureChars( curByte = 0; sawNonSpace = 0; while (numBytes > 0) { - Tcl_UniChar unichar; + int unichar; - clen = Tcl_UtfToUniChar(source, &unichar); + clen = TkUtfToUniChar(source, &unichar); c = (FcChar32) unichar; if (clen <= 0) { @@ -778,7 +778,7 @@ LookUpColor(Display *display, /* Display to lookup colors on */ i >= 0; last2 = last, last = i, i = fontPtr->colors[i].next) { if (pixel == fontPtr->colors[i].color.pixel) { - /* + /* * Color found in cache. Move it to the front of the list and return it. */ if (last >= 0) { @@ -802,7 +802,7 @@ LookUpColor(Display *display, /* Display to lookup colors on */ last = fontPtr->ncolors++; } - /* + /* * Translate the pixel value to a color. Needs a server round-trip. */ xcolor.pixel = pixel; diff --git a/win/Makefile.in b/win/Makefile.in index 7b1766d..7e48213 100644 --- a/win/Makefile.in +++ b/win/Makefile.in @@ -27,6 +27,7 @@ exec_prefix = @exec_prefix@ bindir = @bindir@ libdir = @libdir@ includedir = @includedir@ +datarootdir = @datarootdir@ mandir = @mandir@ # The following definition can be set to non-null for special systems @@ -169,7 +170,7 @@ LDFLAGS_OPTIMIZE = @LDFLAGS_OPTIMIZE@ #CFLAGS = $(CFLAGS_DEBUG) #CFLAGS = $(CFLAGS_OPTIMIZE) #CFLAGS = $(CFLAGS_DEBUG) $(CFLAGS_OPTIMIZE) -CFLAGS = @CFLAGS@ @CFLAGS_DEFAULT@ -DUNICODE -D_UNICODE +CFLAGS = @CFLAGS@ @CFLAGS_DEFAULT@ -DUNICODE -D_UNICODE -D_ATL_XP_TARGETING # Special compiler flags to use when building man2tcl on Windows. MAN2TCLFLAGS = @MAN2TCLFLAGS@ diff --git a/win/rules.vc b/win/rules.vc index 0d8cd6b..2cd711b 100644 --- a/win/rules.vc +++ b/win/rules.vc @@ -159,7 +159,7 @@ DEBUGFLAGS = $(DEBUGFLAGS) -RTC1 DEBUGFLAGS = $(DEBUGFLAGS) -GZ
!endif
-COMPILERFLAGS =-W3 -DUNICODE -D_UNICODE
+COMPILERFLAGS =-W3 /DUNICODE /D_UNICODE /D_ATL_XP_TARGETING
# In v13 -GL and -YX are incompatible.
!if [nmakehlp -c -YX]
@@ -230,6 +230,10 @@ STATIC_BUILD = 1 !else
STATIC_BUILD = 0
!endif
+!if [nmakehlp -f $(OPTS) "nomsvcrt"]
+!message *** Doing nomsvcrt
+MSVCRT = 0
+!else
!if [nmakehlp -f $(OPTS) "msvcrt"]
!message *** Doing msvcrt
MSVCRT = 1
@@ -240,6 +244,7 @@ MSVCRT = 1 MSVCRT = 0
!endif
!endif
+!endif
!if [nmakehlp -f $(OPTS) "staticpkg"] && $(STATIC_BUILD)
!message *** Doing staticpkg
TCL_USE_STATIC_PACKAGES = 1
diff --git a/win/tkWinFont.c b/win/tkWinFont.c index 940bc10..47c4c3c 100644 --- a/win/tkWinFont.c +++ b/win/tkWinFont.c @@ -743,7 +743,7 @@ void TkpGetFontAttrsForChar( Tk_Window tkwin, /* Window on the font's display */ Tk_Font tkfont, /* Font to query */ - Tcl_UniChar c, /* Character of interest */ + int c, /* Character of interest */ TkFontAttributes *faPtr) /* Output: Font attributes */ { WinFont *fontPtr = (WinFont *) tkfont; @@ -828,7 +828,7 @@ Tk_MeasureChars( HFONT oldFont; WinFont *fontPtr; int curX, moretomeasure; - Tcl_UniChar ch; + int ch; SIZE size; FontFamily *familyPtr; Tcl_DString runString; @@ -859,7 +859,7 @@ Tk_MeasureChars( start = source; end = start + numBytes; for (p = start; p < end; ) { - next = p + Tcl_UtfToUniChar(p, &ch); + next = p + TkUtfToUniChar(p, &ch); thisSubFontPtr = FindSubFontForChar(fontPtr, ch, &lastSubFontPtr); if (thisSubFontPtr != lastSubFontPtr) { familyPtr = lastSubFontPtr->familyPtr; @@ -921,7 +921,7 @@ Tk_MeasureChars( familyPtr = lastSubFontPtr->familyPtr; Tcl_DStringInit(&runString); for (p = start; p < end; ) { - next = p + Tcl_UtfToUniChar(p, &ch); + next = p + TkUtfToUniChar(p, &ch); Tcl_UtfToExternal(NULL, familyPtr->encoding, p, (int) (next - p), 0, NULL, buf, sizeof(buf), NULL, &dstWrote, NULL); @@ -970,13 +970,13 @@ Tk_MeasureChars( */ const char *lastWordBreak = NULL; - Tcl_UniChar ch2; + int ch2; end = p; p = source; ch = ' '; while (p < end) { - next = p + Tcl_UtfToUniChar(p, &ch2); + next = p + TkUtfToUniChar(p, &ch2); if ((ch != ' ') && (ch2 == ' ')) { lastWordBreak = p; } @@ -1443,7 +1443,7 @@ MultiFontTextOut( * string when drawing. */ double angle) { - Tcl_UniChar ch; + int ch; SIZE size; HFONT oldFont; FontFamily *familyPtr; @@ -1458,7 +1458,7 @@ MultiFontTextOut( 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) { if (p > source) { @@ -1940,7 +1940,8 @@ FindSubFontForChar( SubFont *subFontPtr; Tcl_DString ds; - if (ch < BASE_CHARS) { + + if ((ch < BASE_CHARS) || (ch >= 0x10000)) { return &fontPtr->subFontArray[0]; } diff --git a/win/tkWinKey.c b/win/tkWinKey.c index 2698c4d..31faea0 100644 --- a/win/tkWinKey.c +++ b/win/tkWinKey.c @@ -88,6 +88,8 @@ TkpGetString( * result. */ { XKeyEvent *keyEv = &eventPtr->xkey; + char buf[6]; + int len; 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 bb60a2d..b2424ce 100644 --- a/win/tkWinX.c +++ b/win/tkWinX.c @@ -92,7 +92,7 @@ static Tcl_ThreadDataKey dataKey; static void GenerateXEvent(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); static unsigned int GetState(UINT message, WPARAM wParam, LPARAM lParam); -static void GetTranslatedKey(XKeyEvent *xkey); +static void GetTranslatedKey(XKeyEvent *xkey, UINT type); static void UpdateInputLanguage(int charset); static int HandleIMEComposition(HWND hwnd, LPARAM lParam); @@ -1157,7 +1157,8 @@ GenerateXEvent( event.type = KeyPress; event.xany.send_event = -1; event.xkey.keycode = wParam; - GetTranslatedKey(&event.xkey); + GetTranslatedKey(&event.xkey, (message == WM_KEYDOWN) ? WM_CHAR : + WM_SYSCHAR); break; case WM_SYSKEYUP: @@ -1229,9 +1230,10 @@ GenerateXEvent( if (IsDBCSLeadByte((BYTE) wParam)) { MSG msg; - if ((PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE) != 0) + if ((PeekMessage(&msg, NULL, WM_CHAR, WM_CHAR, + PM_NOREMOVE) != 0) && (msg.message == WM_CHAR)) { - GetMessage(&msg, NULL, 0, 0); + GetMessage(&msg, NULL, WM_CHAR, WM_CHAR); event.xkey.nbytes = 2; event.xkey.trans_chars[1] = (char) msg.wParam; } @@ -1370,19 +1372,20 @@ GetState( static void GetTranslatedKey( - XKeyEvent *xkey) + XKeyEvent *xkey, + UINT type) { MSG msg; xkey->nbytes = 0; while ((xkey->nbytes < XMaxTransChars) - && PeekMessageA(&msg, NULL, 0, 0, PM_NOREMOVE)) { - if ((msg.message != WM_CHAR) && (msg.message != WM_SYSCHAR)) { + && (PeekMessageA(&msg, NULL, type, type, PM_NOREMOVE) != 0)) { + if (msg.message != type) { break; } - GetMessageA(&msg, NULL, 0, 0); + GetMessageA(&msg, NULL, type, type); /* * If this is a normal character message, we may need to strip off the @@ -1523,7 +1526,7 @@ TkWinGetUnicodeEncoding(void) * * HandleIMEComposition -- * - * This function works around a definciency in some versions of Windows + * This function works around a deficiency in some versions of Windows * 2000 to make it possible to entry multi-lingual characters under all * versions of Windows 2000. * @@ -1553,6 +1556,7 @@ HandleIMEComposition( { HIMC hIMC; int n; + int high = 0; if ((lParam & GCS_RESULTSTR) == 0) { /* @@ -1570,18 +1574,18 @@ HandleIMEComposition( n = ImmGetCompositionString(hIMC, GCS_RESULTSTR, NULL, 0); if (n > 0) { - char *buff = ckalloc(n); + WCHAR *buff = (WCHAR *) ckalloc(n); TkWindow *winPtr; XEvent event; int i; - n = ImmGetCompositionString(hIMC, GCS_RESULTSTR, buff, (unsigned) n); + n = ImmGetCompositionString(hIMC, GCS_RESULTSTR, buff, (unsigned) n) / 2; /* * 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 +1596,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 +1604,6 @@ HandleIMEComposition( event.xkey.state = TkWinGetModifierState(); event.xkey.time = TkpGetMS(); event.xkey.same_screen = True; - event.xkey.keycode = 0; - event.xkey.nbytes = 2; for (i=0; i<n; ) { /* @@ -1609,9 +1611,16 @@ HandleIMEComposition( * UNICODE character in the composition. */ - event.xkey.trans_chars[0] = (char) buff[i++]; - event.xkey.trans_chars[1] = (char) buff[i++]; + event.xkey.keycode = buff[i++]; + if ((event.xkey.keycode & 0xfc00) == 0xd800) { + high = ((event.xkey.keycode & 0x3ff) << 10) + 0x10000; + break; + } else if (high && (event.xkey.keycode & 0xfc00) == 0xdc00) { + event.xkey.keycode &= 0x3ff; + event.xkey.keycode += high; + high = 0; + } event.type = KeyPress; Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL); |