diff options
-rw-r--r-- | ChangeLog | 9 | ||||
-rw-r--r-- | generic/tkTextDisp.c | 69 | ||||
-rw-r--r-- | tests/textDisp.test | 91 | ||||
-rw-r--r-- | tests/textWind.test | 14 |
4 files changed, 144 insertions, 39 deletions
@@ -1,3 +1,12 @@ +2003-11-21 Vince Darley <vincentdarley@users.sourceforge.net> + + * generic/tkTextDisp.c: prevent wrapped line height calculations + until the widget has actually been given a geometry. + + * tests/textWind.test: + * tests/textDisp.test: fix to [Bug 843752], allowing tests to + complete cross-platform. Thanks to dgp for extensive testing. + 2003-11-21 Donal K. Fellows <donal.k.fellows@man.ac.uk> * doc/FindPhoto.3: Removed reference to long-gone header file. diff --git a/generic/tkTextDisp.c b/generic/tkTextDisp.c index c773f91..623570a 100644 --- a/generic/tkTextDisp.c +++ b/generic/tkTextDisp.c @@ -13,7 +13,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkTextDisp.c,v 1.33 2003/11/16 14:13:09 vincentdarley Exp $ + * RCS: @(#) $Id: tkTextDisp.c,v 1.34 2003/11/21 17:29:13 vincentdarley Exp $ */ #include "tkPort.h" @@ -356,11 +356,12 @@ typedef struct CharInfo { * checked to see how clever this code is at reducing redisplays. */ -static int numRedisplays; /* Number of calls to DisplayText. */ -static int linesRedrawn; /* Number of calls to DisplayDLine. */ -static int numCopies; /* Number of calls to XCopyArea to copy part - * of the screen. */ - +static int numRedisplays; /* Number of calls to DisplayText. */ +static int linesRedrawn; /* Number of calls to DisplayDLine. */ +static int numCopies; /* Number of calls to XCopyArea + * to copy part of the screen. */ +static int lineHeightsRecalculated; /* Number of line layouts purely + * for height calculation purposes.*/ /* * Forward declarations for procedures defined later in this file: */ @@ -433,7 +434,7 @@ static int SizeOfTab _ANSI_ARGS_((TkText *textPtr, int x, int maxX)); static void TextInvalidateRegion _ANSI_ARGS_((TkText *textPtr, TkRegion region)); -static int TextCalculateDisplayLineHeight _ANSI_ARGS_(( +static int CalculateDisplayLineHeight _ANSI_ARGS_(( TkText *textPtr, CONST TkTextIndex *indexPtr, int *byteCountPtr)); static void DlineIndexOfX _ANSI_ARGS_((TkText *textPtr, @@ -1930,7 +1931,22 @@ FreeDLines(textPtr, firstPtr, lastPtr, action) register TkTextDispChunk *chunkPtr, *nextChunkPtr; register DLine *nextDLinePtr; - if (action == DLINE_UNLINK) { + if (action == DLINE_FREE_TEMP) { + lineHeightsRecalculated++; + if (tkTextDebug) { + char string[TK_POS_CHARS]; + + /* + * Debugging is enabled, so keep a log of all the lines + * whose height was recalculated. The test suite uses this + * information. + */ + + TkTextPrintIndex(&firstPtr->index, string); + Tcl_SetVar2(textPtr->interp, "tk_textHeightCalc", (char *) NULL, + string, TCL_GLOBAL_ONLY|TCL_APPEND_VALUE|TCL_LIST_ELEMENT); + } + } else if (action == DLINE_UNLINK) { if (textPtr->dInfoPtr->dLinePtr == firstPtr) { textPtr->dInfoPtr->dLinePtr = lastPtr; } else { @@ -2519,6 +2535,12 @@ AsyncUpdateLineMetrics(clientData) return; } + if (dInfoPtr->flags & REDRAW_PENDING) { + dInfoPtr->lineUpdateTimer = Tcl_CreateTimerHandler(1, + AsyncUpdateLineMetrics, clientData); + return; + } + lineNum = dInfoPtr->currentMetricUpdateLine; if (lineNum == -1) { dInfoPtr->lastMetricUpdateLine = 0; @@ -2907,7 +2929,7 @@ TkTextFindDisplayLineEnd(textPtr, indexPtr, end, xOffset) /* *---------------------------------------------------------------------- * - * TextCalculateDisplayLineHeight -- + * CalculateDisplayLineHeight -- * * This procedure is invoked to recalculate the height of the * particular display line which starts with the given index, @@ -2939,7 +2961,7 @@ TkTextFindDisplayLineEnd(textPtr, indexPtr, end, xOffset) */ static int -TextCalculateDisplayLineHeight(textPtr, indexPtr, byteCountPtr) +CalculateDisplayLineHeight(textPtr, indexPtr, byteCountPtr) TkText *textPtr; /* Widget record for text widget. */ CONST TkTextIndex *indexPtr; /* The index at the beginning of the * display line of interest. */ @@ -2982,7 +3004,7 @@ TextCalculateDisplayLineHeight(textPtr, indexPtr, byteCountPtr) * top of the index's current display line (could be zero). * * Side effects: - * Just those of 'TextCalculateDisplayLineHeight'. + * Just those of 'CalculateDisplayLineHeight'. * *---------------------------------------------------------------------- */ @@ -3026,7 +3048,7 @@ TkTextIndexYPixels(textPtr, indexPtr) * specifically the 'linePtr->pixelHeight == pixelHeight' test * below this while loop. */ - height = TextCalculateDisplayLineHeight(textPtr, &index, &bytes); + height = CalculateDisplayLineHeight(textPtr, &index, &bytes); index.byteIndex += bytes; @@ -3065,7 +3087,7 @@ TkTextIndexYPixels(textPtr, indexPtr) * Side effects: * Line heights may be recalculated, and a timer to update * the scrollbar may be installed. Also see the called - * function 'TextCalculateDisplayLineHeight' for its side + * function 'CalculateDisplayLineHeight' for its side * effects. * *---------------------------------------------------------------------- @@ -3106,7 +3128,7 @@ TkTextUpdateOneLine(textPtr, linePtr) * specifically the 'linePtr->pixelHeight == pixelHeight' test * below this while loop. */ - height = TextCalculateDisplayLineHeight(textPtr, &index, &bytes); + height = CalculateDisplayLineHeight(textPtr, &index, &bytes); if (height > 0) { pixelHeight += height; @@ -4309,7 +4331,7 @@ TkTextSetYView(textPtr, indexPtr, pickPlace) * window. */ - lineHeight = TextCalculateDisplayLineHeight(textPtr, indexPtr, NULL); + lineHeight = CalculateDisplayLineHeight(textPtr, indexPtr, NULL); /* * It would be better if 'bottomY' were calculated using the * actual height of the given line, not 'textPtr->charHeight'. @@ -4785,7 +4807,7 @@ YScrollByPixels(textPtr, offset) * not be totally visible. Note that 'count' is * negative here. */ - offset -= TextCalculateDisplayLineHeight(textPtr, + offset -= CalculateDisplayLineHeight(textPtr, &textPtr->topIndex, NULL) - dInfoPtr->topPixelOffset; MeasureUp(textPtr, &textPtr->topIndex, -offset, &textPtr->topIndex, &dInfoPtr->newTopPixelOffset); @@ -5359,6 +5381,21 @@ GetPixelCount(textPtr, dlPtr) break; } dlPtr = LayoutDLine(textPtr, &index); + + if (tkTextDebug) { + char string[TK_POS_CHARS]; + + /* + * Debugging is enabled, so keep a log of all the + * lines whose height was recalculated. The test + * suite uses this information. + */ + + TkTextPrintIndex(&index, string); + Tcl_SetVar2(textPtr->interp, "tk_textHeightCalc", + (char *) NULL, string, + TCL_GLOBAL_ONLY|TCL_APPEND_VALUE|TCL_LIST_ELEMENT); + } count -= dlPtr->height; notFirst = 1; } diff --git a/tests/textDisp.test b/tests/textDisp.test index 4fad84b..48a4567 100644 --- a/tests/textDisp.test +++ b/tests/textDisp.test @@ -6,7 +6,7 @@ # Copyright (c) 1998-1999 by Scriptics Corporation. # All rights reserved. # -# RCS: @(#) $Id: textDisp.test,v 1.20 2003/11/15 16:57:57 vincentdarley Exp $ +# RCS: @(#) $Id: textDisp.test,v 1.21 2003/11/21 17:29:13 vincentdarley Exp $ package require tcltest 2.1 eval tcltest::configure $argv @@ -3150,11 +3150,43 @@ test textDisp-27.6 {SizeOfTab procedure, center alignment} {textfonts} { } [list [list 32 [expr {$fixedDiff + 18}] 7 $fixedHeight] [list 39 [expr {$fixedDiff + 18}] 7 $fixedHeight]] test textDisp-27.7 {SizeOfTab procedure, center alignment, wrap -none (potential numerical problems)} {textfonts} { .t delete 1.0 end - .t configure -tabs {1c 2c center 3c 4c} -wrap none -width 40 + set cm [winfo fpixels .t 1c] + .t configure -tabs {1c 2c center 3c 4c 5c 6c 7c 8c} -wrap none -width 40 .t insert 1.0 a\tb\tc\td\te\n012345678934567890a\tbb\tcc\tdd + set width [expr {$fixedWidth * 19}] + set tab $cm + while {$tab < $width} { + set tab [expr {$tab + $cm}] + } + # Now we've calculated to the end of the tab after 'a', add one + # more for 'bb\t' and we're there, with 4 for the border + set tab [expr {4 + int($tab + $cm)}] update - .t bbox 2.24 -} [list 200 [expr {$fixedDiff + 18}] 7 $fixedHeight] + set res [.t bbox 2.23] + lset res 0 [expr {[lindex $res 0] - $tab}] + set res +} [list 0 [expr {$fixedDiff + 18}] 7 $fixedHeight] +test textDisp-27.7.1 {SizeOfTab procedure, fractional tab interpolation problem} {knownBug textfonts} { + .t delete 1.0 end + set cm [winfo fpixels .t 1c] + .t configure -tabs {1c 2c 3c 4c} -wrap none -width 40 + .t insert 1.0 a\tb\tc\td\te\n012345678934567890a\tbb\tcc\tdd + set width [expr {$fixedWidth * 19}] + set tab $cm + while {$tab < $width} { + set tab [expr {$tab + $cm}] + } + # Now we've calculated to the end of the tab after 'a', add one + # more for 'bb\t' and we're there, with 4 for the border + set tab [expr {4 + int($tab + $cm)}] + update + set res [.t bbox 2.23] + # Now, on some platforms Tk interpolated from 3c-4c->5c but that + # interpolation doesn't use fractional pixels and so this result + # might be off by one. + lset res 0 [expr {[lindex $res 0] - $tab}] + set res +} [list 0 [expr {$fixedDiff + 18}] 7 $fixedHeight] .t configure -wrap char -tabs {} -width 20 update @@ -3325,10 +3357,10 @@ test textDisp-29.2.5 {miscellaneous: can show last character} { .t2.t xview scroll 2 units set iWidth2 [lindex [.t2.t bbox end-2c] 2] - if {($iWidth == $iWidth2) && $iWidth > 2} { + if {($iWidth == $iWidth2) && $iWidth >= 2} { set result "correct" } else { - set result "not correct" + set result "last character is not completely visible when it should be" } } {correct} test textDisp-29.3 {miscellaneous: lines wrap but are still too long} {textfonts} { @@ -3494,24 +3526,63 @@ test textDisp-32.1 {everything elided} { test textDisp-33.0 {one line longer than fits in the widget} { pack [text .tt -wrap char] - .tt insert 1.0 [string repeat "hello there " 2500] + .tt insert 1.0 [string repeat "more wrap + " 300] update ; update ; update .tt see 1.0 lindex [.tt yview] 0 } {0.0} - test textDisp-33.1 {one line longer than fits in the widget} { destroy .tt pack [text .tt -wrap char] - .tt insert 1.0 [string repeat "hello there " 2500] + .tt insert 1.0 [string repeat "more wrap + " 300] update ; update ; update .tt yview "1.0 +1 displaylines" if {[lindex [.tt yview] 0] > 0.1} { - set result "bad result" + set result "window should be scrolled to the top" + } else { + set result "ok" + } +} {ok} +test textDisp-33.2 {one line longer than fits in the widget} { + destroy .tt + pack [text .tt -wrap char] + .tt debug 1 + set tk_textHeightCalc "" + .tt insert 1.0 [string repeat "more wrap + " 1] + after 100 ; update + # Nothing should have been recalculated. + set tk_textHeightCalc +} {} +test textDisp-33.3 {one line longer than fits in the widget} { + destroy .tt + pack [text .tt -wrap char] + .tt debug 1 + set tk_textHeightCalc "" + .tt insert 1.0 [string repeat "more wrap + " 300] + after 100 ; update + # Each line should have been recalculated just once + .tt debug 0 + expr {[llength $tk_textHeightCalc] == [.tt count -displaylines 1.0 end]} +} {1} +test textDisp-33.4 {one line longer than fits in the widget} { + destroy .tt + pack [text .tt -wrap char] + .tt debug 1 + set tk_textHeightCalc "" + .tt insert 1.0 [string repeat "more wrap + " 300] + update ; update ; update + set idx [.tt index "1.0 + 1 displaylines"] + .tt yview $idx + if {[lindex [.tt yview] 0] > 0.1} { + set result "window should be scrolled to the top" } else { set result "ok" } + set idx [.tt index "1.0 + 1 displaylines"] + .tt debug 0 + set result } {ok} +destroy .tt deleteWindows option clear diff --git a/tests/textWind.test b/tests/textWind.test index 7c006ff..f5816a7 100644 --- a/tests/textWind.test +++ b/tests/textWind.test @@ -6,7 +6,7 @@ # Copyright (c) 1998-1999 by Scriptics Corporation. # All rights reserved. # -# RCS: @(#) $Id: textWind.test,v 1.12 2003/11/07 15:36:27 vincentdarley Exp $ +# RCS: @(#) $Id: textWind.test,v 1.13 2003/11/21 17:29:13 vincentdarley Exp $ package require tcltest 2.1 eval tcltest::configure $argv @@ -482,18 +482,6 @@ test textWind-10.4.1 {EmbWinLayoutProc procedure, error in creating window} {tex update idletasks lappend msg [winfo exists .t.f.f] } [list {{can't embed .t.f.f relative to .t}} 1] -test textWind-10.4.2 {EmbWinLayoutProc procedure, error in creating window} {textfonts} { - .t delete 1.0 end - .t insert 1.0 "Some sample text" - catch {destroy .t.f} - .t window create 1.5 -create { - frame .t.f - frame .t.f.f -width 10 -height 20 -bg $color - } - set msg {} - update - lappend msg [winfo exists .t.f.f] -} {{{can't embed .t.f.f relative to .t}} {{window name "f" already exists in parent}} 1} catch {destroy .t.f} test textWind-10.5 {EmbWinLayoutProc procedure, error in creating window} {textfonts} { .t delete 1.0 end |