From 28a17a508560345357143eac9b4a8e3c97c1eb83 Mon Sep 17 00:00:00 2001 From: vincentdarley Date: Sat, 15 Nov 2003 12:47:14 +0000 Subject: fixed tab interpretation inconsistency --- ChangeLog | 6 ++++ generic/tkTextDisp.c | 88 ++++++++++++++++++++++++++++++++++------------------ tests/textDisp.test | 16 ++++++++-- 3 files changed, 77 insertions(+), 33 deletions(-) diff --git a/ChangeLog b/ChangeLog index e9fb2a8..6abbb11 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2003-11-15 Vince Darley + + * generic/tkTextDisp.c: + * tests/textDisp.test: fixes to one more old Tk [Bug 422411] + this time concerning inconsistent tab interpretation. + 2003-11-14 Joe English * doc/text.n: Fix markup errors. diff --git a/generic/tkTextDisp.c b/generic/tkTextDisp.c index 7e6713b..040c907 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.30 2003/11/15 02:49:36 vincentdarley Exp $ + * RCS: @(#) $Id: tkTextDisp.c,v 1.31 2003/11/15 12:47:15 vincentdarley Exp $ */ #include "tkPort.h" @@ -429,8 +429,8 @@ static void YScrollByLines _ANSI_ARGS_((TkText *textPtr, static void YScrollByPixels _ANSI_ARGS_((TkText *textPtr, int offset)); static int SizeOfTab _ANSI_ARGS_((TkText *textPtr, - TkTextTabArray *tabArrayPtr, int index, int x, - int maxX)); + TkTextTabArray *tabArrayPtr, int *indexPtr, + int x, int maxX)); static void TextInvalidateRegion _ANSI_ARGS_((TkText *textPtr, TkRegion region)); static int TextCalculateDisplayLineHeight _ANSI_ARGS_(( @@ -1239,9 +1239,8 @@ LayoutDLine(textPtr, indexPtr) AdjustForTab(textPtr, tabArrayPtr, tabIndex, tabChunkPtr); x = chunkPtr->x + chunkPtr->width; } - tabIndex++; tabChunkPtr = chunkPtr; - tabSize = SizeOfTab(textPtr, tabArrayPtr, tabIndex, x, maxX); + tabSize = SizeOfTab(textPtr, tabArrayPtr, &tabIndex, x, maxX); if ((maxX >= 0) && (tabSize >= maxX - x)) { break; } @@ -6663,10 +6662,14 @@ AdjustForTab(textPtr, tabArrayPtr, index, chunkPtr) * * Results: * The return value is the minimum number of pixels that will - * be occupied by the index'th tab of tabArrayPtr, assuming that + * be occupied by the next tab of tabArrayPtr, assuming that * the current position on the line is x and the end of the - * line is maxX. For numeric tabs, this is a conservative - * estimate. The return value is always >= 0. + * line is maxX. The 'next tab' is determined by a combination + * of the current position (x) which it must be equal to or + * beyond, and the tab count in indexPtr. + * + * For numeric tabs, this is a conservative estimate. The return + * value is always >= 0. * * Side effects: * None. @@ -6675,45 +6678,70 @@ AdjustForTab(textPtr, tabArrayPtr, index, chunkPtr) */ static int -SizeOfTab(textPtr, tabArrayPtr, index, x, maxX) +SizeOfTab(textPtr, tabArrayPtr, indexPtr, x, maxX) TkText *textPtr; /* Information about the text widget as * a whole. */ TkTextTabArray *tabArrayPtr; /* Information about the tab stops * that apply to this line. NULL * means use default tabbing (every * 8 chars.) */ - int index; /* Index of current tab stop. */ - int x; /* Current x-location in line. Only - * used if tabArrayPtr == NULL. */ + int *indexPtr; /* Contains index of previous tab + * stop, will be updated to + * reflect the number of stops + * used. */ + int x; /* Current x-location in line. */ int maxX; /* X-location of pixel just past the * right edge of the line. */ { - int tabX, prev, result, spaceWidth; + int tabX, prev, result, index, spaceWidth; TkTextTabAlign alignment; - + if ((tabArrayPtr == NULL) || (tabArrayPtr->numTabs == 0)) { tabX = NextTabStop(textPtr->tkfont, x, 0); + /* + * We used up one tab stop. + */ + *indexPtr = (*indexPtr)+1; return tabX - x; } - if (index < tabArrayPtr->numTabs) { - tabX = tabArrayPtr->tabs[index].location; - alignment = tabArrayPtr->tabs[index].alignment; - } else { - /* - * Ran out of tab stops; compute a tab position by extrapolating - * from the last two tab positions. - */ - if (tabArrayPtr->numTabs > 1) { - prev = tabArrayPtr->tabs[tabArrayPtr->numTabs-2].location; + index = *indexPtr; + do { + /* + * We were given the count before this tabs, so increment it + * first. + */ + index++; + if (index < tabArrayPtr->numTabs) { + tabX = tabArrayPtr->tabs[index].location; + alignment = tabArrayPtr->tabs[index].alignment; } else { - prev = 0; + /* + * Ran out of tab stops; compute a tab position by extrapolating + * from the last two tab positions. + */ + + if (tabArrayPtr->numTabs > 1) { + prev = tabArrayPtr->tabs[tabArrayPtr->numTabs-2].location; + } else { + prev = 0; + } + tabX = tabArrayPtr->tabs[tabArrayPtr->numTabs-1].location + + (index + 1 - tabArrayPtr->numTabs) + * (tabArrayPtr->tabs[tabArrayPtr->numTabs-1].location - prev); + alignment = tabArrayPtr->tabs[tabArrayPtr->numTabs-1].alignment; } - tabX = tabArrayPtr->tabs[tabArrayPtr->numTabs-1].location - + (index + 1 - tabArrayPtr->numTabs) - * (tabArrayPtr->tabs[tabArrayPtr->numTabs-1].location - prev); - alignment = tabArrayPtr->tabs[tabArrayPtr->numTabs-1].alignment; - } + /* + * If this tab stop is before the current x position, then we + * must obviously continue until we reach the text tab stop. + */ + } while (tabX < x); + + /* + * Inform our caller of how many tab stops we've used up. + */ + *indexPtr = index; + if (alignment == CENTER) { /* * Be very careful in the arithmetic below, because maxX may diff --git a/tests/textDisp.test b/tests/textDisp.test index 30495b8..bb60912 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.18 2003/11/15 02:33:51 vincentdarley Exp $ +# RCS: @(#) $Id: textDisp.test,v 1.19 2003/11/15 12:47:15 vincentdarley Exp $ package require tcltest 2.1 eval tcltest::configure $argv @@ -3089,7 +3089,16 @@ test textDisp-26.13 {AdjustForTab procedure, not enough space} {textfonts} { .t tag add x 1.0 end list [lindex [.t bbox 1.4] 0] [lindex [.t bbox 1.8] 0] \ [lindex [.t bbox 1.12] 0] [lindex [.t bbox 1.16] 0] -} [list 28 56 84 120] +} [list 28 56 120 190] +test textDisp-26.14 {AdjustForTab procedure, not enough space} {textfonts} { + .t delete 1.0 end + .t insert end "a \tb \tc \td \te \tf \tg\n" + .t insert end "Watch the \tX and the \t\t\tY\n" + .t tag configure moop -tabs [expr {8*$fixedWidth}] + .t insert end "Watch the \tX and the \t\t\tY\n" moop + list [lindex [.t bbox 2.11] 0] [lindex [.t bbox 2.24] 0] \ + [lindex [.t bbox 3.11] 0] [lindex [.t bbox 3.24] 0] +} [list 112 56 112 56] .t configure -width 20 -bd 2 -highlightthickness 2 -relief sunken -tabs {} \ -wrap char @@ -3145,7 +3154,8 @@ test textDisp-27.7 {SizeOfTab procedure, center alignment, wrap -none (potential .t insert 1.0 a\tb\tc\td\te\n012345678934567890a\tbb\tcc\tdd update .t bbox 2.24 -} [list 172 [expr {$fixedDiff + 18}] 7 $fixedHeight] +} [list 200 [expr {$fixedDiff + 18}] 7 $fixedHeight] + .t configure -wrap char -tabs {} -width 20 update test textDisp-27.8 {SizeOfTab procedure, right alignment} {textfonts} { -- cgit v0.12